Text processing/Max licenses in use
A company currently pays a fixed sum for the use of a particular licensed software package. In determining if it has a good deal it decides to calculate its maximum use of the software from its license management log file.
You are encouraged to solve this task according to the task description, using any language you may know.
Assume the software's licensing daemon faithfully records a checkout event when a copy of the software starts and a checkin event when the software finishes to its log file. An example of checkout and checkin events are:
License OUT @ 2008/10/03_23:51:05 for job 4974 ... License IN @ 2008/10/04_00:18:22 for job 4974
Save the 10,000 line log file from here into a local file then write a program to scan the file extracting both the maximum licenses that were out at any time, and the time(s) at which this occurs.
Ada
<lang Ada>-- licenselist.adb -- -- run under GPS 4.3-5 (Sidux/Debian) -- process rosetta.org text_processing/3 example -- uses linked-list to hold times with Ada.Text_IO, Ada.Integer_Text_IO, Ada.Strings.Unbounded,
Ada.Strings.Unbounded.Text_IO, Ada.Containers.Doubly_Linked_Lists;
use Ada.Text_IO, Ada.Integer_Text_IO,
Ada.Strings.Unbounded, Ada.Strings.Unbounded.Text_IO, Ada.Containers;
procedure licenselist is
type logrec is record -- define a record 'logrec' to place in a list logtext : String(1..19); end record;
package dblist is new Doubly_Linked_Lists(logrec); use dblist; -- declare dblist as a list of logrec's licenselog : list; logtime : logrec; -- to record the time of max OUT licenses
infile : File_Type; -- file handle str : Unbounded_String; -- input string buffer of unknown length outcnt, maxoutcnt : integer := 0; infilename : string := "license.log";
procedure trace_times is -- loop thru times list and print pntr : cursor := licenselog.first; -- pntr is of system type cursor reference to local list 'licenselog' begin new_line; while has_element(pntr) loop put(element(pntr).logtext); new_line; next(pntr); end loop; end trace_times;
begin -- main program --
open ( infile, mode=> in_file, name=> infilename );
loop exit when End_of_file ( infile ); str := get_line( infile ); if index( str, "OUT" ) > 0 then -- test if OUT record outcnt := outcnt +1; else -- else assume IN record outcnt := outcnt -1; end if; if outcnt > maxoutcnt then maxoutcnt := outcnt;
logtime.logtext := slice(str,15,33); -- date_time field
licenselog.clear; -- reset list for new time(s) licenselog.append (logtime); -- put current time into list elsif outcnt = maxoutcnt then logtime.logtext := slice(str,15,33); -- date_time field licenselog.append (logtime); -- add current time into list end if; -- have to account for possibility of equal number of OUT's end loop; put("The max. number of licenses OUT is ");put(maxoutcnt,5); new_line; put(" at these times ");
trace_times; close ( infile );
end licenselist;</lang> Output:
The max. number of licenses out is 99 at these times 2008/10/03_08:39:34 2008/10/03_08:40:40 [2010-06-06 01:06:07] process terminated successfully (elapsed time: 00.25s)
ALGOL 68
note: This specimen retains the original C coding style.
<lang algol68>PROC report = (REF FILE file in)INT: (
MODE TIME = [19]CHAR; STRUCT ([3]CHAR inout, TIME time, INT jobnum) record; FORMAT record fmt = $"License "g" @ "g" for job "g(0)l$;
FLEX[1]TIME max time;
INT lic out := 0, max out := LWB max time-1, max count := LWB max time-1; BOOL file in ended := FALSE; on logical file end(file in, (REF FILE file in)BOOL: file in ended := TRUE); WHILE getf(file in, (record fmt, record));
- WHILE # NOT file in ended DO
IF inout OF record = "OUT" THEN lic out +:= 1 ELIF lic out > 0 THEN # incase license already "OUT" # lic out -:= 1 FI;
IF lic out > max out THEN max out := lic out; max count := LWB max time-1 FI; IF lic out = max out THEN IF max count = UPB max time THEN [UPB max time*2]TIME new max time; new max time[:UPB max time] := max time; max time := new max time # ;putf(stand error, ($"increasing UPB max time (now it is "g(0)")"l$, UPB max time)); # FI; max time[max count +:= 1] := time OF record FI OD;
printf(($"Maximum simultaneous license use is "g(0)" at the following times:"l$, max out)); FOR lic out FROM LWB max time TO max count DO printf(($gl$, max time[lic out])) OD;
0 EXIT exit report error: errno
);
INT errno;
COMMENT
Usage: a68g Text_processing_3.a68 --exit Text_processing_3.dat a68g Text_processing_3.a68 < Text_processing_3.dat
END COMMENT
main: (
INT argv1 := 4; IF argc >= argv1 THEN FOR i FROM argv1 TO argc DO FILE file in; errno := open(file in, argv(i), stand in channel); IF errno /= 0 THEN putf(stand error, ($"cannot read "gl$, argv(1))); exit main error ELSE report(file in) FI; close(file in) OD ELSE report(stand in) FI; exit main error: SKIP
)</lang> Output:
Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40
APL
<lang apl>⍝ Copy/paste file's contents into TXT (easiest), or TXT ← ⎕NREAD
I ← TXT[;8+⎕IO] D ← TXT[;⎕IO+14+⍳19] lu ← +\ ¯1 * 'OI' ⍳ I mx ← (⎕IO+⍳⍴lu)/⍨lu= max ← ⌈/ lu ⎕ ← 'Maximum simultaneous license use is ' , ' at the following times:' ,⍨ ⍕max ⋄ ⎕←D[mx;]</lang>
<lang apl>Maximum simultaneous license use is 99 at the following times:
2008/10/03_08:39:34 2008/10/03_08:40:40</lang>
AutoHotkey
<lang autohotkey> IfNotExist, mlijobs.txt
UrlDownloadToFile, http://rosettacode.org/mlijobs.txt, mlijobs.txt
out := 0, max_out := -1, max_times := ""
Loop, Read, mlijobs.txt {
If InStr(A_LoopReadLine, "OUT") out++ Else out-- If (out > max_out) max_out := out, max_times := "" If (out = max_out) { StringSplit, lineArr, A_LoopReadLine, %A_Space% max_times .= lineArr4 . "`n" }
}
MsgBox Maximum use is %max_out% at:`n`n%max_times% </lang>
Maximum use is 99 at: 2008/10/03_08:39:34 2008/10/03_08:40:40
AWK
to be called with awk -f licenses.awk ./mlijobs.txt <lang awk>$2=="OUT" {
count = count + 1 time = $4 if ( count > maxcount ) { maxcount = count maxtimes = time } else { if ( count == maxcount ) { maxtimes = maxtimes " and " time } }
} $2=="IN" { count = count - 1 } END {print "The biggest number of licenses is " maxcount " at " maxtimes " !"}</lang>
Sample output
The biggest number of licenses is 99 at 2008/10/03_08:39:34 and 2008/10/03_08:40:40 !
BBC BASIC
<lang bbcbasic> max% = 0
nlicence% = 0 file% = OPENIN("mlijobs.txt") WHILE NOT EOF#file% a$ = GET$#file% stamp$ = MID$(a$, 15, 19) IF INSTR(a$, "OUT") THEN nlicence% += 1 IF nlicence% > max% THEN max% = nlicence% start$ = stamp$ ENDIF ENDIF IF INSTR(a$, "IN") THEN IF nlicence% = max% THEN finish$ = previous$ ENDIF nlicence% -= 1 ENDIF previous$ = stamp$ ENDWHILE CLOSE #file% PRINT "Maximum licences checked out = " ; max% PRINT "From " start$ " to " finish$ END</lang>
Output:
Maximum licences checked out = 99 From 2008/10/03_08:39:34 to 2008/10/03_08:40:40
Bracmat
<lang bracmat>( 0:?N:?n
& :?Ts & @( get$("mlijobs.txt",STR) : ? ( "e " ?OI " @ " ?T " " ? & ( !OI:OUT & !n+1 : ( >!N:?N&!T:?Ts | !N&!Ts !T:?Ts | ? ) | !n+-1 ) : ?n & ~ ) )
| out$(!N !Ts) ); </lang> Output:
99 2008/10/03_08:39:34 2008/10/03_08:40:40
C
<lang c>#include <stdio.h>
- include <stdlib.h>
- include <string.h>
- include <sys/types.h>
- define INOUT_LEN 4
- define TIME_LEN 20
- define MAX_MAXOUT 1000
char inout[INOUT_LEN]; char time[TIME_LEN]; uint jobnum;
char maxtime[MAX_MAXOUT][TIME_LEN];
int main(int argc, char **argv) {
FILE *in = NULL; int l_out = 0, maxout=-1, maxcount=0;
if ( argc > 1 ) { in = fopen(argv[1], "r"); if ( in == NULL ) { fprintf(stderr, "cannot read %s\n", argv[1]); exit(1); } } else { in = stdin; }
while( fscanf(in, "License %s @ %s for job %u\n", inout, time, &jobnum) != EOF ) {
if ( strcmp(inout, "OUT") == 0 ) l_out++; else l_out--;
if ( l_out > maxout ) { maxout = l_out; maxcount=0; maxtime[0][0] = '\0'; } if ( l_out == maxout ) { if ( maxcount < MAX_MAXOUT ) {
strncpy(maxtime[maxcount], time, TIME_LEN); maxcount++;
} else {
fprintf(stderr, "increase MAX_MAXOUT (now it is %u)\n", MAX_MAXOUT); exit(1);
} } }
printf("Maximum simultaneous license use is %d at the following times:\n", maxout); for(l_out=0; l_out < maxcount; l_out++) { printf("%s\n", maxtime[l_out]); }
if ( in != stdin ) fclose(in); exit(0);
}</lang>
Using mmap, no extra storage (think this as a search and replace):<lang c>#include <stdio.h>
- include <unistd.h>
- include <fcntl.h>
- include <sys/types.h>
- include <sys/stat.h>
- include <sys/mman.h>
- include <err.h>
- include <string.h>
int main() { struct stat s; int fd = open("mlijobs.txt", O_RDONLY); int cnt, max_cnt, occur; char *buf, *ptr;
if (fd == -1) err(1, "open"); fstat(fd, &s); ptr = buf = mmap(0, s.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
cnt = max_cnt = 0; while(ptr - buf < s.st_size - 33) { if (!strncmp(ptr, "License OUT", 11) && ++cnt >= max_cnt) { if (cnt > max_cnt) { max_cnt = cnt; occur = 0; } /* can't sprintf time stamp: might overlap */ memmove(buf + 26 * occur, ptr + 14, 19); sprintf(buf + 26 * occur + 19, "%6d\n", cnt); occur++; } else if (!strncmp(ptr, "License IN ", 11)) cnt --;
while (ptr < buf + s.st_size && *ptr++ != '\n'); }
printf(buf); munmap(buf, s.st_size); return close(fd); }</lang>output<lang>2008/10/03_08:39:34 99 2008/10/03_08:40:40 99</lang>
C++
<lang cpp>#include <fstream>
- include <iostream>
- include <iterator>
- include <string>
- include <vector>
int main() {
const char logfilename[] = "mlijobs.txt"; std::ifstream logfile(logfilename);
if (!logfile.is_open()) { std::cerr << "Error opening: " << logfilename << "\n"; return -1; }
int license = 0, max_license = 0; std::vector<std::string> max_timestamp;
for (std::string logline; std::getline(logfile, logline); ) { std::string action(logline.substr(8,3));
if (action == "OUT") { if (++license >= max_license) { if (license > max_license) { max_license = license; max_timestamp.clear(); } max_timestamp.push_back(logline.substr(14, 19)); } } else if (action == "IN ") { --license; } }
std::cout << "License count at log end: " << license << "\nMaximum simultaneous license: " << max_license << "\nMaximum license time(s):\n";
std::copy(max_timestamp.begin(), max_timestamp.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}</lang>
Output:
License count at log end: 0 Maximum simultaneous licenses: 99 Maximum license time(s): 2008/10/03_08:39:34 2008/10/03_08:40:40
C#
<lang csharp> using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO;
namespace TextProc3 {
class Program { static void Main(string[] args) { string line; int count = 0, maxcount = 0; List<string> times = new List<string>(); System.IO.StreamReader file = new StreamReader("mlijobs.txt"); while ((line = file.ReadLine()) != null) { string[] lineelements = line.Split(' '); switch (lineelements[1]) { case "IN": count--; break; case "OUT": count++; if (count > maxcount) { maxcount = count; times.Clear(); times.Add(lineelements[3]); }else if(count == maxcount){ times.Add(lineelements[3]); } break; } } file.Close(); Console.WriteLine(maxcount); foreach (string time in times) { Console.WriteLine(time); } } }
} </lang>
99 2008/10/03_08:39:34 2008/10/03_08:40:40
Common Lisp
<lang lisp>(defun max-licenses (&optional (logfile "mlijobs.txt"))
(with-open-file (log logfile :direction :input) (do ((current-logs 0) (max-logs 0) (max-log-times '()) (line #1=(read-line log nil nil) #1#)) ((null line) (format t "~&Maximum simultaneous license use is ~w at the ~ following time~p: ~{~% ~a~}." max-logs (length max-log-times) (nreverse max-log-times))) (cl-ppcre:register-groups-bind (op time) ("License (\\b.*\\b)[ ]{1,2}@ (\\b.*\\b)" line) (cond ((string= "OUT" op) (incf current-logs)) ((string= "IN" op) (decf current-logs)) (t (cerror "Ignore it." "Malformed entry ~s." line))) (cond ((> current-logs max-logs) (setf max-logs current-logs max-log-times (list time))) ((= current-logs max-logs) (push time max-log-times)))))))</lang>
> (max-licenses) Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40. NIL
D
<lang d>void main() {
import std.stdio; int nOut, maxOut = -1; string[] maxTimes;
foreach (string job; lines(File("mlijobs.txt"))) { nOut += (job[8] == 'O') ? 1 : -1; if (nOut > maxOut) { maxOut = nOut; maxTimes = null; } if (nOut == maxOut) maxTimes ~= job[14 .. 33]; }
writefln("Maximum simultaneous license use is %d at" ~ " the following times:\n%( %s\n%)", maxOut, maxTimes);
}</lang>
- Output:
Maximum simultaneous license use is 99 at the following times: "2008/10/03_08:39:34" "2008/10/03_08:40:40"
E
<lang e>var out := 0 var maxOut := 0 var maxTimes := []
def events := ["OUT " => 1, "IN " => -1]
for line in <file:mlijobs.txt> {
def `License @{via (events.fetch) delta}@@ @time for job @num$\n` := line
out += delta if (out > maxOut) { maxOut := out maxTimes := [] } if (out == maxOut) { maxTimes with= time }
}
println(`Maximum simultaneous license use is $maxOut at the following times:`) for time in maxTimes {
println(` $time`)
}</lang>
Euphoria
<lang euphoria>function split(sequence s, integer c)
sequence out integer first, delim out = {} first = 1 while first <= length(s) do delim = find_from(c, s, first) if delim = 0 then delim = length(s) + 1 end if out = append(out, s[first..delim-1]) first = delim + 1 end while return out
end function
include get.e function val(sequence s)
sequence v v = value(s) return v[2] - v[1] * v[1]
end function
constant fn = open("mlijobs.txt", "r") integer maxout sequence jobs, line, maxtime object x jobs = {} maxout = 0 while 1 do
x = gets(fn) if atom(x) then exit end if line = split(x, ' ') line[$] = val(line[$]) if equal(line[2], "OUT") then jobs &= line[$] if length(jobs) > maxout then maxout = length(jobs) maxtime = {line[4]} elsif length(jobs) = maxout then maxtime = append(maxtime, line[4]) end if else jobs[find(line[$],jobs)] = jobs[$] jobs = jobs[1..$-1] end if
end while close(fn)
printf(1, "Maximum simultaneous license use is %d at the following times:\n", maxout) for i = 1 to length(maxtime) do
printf(1, "%s\n", {maxtime[i]})
end for</lang>
Output:
Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40
Factor
Placing the file in resource:work/mlijobs.txt:
<lang factor>USING: kernel sequences splitting math accessors io.encodings.ascii io.files math.parser io ; IN: maxlicenses
TUPLE: maxlicense max-count current-count times ;
<PRIVATE
- <maxlicense> ( -- max ) -1 0 V{ } clone \ maxlicense boa ; inline
- out? ( line -- ? ) [ "OUT" ] dip subseq? ; inline
- line-time ( line -- time ) " " split harvest fourth ; inline
- update-max-count ( max -- max' )
dup [ current-count>> ] [ max-count>> ] bi > [ dup current-count>> >>max-count V{ } clone >>times ] when ;
- (inc-current-count) ( max ? -- max' )
[ [ 1 + ] change-current-count ] [ [ 1 - ] change-current-count ] if update-max-count ; inline
- inc-current-count ( max ? time -- max' time )
[ (inc-current-count) ] dip ;
- current-max-equal? ( max -- max ? )
dup [ current-count>> ] [ max-count>> ] bi = ;
- update-time ( max time -- max' )
[ current-max-equal? ] dip swap [ [ suffix ] curry change-times ] [ drop ] if ;
- split-line ( line -- ? time ) [ out? ] [ line-time ] bi ;
- process ( max line -- max ) split-line inc-current-count update-time ;
PRIVATE>
- find-max-licenses ( -- max )
"resource:work/mlijobs.txt" ascii file-lines <maxlicense> [ process ] reduce ;
- print-max-licenses ( max -- )
[ times>> ] [ max-count>> ] bi "Maximum simultaneous license use is " write number>string write " at the following times: " print [ print ] each ;</lang>
<lang factor>( scratchpad ) [ find-max-licenses print-max-licenses ] time Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40 Running time: 0.16164423 seconds</lang>
Forth
<lang forth> 20 constant date-size create max-dates date-size 100 * allot variable max-out variable counter
stdin value input
- process ( addr len -- )
8 /string over 3 s" OUT" compare 0= if 1 counter +! counter @ max-out @ > if counter @ max-out ! drop 5 + date-size max-dates place else counter @ max-out @ = if drop 5 + date-size max-dates +place else 2drop then then else drop 2 s" IN" compare 0= if -1 counter +! then then ;
- main
0 max-out ! 0 counter ! s" mlijobs.txt" r/o open-file throw to input begin pad 80 input read-line throw while pad swap process repeat drop input close-file throw max-out @ . ." max licenses in use @" max-dates count type cr ;
main bye </lang>
Fortran
<lang fortran>
PROGRAM MAX_LICENSES IMPLICIT NONE INTEGER :: out=0, maxout=0, maxcount=0, err CHARACTER(50) :: line CHARACTER(19) :: maxtime(100) OPEN (UNIT=5, FILE="Licenses.txt", STATUS="OLD", IOSTAT=err) IF (err > 0) THEN WRITE(*,*) "Error opening file Licenses.txt" STOP END IF DO READ(5, "(A)", IOSTAT=err) line IF (err == -1) EXIT ! EOF detected IF (line(9:9) == "O") THEN out = out + 1 ELSE IF (line(9:9) == "I") THEN out = out - 1 END IF IF (out > maxout ) THEN maxout = maxout + 1 maxcount = 1 maxtime(maxcount) = line(15:33) ELSE IF (out == maxout) THEN maxcount = maxcount + 1 maxtime(maxcount) = line(15:33) END IF END DO CLOSE(5) WRITE(*,"(A,I4,A)") "Maximum simultaneous license use is", maxout, " at the following times:" WRITE(*,"(A)") maxtime(1:maxcount) END PROGRAM MAX_LICENSES
</lang> Output
Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40
Gema
Start with gema -f licenses.gema mlijobs.txt <lang gema> @set{count;0};@set{max;0}
License OUT \@ * *\n=@incr{count}@testmax{${count},*} License IN \@ * *\n=@decr{count} \Z=@report{${max},${times${max}}}
testmax:*,*=@cmpn{${max};$1;@set{max;$1};;}@append{times${count};$2\n}
report:*,*=Maximum simultaneous license use is * at\n* </lang> Output:
Maximum simultaneous license use is 99 at 2008/10/03_08:39:34 2008/10/03_08:40:40
Go
<lang go>package main
import (
"bufio" "fmt" "io" "os" "bytes"
)
var fn = "mlijobs.txt"
func main() {
f, err := os.Open(fn) if err != nil { fmt.Println(err) return } defer f.Close() var ml, out int var mlTimes []string in := []byte("IN") for lr := bufio.NewReader(f); ; { line, pref, err := lr.ReadLine() if err == io.EOF { break } if err != nil { fmt.Println(err) return } if pref { fmt.Println("Unexpected long line.") return } f := bytes.Fields(line) if len(f) != 7 { fmt.Println("unexpected format,", len(f), "fields.") return } if bytes.Equal(f[1], in) { out-- continue } out++ if out == ml { mlTimes = append(mlTimes, string(f[3])) continue } if out > ml { ml = out mlTimes = append(mlTimes[:0], string(f[3])) } } fmt.Println("max licenses:", ml) fmt.Println("at:") for _, t := range mlTimes { fmt.Println(" ", t) }
}</lang> Output:
max licenses: 99 at: 2008/10/03_08:39:34 2008/10/03_08:40:40
Haskell
<lang haskell> import Data.List
main = do
f <- readFile "./../Puzzels/Rosetta/inout.txt" let (ioo,dt) = unzip. map ((\(_:io:_:t:_)-> (io,t)). words) . lines $ f cio = drop 1 . scanl (\c io -> if io == "IN" then pred c else succ c) 0 $ ioo mo = maximum cio putStrLn $ "Maximum simultaneous license use is " ++ show mo ++ " at:" mapM_ (putStrLn . (dt!!)) . elemIndices mo $ cio
</lang>
HicEst
We open Licenses.txt in MatrixExplorer mode with 3 columns: IN/OUT, date_time, ID_nr. This allows to adress single file elements by Licenses(row, column). <lang HicEst>CHARACTER Licenses="Licenses.txt" REAL :: counts(1), Top10(10)
OPEN(FIle=Licenses, fmt='8x,A3,3x,A19,Nb ,', LENgth=lines)
ALLOCATE(counts, lines) counts(1) = 1 DO line = 2, lines
counts(line) = counts(line-1) + 1 - 2*(Licenses(line,1)=='IN')
ENDDO
SORT(Vector=counts, Descending=1, Index=Top10)
DO i = 1, LEN(Top10)
WRITE() counts(Top10(i)), Licenses(Top10(i), 2)
ENDDO
END</lang>
99 2008/10/03_08:40:40 99 2008/10/03_08:39:34 98 2008/10/03_08:40:47 98 2008/10/03_08:40:11 98 2008/10/03_08:39:46 98 2008/10/03_08:39:45 98 2008/10/03_08:39:30 97 2008/10/03_20:44:58 97 2008/10/03_08:41:36 97 2008/10/03_08:40:53
Icon and Unicon
The following solution works in both languages: <lang unicon>procedure main(A)
maxCount := count := 0
every !&input ? case tab(upto('@')) of { "License OUT ": { maxTime := (maxCount <:= (count +:= 1), []) put(maxTime, (maxCount = count, ="@ ", tab(find(" for ")))) } "License IN ": count -:= (count > 0, 1) # Error check }
write("There were ",maxCount," licenses out at:") every write("\t",!maxTime)
end</lang>
And a run of the program:
->ml <mlijobs.txt There were 99 licenses out at: 2008/10/03_08:39:34 2008/10/03_08:40:40 ->
J
<lang j> require 'files'
'I D' =: (8 ; 14+i.19) {"1 &.> <'m' fread 'licenses.txt' NB. read file as matrix, select columns lu =: +/\ _1 ^ 'OI' i. I NB. Number of licenses in use at any given time mx =: (I.@:= >./) lu NB. Indicies of maxima
NB. Output results (mx { D) ,~ 'Maximum simultaneous license use is ' , ' at the following times:' ,~ ": {. ,mx { lu</lang>
Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40
Java
<lang java5>import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.LinkedList;
public class License {
public static void main(String[] args) throws FileNotFoundException, IOException{ BufferedReader in = new BufferedReader(new FileReader(args[0])); int max = Integer.MIN_VALUE; LinkedList<String> dates = new LinkedList<String>(); String line; int count = 0; while((line = in.readLine()) != null){ if(line.startsWith("License OUT ")) count++; if(line.startsWith("License IN ")) count--; if(count > max){ max = count; String date = line.split(" ")[3]; dates.clear(); dates.add(date); }else if(count == max){ String date = line.split(" ")[3]; dates.add(date); } } System.out.println("Max licenses out: "+max); System.out.println("At time(s): "+dates); }
}</lang>
Max licenses out: 99 At time(s): [2008/10/03_08:39:34, 2008/10/03_08:40:40]
JavaScript
for the file i/o
<lang javascript>var file_system = new ActiveXObject("Scripting.FileSystemObject"); var fh = file_system.openTextFile('mlijobs.txt', 1); // 1 == open for reading var in_use = 0, max_in_use = -1, max_in_use_at = [];
while ( ! fh.atEndOfStream) {
var line = fh.readline(); if (line.substr(8,3) == "OUT") { in_use++; if (in_use > max_in_use) { max_in_use = in_use; max_in_use_at = [ line.split(' ')[3] ]; } else if (in_use == max_in_use) max_in_use_at.push( line.split(' ')[3] ); } else if (line.substr(8,2) == "IN") in_use--;
}
fh.close();
WScript.echo("Max licenses out: " + max_in_use + "\n " + max_in_use_at.join('\n '));</lang>
output:
Max licenses out: 99 2008/10/03_08:39:34 2008/10/03_08:40:40
K
<lang K> r:m@&a=x:|/a:+\{:[x[8+!3]~"OUT";1;-1]}'m:0:"mlijobs.txt";
`0:,/"Maximum simultaneous license use is ",$x; `0:" at the following times:\n";`0:r[;14+!19]</lang>
Output:
<lang K>Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40</lang>
Lua
<lang lua> filename = "mlijobs.txt" io.input( filename )
max_out, n_out = 0, 0 occurr_dates = {}
while true do
line = io.read( "*line" ) if line == nil then break end
if string.find( line, "OUT" ) ~= nil then n_out = n_out + 1 if n_out > max_out then max_out = n_out occurr_dates = {} occurr_dates[#occurr_dates+1] = string.match( line, "@ ([%d+%p]+)" ) elseif n_out == max_out then occurr_dates[#occurr_dates+1] = string.match( line, "@ ([%d+%p]+)" ) end else n_out = n_out - 1 end
end
print( "Maximum licenses in use:", max_out ) print( "Occurrences:" ) for i = 1, #occurr_dates do
print( "", occurr_dates[i] )
end</lang> Output:
Maximum licenses in use: 99 Occurrences: 2008/10/03_08:39:34 2008/10/03_08:40:40
M4
<lang M4> divert(-1) define(`current',0) define(`max',0) define(`OUT',`define(`current',incr(current))`'ifelse(eval(current>max),1,
`define(`max',current)`'divert(-1)`'undivert(1)`'divert(1)', `ifelse(current,max,`divert(1)undivert(1)')')')
define(`IN',`define(`current',decr(current))') define(`for',`divert(-1)') include(mlijobs.txt)) divert max undivert(1) </lang>
Output:
99 @ 2008/10/03_08:39:34 @ 2008/10/03_08:40:40
Mathematica
<lang Mathematica>LC = 0; LCMax = 0; Scan[
If[MemberQ[#, "OUT"], LC++; If[LCMax < LC, LCMax = LC; LCMaxtimes = {};]; If[LCMax == LC, AppendTo[LCMaxtimes, #4]], LC--;] &, Import["mlijobs.txt", "Table"]]
Print["The maximum number of licenses used was ", LCMax, ", at ", LCMaxtimes]
output: -> The maximum number of licenses used was 99, at {2008/10/03_08:39:34,2008/10/03_08:40:40}</lang>
MAXScript
<lang maxscript>fn licencesInUse = (
local logFile = openFile "mlijobs.txt" local out = 0 local maxOut = -1 local maxTimes = #()
while not EOF logFile do ( line = readLine logFile
if findString line "OUT" != undefined then ( out += 1 ) else ( out -= 1 )
if out > maxOut then ( maxOut = out maxTimes = #() )
if out == maxOut then ( append maxTimes (filterString line " ")[4] ) ) format "Maximum simultaneous license use is % at the following times:\n" maxOut
for time in maxTimes do ( format "%\n" time )
close logFile
)
licencesInUse()</lang> Output
Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40
OCaml
<lang ocaml>let () =
let out = ref 0 in let max_out = ref(-1) in let max_times = ref [] in
let ic = open_in "mlijobs.txt" in try while true do let line = input_line ic in let io, date, n = Scanf.sscanf line "License %3[IN OUT] %_c %19[0-9/:_] for job %d" (fun io date n -> (io, date, n)) in if io = "OUT" then incr out else decr out; if !out > !max_out then ( max_out := !out; max_times := [date]; ) else if !out = !max_out then max_times := date :: !max_times; done with End_of_file -> close_in ic; Printf.printf "Maximum simultaneous license use is %d \ at the following times:\n" !max_out; List.iter print_endline !max_times;
- </lang>
Oz
<lang oz>declare
fun {MaxLicenses Filename ?Times} InUse = {NewCell 0} MaxInUse = {NewCell 0} MaxTimes = {NewCell nil} in for Job in {ReadLines Filename} do case {List.take Job 11} of "License OUT" then InUse := @InUse + 1 if @InUse > @MaxInUse then MaxInUse := @InUse MaxTimes := nil end if @InUse == @MaxInUse then
JobTime = {Nth {String.tokens Job & } 4} in
MaxTimes := JobTime|@MaxTimes end [] "License IN " then InUse := @InUse - 1 end end Times = {Reverse @MaxTimes} @MaxInUse end
%% Helper. %% Returns a lazy list. So we don't keep the whole logfile in memory... fun {ReadLines Filename} F = {New class $ from Open.file Open.text end init(name:Filename)} fun lazy {ReadNext} case {F getS($)} of false then nil [] Line then Line|{ReadNext} end end in %% close file when handle becomes unreachable {Finalize.register F proc {$ F} {F close} end} {ReadNext} end
Times MaxInUse = {MaxLicenses "mlijobs.txt" ?Times}
in
{System.showInfo "Maximum simultaneous license use is "#MaxInUse#" at the following times:"} {ForAll Times System.showInfo}</lang>
Output:
Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40
PARI/GP
<lang parigp>license()={ my(v=externstr("type mlijobs.txt"),u,cur,rec,t); for(i=1,#v, u=Vec(v[i]); if(#u>9 && u[9] == "O", if(cur++>rec, rec=cur; t=[v[i]] , if(cur == rec,t=concat(t,[v[i]])) ) , cur-- ) ); print(apply(s->concat(vecextract(Vec(s),"15..33")), t)); rec };</lang>
["2008/10/03_08:39:34", "2008/10/03_08:40:40"] %1 = 99
Perl
<lang perl>#!/usr/bin/perl -w use strict;
my $out = 0; my $max_out = -1; my @max_times;
open FH, '<mlijobs.txt' or die "Can't open file: $!"; while (<FH>) {
chomp; if (/OUT/) { $out++; } else { $out--; } if ($out > $max_out) { $max_out = $out; @max_times = (); } if ($out == $max_out) { push @max_times, (split)[3]; }
} close FH;
print "Maximum simultaneous license use is $max_out at the following times:\n"; print " $_\n" foreach @max_times;</lang> Example output:
Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40
Perl 6
Redirecting the mlijobs.txt file to STDIN: <lang perl6>my %licenses;
%licenses<count max> = 0,0;
for $*IN.lines -> $line {
my ( $license, $date_time ); ( *, $license, *, $date_time ) = split /\s+/, $line; if $license eq 'OUT' { %licenses<count>++; if %licenses<count> > %licenses<max> { %licenses<max> = %licenses<count>; %licenses<times> = [$date_time]; } elsif %licenses<count> == %licenses<max> { %licenses<times>.push($date_time); } } else { if %licenses<count> == %licenses<max> { %licenses<times>[*-1] ~= " through " ~ $date_time; } %licenses<count>--; }
};
my $plural = %licenses<times>.elems == 1 ?? !! 's';
say "Maximum concurrent licenses in use: {%licenses<max>}, in the time period{$plural}:"; say join ",\n", %licenses<times>.list;</lang>
Example output:
Maximum concurrent licenses in use: 99, in the time periods: 2008/10/03_08:39:34 through 2008/10/03_08:39:45, 2008/10/03_08:40:40 through 2008/10/03_08:40:47
PHP
<lang php>$handle = fopen ("mlijobs.txt", "rb"); $maxcount = 0; $count = 0; $times = array(); while (!feof($handle)) {
$buffer = fgets($handle); $op = trim(substr($buffer,8,3));
switch ($op){ case 'IN': $count--; break; case 'OUT': $count++; preg_match('/([\d|\/|_|:]+)/',$buffer,$time); if($count>$maxcount){ $maxcount = $count; $times = Array($time[0]); }elseif($count == $maxcount){ $times[] = $time[0]; } break; } } fclose ($handle);
echo $maxcount . '
';
for($i=0;$i<count($times);$i++){
echo $times[$i] . '
';
}</lang>
99 2008/10/03_08:39:34 2008/10/03_08:40:40
PL/I
<lang PL/I> text3: procedure options (main); /* 19 November 2011 */
declare line character (80) varying; declare (nout, max_nout) fixed; declare saveline character (80) varying controlled; declare k fixed binary; declare in file input;
open file (in) title ('/TEXT-MAX.DAT,TYPE(TEXT),RECSIZE(80)' );
on endfile (in) go to finish_up;
max_nout, nout = 0; do forever; get file (in) edit (line) (L); if substr(line, 9, 4) = 'OUT' then nout = nout+1; else if substr(line, 9, 3) = 'IN' then nout = nout-1; if nout = max_nout then do; allocate saveline; saveline = line; end; if nout > max_nout then do; do while (allocation(saveline) > 0); free saveline; end; max_nout = nout; allocate saveline; saveline = line; end; end;
finish_up:
put skip list ('The maximum number of licences taken out = ' || max_nout); do while (allocation(saveline) > 0); k = index(saveline, '@'); if k > 0 then put skip list ('It occurred at ' || substr(saveline, k+1) ); free saveline; end;
end text3; </lang> OUTPUT:
The maximum number of licences taken out = 99 It occurred at 2008/10/03_08:40:40 for job 1837 It occurred at 2008/10/03_08:39:34 for job 1833
PicoLisp
Put the following into an executable file "licenses": <lang PicoLisp>#!/usr/bin/picolisp /usr/lib/picolisp/lib.l
(zero Count MaxCount)
(in (opt)
(while (split (line) " ") (case (pack (cadr (setq Line @))) (IN (dec 'Count) ) (OUT (let Time (cadddr Line) (cond ((> (inc 'Count) MaxCount) (setq MaxCount Count MaxTimes Time) ) ((= Count MaxCount) (setq MaxTimes (pack MaxTimes " and " Time)) ) ) ) ) ) ) )
(prinl "The biggest number of licenses is " MaxCount " at " MaxTimes " !") (bye)</lang> Then it can be called as
$ ./licenses mlijobs.txt The biggest number of licenses is 99 at 2008/10/03_08:39:34 and 2008/10/03_08:40:40 !
PureBasic
<lang PureBasic>OpenConsole()
If ReadFile(0, OpenFileRequester("Text processing/3","mlijobs.txt","All files",1))
While Not Eof(0) currline$=ReadString(0) If StringField(currline$,2," ")="OUT" counter+1 Else counter-1 EndIf If counter>max max=counter maxtime$=StringField(currline$,4," ") ElseIf counter=max maxtime$+#CRLF$+StringField(currline$,4," ") EndIf Wend PrintN(Str(max)+" license(s) used at ;"+#CRLF$+maxtime$) CloseFile(0)
Else
PrintN("Failed to open the file.")
EndIf
PrintN(#CRLF$+"Press ENTER to exit"): Input() CloseConsole()</lang>
99 license(s) used at ; 2008/10/03_08:39:34 2008/10/03_08:40:40 Press ENTER to exit
Python
<lang python>out = 0 max_out = -1 max_times = []
for job in open('mlijobs.txt'):
if "OUT" in job: out += 1 else: out -= 1 if out > max_out: max_out = out max_times = [] if out == max_out: max_times.append(job.split()[3])
print "Maximum simultaneous license use is", max_out, "at the following times:" for time in max_times:
print " ", time</lang>
Example output:
Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40
R
<lang R>
- Read in data, discard useless bits
dfr <- read.table("mlijobs.txt") dfr <- dfr[,c(2,4)]
- Find most concurrent licences, and when
n.checked.out <- cumsum(ifelse(dfr$V2=="OUT", 1, -1)) times <- strptime(dfr$V4, "%Y/%m/%d_%H:%M:%S") most.checked.out <- max(n.checked.out) when.most.checked.out <- times[which(n.checked.out==most.checked.out)]
- As a bonus, plot license use
plot(times, n.checked.out, type="s") </lang>
Racket
<lang racket>#lang racket
- reads a licence file on standard input
- returns max licences used and list of times this occurred
(define (count-licences)
(let inner ((ln (read-line)) (in-use 0) (max-in-use 0) (times-list null)) (if (eof-object? ln) (values max-in-use (reverse times-list)) (let ((mtch (regexp-match #px"License (IN |OUT) @ (.*) for job.*" ln))) (cond [(string=? "OUT" (second mtch)) (let ((in-use+1 (add1 in-use))) (cond [(> in-use+1 max-in-use) (inner (read-line) in-use+1 in-use+1 (list (third mtch)))] [(= in-use+1 max-in-use) (inner (read-line) in-use+1 max-in-use (cons (third mtch) times-list))] [else (inner (read-line) in-use+1 max-in-use times-list)]))] [(string=? "IN " (second mtch)) (inner (read-line) (sub1 in-use) max-in-use times-list)] [else (inner (read-line) in-use max-in-use times-list)])))))
(define-values (max-used max-used-when) (with-input-from-file "mlijobs.txt" count-licences)) (printf "Maximum licences in simultaneously used is ~a at the following times:~%"
max-used)
(for-each displayln max-used-when) </lang> Output:
Maximum licences in simultaneously used is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40
REXX
Version 1
<lang rexx> /*REXX program to process instrument data from a data file. */
numeric digits 20 /*allow for bigger numbers. */ ifid='LICENSE.LOG' /*the input file. */ ofid='LICENSE.REP' /*the report file. */ monthDays.=31 /*number of days in every month. */ monthDays.4 =30 monthDays.6 =30 monthDays.9 =30 monthDays.11=30
otime='9999 99 99 99 99 99' /*latest OUT time. */ itime='0000 00 00 00 00 00' /*latest IN time. */ lowjob=99999
highjob=0
do while lines(ifid)\==0 /*read until finished. */ rec=linein(ifid) /*read the next record (line). */ parse upper var rec . InOut . datestamp . . job# /*get some stuff*/ $datestamp=translate(datestamp,,'/:_') if InOut=='IN' then do in.job#=$datestamp /*<─────assign an IN record.*/ if $datestamp>Itime then itime=$datestamp end else do out.job#=$datestamp /*<─────assign an OUT record.*/ if $datestamp<otime then otime=$datestamp end lowjob=min( lowjob,job#) highjob=max(highjob,job#) end /*DO WHILE*/
has=0 maxhas=0 qtime=otime mtimeL=
do jjj=1 until qtime>itime has=inRange(qtime) if has==maxhas then mtimeL=qtime if has>maxhas then do maxhas=has mtime=qtime mtimes=qtime end qtime=addAsec(qtime) end /*DO UNTIL*/
call sy parse var mtimes yy mm dd hh mn ss; _=yy'/'mm"/"dd hh':'mn":"ss call sy 'maximum number of licenses out is ' maxhas " at " _
if mtimeL\== & mtimeL\==mtimes then
do maxhas__=left(,length(maxhas)+5) parse var mtimeL yy mm dd hh mn ss; _=yy'/'mm"/"dd hh':'mn":"ss call sy ' through ' maxhas__ _ end
exit
/*─────────────────────────────────────addAsec subroutine───────────────*/ addAsec: procedure expose monthDays.; parse arg yy mm dd hh mn ss ss=right(ss+1 ,2,0) ; if ss<60 then return yy mm dd hh mn ss ss=right(ss-60,2,0); mn=right(mn+1,2,0); if mn<60 then return yy mm dd hh mn ss mn=right(mn-60,2,0); hh=right(hh+1,2,0); if hh<24 then return yy mm dd hh mn ss monthDays.2=28+leapyear(yy) ??=monthDays.mm hh=right(hh-24,2,0); dd=right(dd+1,2,0); if dd<?? then return yy mm dd hh mn ss mm=right(mm-??,2,0); yy=right(yy+y,4,0) return yy mm dd hh mn ss
/*─────────────────────────────────────inRange subroutine───────────────*/ inRange: hases=0; parse arg xtime /*see if xtime is in jobs' range.*/
do j=lowjob to highjob if xtime << out.j then leave if xtime >> in.j then iterate hases=hases+1 end
return hases
/*─────────────────────────────────────LEAPYEAR subroutine──────────────*/ leapyear: procedure; arg y /*year could be: Y, YY, YYY, YYYY*/ if length(y)==2 then y=left(right(date(),4),2)y /*adjust for YY year.*/ if y//4\==0 then return 0 /* not ≈ by 4? Not a leapyear.*/ return y//100\==0 | y//400==0 /*apply 100 and 400 year rule. */
/*─────────────────────────────────────SY subroutine────────────────────*/ sy: procedure expose ofid; say arg(1); call lineout ofid,arg(1); return </lang> Output:
maximum number of licenses out is 99 at 2008/10/03 08:39:34 through 2008/10/03 08:40:47
Version 2 dual-coded for PC and TSO
<lang rexx>/* REXX **************************************************************
- 19.11.2012 Walter Pachl transscribed from PL/I
- and dual-coded (for PC (Windows) and TSO)
- /
Parse Source source call time 'R' Say source If left(source,7)='Windows' Then Do
fid='mlijobs.txt' Do i=1 By 1 While lines(fid)>0 l.i=linein(fid) End l.0=i-1 End
Else Do
"ALLOC FI(IN) DA(MLIJOBS.TEXT) SHR REUSE" 'EXECIO * DISKR IN (STEM L. FINIS' 'FREE FI(IN)' End
store.0=0 max_nout=0 nout =0 cnt=0 cnt.=0 do i=1 To l.0
line=l.i Parse Var line 9 inout +3 Select When inout='OUT' then nout = nout+1; When inout='IN' then nout = nout-1; Otherwise Iterate End cnt.nout=cnt.nout+1 cnt=cnt+1 if nout = max_nout then Call store line if nout > max_nout then Do max_nout=nout drop store. store.0=0 Call store end; end;
Say 'The maximum number of licences taken out = ' max_nout Do i=1 to store.0
k=pos('@',store.i) Say 'It occurred at 'substr(store.i,k+1) End
limit=5 Do nout=0 To max_nout
If nout=limit+1 Then Say '.........' If nout<=limit | nout>=max_nout-limit Then Say right(cnt.nout,5) right(nout,3) End
Say right(cnt,5) 'Jobs' Say time('E') 'seconds (elapsed)' Exit
store:
z=store.0+1 store.z=line store.0=z Return</lang>
Output:
TSO COMMAND LIC SYS00059 N555555.PRIV.CLIST ? TSO ISPF ? The maximum number of licences taken out = 99 It occurred at 2008/10/03_08:39:34 for job 1833 It occurred at 2008/10/03_08:40:40 for job 1837 1 0 2 1 2 2 2 3 2 4 2 5 ......... 24 94 22 95 15 96 7 97 5 98 2 99 10000 Jobs 0.384154 seconds (elapsed)
Ruby
<lang ruby>out = 0 max_out = -1 max_times = []
File.foreach('mlijobs.txt') do |line|
out += line.include?("OUT") ? 1 : -1 if out > max_out max_out = out max_times = [] end max_times << line.split[3] if out == max_out
end
puts "Maximum simultaneous license use is #{max_out} at the following times:" max_times.each {|time| puts " #{time}"}</lang>
Example output:
Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40
Run BASIC
<lang lb>open "c:\data\temp\logFile.txt" for input as #f while not(eof(#f))
line input #f, a$ if word$(a$,2," ") = "IN" then count = count - 1 else count = count + 1 maxCount = max(maxCount,count)
wend open "c:\data\temp\logFile.txt" for input as #f while not(eof(#f))
line input #f, a$ if word$(a$,2," ") = "IN" then count = count - 1 else count = count + 1 if count = maxCount then theDate$ = theDate$ + " | " + word$(a$,4," ") + " Job:";word$(a$,7," ")
wend print maxCount;" ";theDate$</lang>
Seed7
<lang seed7>$ include "seed7_05.s7i";
const proc: main is func
local var file: inFile is STD_NULL; var string: line is ""; var integer: currLicenses is 0; var integer: maxLicenses is 0; var array string: maxLicenseTimes is 0 times ""; var string: eventTime is ""; begin inFile := open("mlijobs.txt", "r"); while hasNext(inFile) do line := getln(inFile); if line[9 len 3] = "OUT" then incr(currLicenses); if currLicenses >= maxLicenses then if currLicenses > maxLicenses then maxLicenses := currLicenses; maxLicenseTimes := 0 times ""; end if; maxLicenseTimes &:= line[15 len 19]; end if; elsif currLicenses > 0 then decr(currLicenses); end if; end while; close(inFile); writeln("Maximum simultaneous license use is " <& maxLicenses <& " at the following times:"); for eventTime range maxLicenseTimes do writeln(eventTime); end for; end func;</lang>
Output:
Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 2008/10/03_08:40:40
Tcl
<lang tcl> set out 0
set max_out -1 set max_times {} foreach job [split [read [open "mlijobs.txt" "r"]] "\n"] { if {[lindex $job 1] == "OUT"} { incr out } { incr out -1 } if {$out > $max_out} { set max_out $out set max_times {} } if {$out == $max_out} { lappend max_times [lindex $job 3] } } puts "Maximum simultaneous license use is $max_out at the following times:" foreach t $max_times { puts " $t" }</lang>
Output matches Python
TUSCRIPT
<lang tuscript> $$ MODE TUSCRIPT joblog="mlijobs.txt",jobnrout=0 log=FILE (joblog) DICT jobnrout CREATE LOOP l=log jobout=EXTRACT (l,":License :"|,": :")
IF (jobout=="out") THEN time=EXTRACT (l,":@ :"|,": :"), jobnrout=jobnrout+1 DICT jobnrout APPEND/QUIET jobnrout,num,cnt,time;" " ELSE jobnrout=jobnrout-1 ENDIF
ENDLOOP DICT jobnrout UNLOAD jobnrout,num,cnt,time DICT jobnrout SIZE maxlicout times=SELECT (time,#maxlicout) PRINT "The max. number of licences out is ", maxlicout PRINT "at these times: ", times </lang> Output:
The max. number of licences out is 99 at these times: 2008/10/03_08:39:34 2008/10/03_08:40:40
Ursala
Four functions are defined. Log lexes the log file, which can be accessed as a pre-declared constant without explicit I/O by being given as a compile-time command line parameter. Scan accumulates running totals of licenses in use. Search identifies the maxima, and format transforms the results to human readable form.
<lang Ursala>
- import std
- import nat
log = ^(~&hh==`O,~&tth)*FtPS sep` *F mlijobs_dot_txt scan = @NiX ~&ar^& ^C/~&alrhr2X ~&arlh?/~&faNlCrtPXPR ~&fabt2R search = @lSzyCrSPp leql$^&hl@lK2; ^/length@hl ~&rS format = ^|C\~& --' licenses in use at'@h+ %nP
- show+
main = format search scan log</lang> output:
99 licenses in use at 2008/10/03_08:39:34 2008/10/03_08:40:40
Vedit macro language
<lang vedit> File_Open("|(PATH_ONLY)\data\mlijobs.txt", BROWSE)
- 1 = 0 // Number of licenses active
- 2 = 0 // Max number of active licenses found
Repeat(ALL) {
Search("|{OUT,IN}|W@", ADVANCE+ERRBREAK) if (Match_Item == 1) { // "OUT" #1++ if (#1 > #2) { // new high value #2 = #1 Reg_Empty(10) // empty the time list } if (#1 == #2) { // same as high value Reg_Copy(10, 1, APPEND) // store time } } else { // "IN" #1-- }
}
Message("Maximum simultaneous license use is ") Num_Type(#2, LEFT+NOCR) Message(" at the following times:\n") Reg_Type(10)
Buf_Quit(OK) </lang>
Output:
Maximum simultaneous license use is 99 at the following times: 2008/10/03_08:39:34 for job 1833 2008/10/03_08:40:40 for job 1837