diff --git a/day2.ml b/day2.ml index 5964d0c..3cf4e8a 100644 --- a/day2.ml +++ b/day2.ml @@ -1,60 +1,32 @@ -module type Part = sig - type t - val parse_line: string -> t - val ok: t -> bool -end +type line = {first: int; second: int; char: char; pass: string} -let parse_line' f str = Scanf.sscanf str "%d - %d %c : %s" f +let parse_line str = Scanf.sscanf str "%d - %d %c : %s" + (fun first second char pass -> {first; second; char; pass}) -module Part1: Part = struct - type t = {min: int; max: int; char: char; pass: string} +let count_str c str = + let res = ref 0 in + String.iter (fun d -> if c = d then incr res) str; + !res - let parse_line = parse_line' - (fun min max char pass -> {min; max; char; pass}) +let ok1 {first; second; char; pass} = + let res = count_str char pass in + res >= first && res <= second - let count c str = - let res = ref 0 in - String.iter (fun d -> if c = d then incr res) str; - !res - - let ok {min; max; char; pass} = - let res = count char pass in - res >= min && res <= max -end +let ok2 {first; second; char; pass} = + (pass.[first - 1] = char) <> (pass.[second - 1] = char) -module Part2: Part = struct - type t = {pos1: int; pos2: int; char: char; pass: string} - - let parse_line = parse_line' - (fun pos1 pos2 char pass -> {pos1 = pos1 - 1; pos2 = pos2 - 1; char; pass}) - - let ok {pos1; pos2; char; pass} = - (pass.[pos1] = char) <> (pass.[pos2] = char) -end - - -module type Main = sig val run: string -> unit end - -module Main(P: Part)(): Main = struct - open P - - let count_all = ref 0 - let count_ok = ref 0 +let main' 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 + if ok l then incr count_ok in + Bracket.infile_iter_lines input ~line:parse_line ~iter:check; + Printf.printf "%d out of %d ok\n" !count_ok !count_all - let run input = - Bracket.infile_iter_lines input ~line:parse_line ~iter:check; - Printf.printf "%d out of %d ok\n" !count_ok !count_all -end - -let main' (module P: Part) = - let module M = Main(P)() in M.run - -let mains = [|main' (module Part1); main' (module Part2)|] +let mains = [|main' ok1; main' ok2|] let main = function | [part; input] -> mains.(int_of_string part - 1) input