Text processing/Max licenses in use: Difference between revisions
m ({{omit from|Openscad}}) |
(→{{header|Euphoria}}: Euphoria example added) |
||
Line 539: | Line 539: | ||
println(` $time`) |
println(` $time`) |
||
}</lang> |
}</lang> |
||
=={{header|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: |
|||
<pre>Maximum simultaneous license use is 99 at the following times: |
|||
2008/10/03_08:39:34 |
|||
2008/10/03_08:40:40 |
|||
</pre> |
|||
=={{header|Factor}}== |
=={{header|Factor}}== |
Revision as of 20:57, 28 August 2011
You are encouraged to solve this task according to the task description, using any language you may know.
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.
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 !
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> import std.stdio; import std.file; import std.string; void main() {
int maxlic = 0,currlic = 0; char[][]maxlic_times; foreach(line;split(cast(char[])read("mlijobs.txt"),"\n")) if (line.length) { if (line[8] == 'O') { // license out currlic++; if (currlic < maxlic) continue; if (currlic > maxlic) { maxlic = currlic; maxlic_times = null; } maxlic_times ~= line[14..33]; } else { // license in currlic--; } }
writefln("Found max %d licenses out at times:",maxlic); foreach(time;maxlic_times) { writefln("%s",time); }
} </lang>
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" "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 == os.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
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
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
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); /* 13 May 2010 */
declare line character (80) varying; declare (nout, max_nout) fixed; declare in file input;
open file (in) title ('/TEXT3.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 max_nout = nout; end;
finish_up:
put skip list ('The maximum number of licences taken out = ' || max_nout);
end text3; </lang> (more to come)
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>
REXX
<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
has=0 maxhas=0 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*/
qtime=otime
do until qtime>itime has=has+inRange(qtime) if has>maxhas then do maxhas=has mtime=qtime end has=0 qtime=addAsec(qtime) end /*DO UNTIL*/
parse var mtime yy mm dd hh mn ss; mtimef=yy'/'mm"/"dd hh':'mn":"ss call sy 'maximum number of licenses out is ' maxhas " at " mtimef 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; say arg(1); if 1==0 then call lineout ofid,arg(1) return </lang> Output:
maximum number of licenses out is 99 at 2008/10/03 08:39:34
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
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
- Programming Tasks
- Text processing
- Ada
- ALGOL 68
- APL
- AutoHotkey
- AWK
- C
- C++
- C sharp
- Common Lisp
- CL-PPCRE
- D
- E
- Euphoria
- Factor
- Forth
- Fortran
- Gema
- Go
- Haskell
- HicEst
- Icon
- Unicon
- J
- Java
- JavaScript
- Lua
- M4
- MAXScript
- OCaml
- Oz
- Perl
- Perl 6
- PHP
- PL/I
- PL/I examples needing attention
- Examples needing attention
- PicoLisp
- PureBasic
- Python
- R
- REXX
- REXX examples needing attention
- Ruby
- Tcl
- TUSCRIPT
- Ursala
- Vedit macro language
- GUISS/Omit
- Openscad/Omit
- PARI/GP/Omit