day 2
This commit is contained in:
parent
512ae7d3d7
commit
816b2851c4
5 changed files with 1052 additions and 9 deletions
|
@ -1,4 +1,4 @@
|
||||||
let days = [|Day1.main|]
|
let days = [|Day1.main; Day2.main|]
|
||||||
|
|
||||||
let _ =
|
let _ =
|
||||||
match Array.to_list Sys.argv with
|
match Array.to_list Sys.argv with
|
||||||
|
|
13
bracket.ml
13
bracket.ml
|
@ -1,17 +1,16 @@
|
||||||
let bracket ~make ~act ~free =
|
let bracket ~make:(lazy x) ~act ~free =
|
||||||
let x = make () in
|
|
||||||
match act x with
|
match act x with
|
||||||
| result -> free x; result
|
| result -> free x; result
|
||||||
| exception e -> free x; raise e
|
| exception e -> free x; raise e
|
||||||
|
|
||||||
let infile ~act name =
|
let infile ~act name =
|
||||||
bracket ~make:(fun () -> open_in name) ~act ~free:close_in_noerr
|
bracket ~make:(lazy (open_in name)) ~act ~free:close_in_noerr
|
||||||
|
|
||||||
let infile_lines ~line:f ~of_seq name =
|
let infile_lines ~line:f ~of_seq name =
|
||||||
let get_line file =
|
let get_line file =
|
||||||
match input_line file with
|
try Some (f (input_line file), file)
|
||||||
| exception End_of_file -> None
|
with End_of_file -> None in
|
||||||
| line -> Some (f line, file)
|
|
||||||
in
|
|
||||||
let act file = of_seq (Seq.unfold get_line file) in
|
let act file = of_seq (Seq.unfold get_line file) in
|
||||||
infile name ~act
|
infile name ~act
|
||||||
|
|
||||||
|
let infile_iter_lines ~line ~iter = infile_lines ~of_seq:(Seq.iter iter) ~line
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
val bracket: make:(unit -> 'a) -> act:('a -> 'b) -> free:('a -> unit) -> 'b
|
val bracket: make:('a Lazy.t) -> act:('a -> 'b) -> free:('a -> unit) -> 'b
|
||||||
|
|
||||||
val infile: act:(in_channel -> 'b) -> string -> 'b
|
val infile: act:(in_channel -> 'b) -> string -> 'b
|
||||||
|
|
||||||
val infile_lines: line:(string -> 'a) -> of_seq:('a Seq.t -> 'b) -> string -> 'b
|
val infile_lines: line:(string -> 'a) -> of_seq:('a Seq.t -> 'b) -> string -> 'b
|
||||||
|
|
||||||
|
val infile_iter_lines:
|
||||||
|
line:(string -> 'a) -> iter:('a -> unit) -> string -> unit
|
||||||
|
|
41
day2.ml
Normal file
41
day2.ml
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
let parse_line' f str = Scanf.sscanf str "%d - %d %c : %s%!" f
|
||||||
|
|
||||||
|
|
||||||
|
type part1 = {min: int; max: int; char: char; pass: string}
|
||||||
|
|
||||||
|
let parse_line1 = parse_line'
|
||||||
|
(fun min max char pass -> {min; max; char; pass})
|
||||||
|
|
||||||
|
let count c str =
|
||||||
|
let res = ref 0 in
|
||||||
|
String.iter (fun d -> if c = d then incr res) str;
|
||||||
|
!res
|
||||||
|
|
||||||
|
let ok1 {min; max; char; pass} =
|
||||||
|
let res = count char pass in
|
||||||
|
res >= min && res <= max
|
||||||
|
|
||||||
|
|
||||||
|
type part2 = {pos1: int; pos2: int; char: char; pass: string}
|
||||||
|
|
||||||
|
let parse_line2 = parse_line'
|
||||||
|
(fun pos1 pos2 char pass -> {pos1 = pos1 - 1; pos2 = pos2 - 1; char; pass})
|
||||||
|
|
||||||
|
let ok2 {pos1; pos2; char; pass} =
|
||||||
|
(pass.[pos1] = char) <> (pass.[pos2] = char)
|
||||||
|
|
||||||
|
|
||||||
|
let main' ~line ~ok input =
|
||||||
|
let count_all = ref 0 in
|
||||||
|
let count_ok = ref 0 in
|
||||||
|
let check l = incr count_all; if ok l then incr count_ok in
|
||||||
|
Bracket.infile_iter_lines input ~line ~iter:check;
|
||||||
|
Printf.printf "%d out of %d ok\n" !count_ok !count_all
|
||||||
|
|
||||||
|
let main1 = main' ~line:parse_line1 ~ok:ok1
|
||||||
|
let main2 = main' ~line:parse_line2 ~ok:ok2
|
||||||
|
let mains = [|main1; main2|]
|
||||||
|
|
||||||
|
let main = function
|
||||||
|
| [part; input] -> mains.(int_of_string part - 1) input
|
||||||
|
| _ -> Usage.exit "2 <part> <infile>"
|
Loading…
Reference in a new issue