38 lines
998 B
OCaml
38 lines
998 B
OCaml
type line = {first: int; second: int; char: char; pass: string}
|
|
|
|
let parse_line str = Scanf.sscanf str "%d - %d %c : %s"
|
|
(fun first second char pass -> {first; second; char; pass})
|
|
|
|
|
|
let count_str c str =
|
|
let res = ref 0 in
|
|
String.iter (fun d -> if c = d then incr res) str;
|
|
!res
|
|
|
|
let ok1 {first; second; char; pass} =
|
|
let res = count_str char pass in
|
|
res >= first && res <= second
|
|
|
|
let ok2 {first; second; char; pass} =
|
|
(pass.[first - 1] = char) <> (pass.[second - 1] = char)
|
|
|
|
|
|
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 in
|
|
Bracket.infile_iter_lines input ~line:parse_line ~iter:check;
|
|
Printf.printf "%d out of %d ok\n" !count_ok !count_all
|
|
|
|
let main = Misc.main 2 [|main' ok1; main' ok2|]
|
|
|
|
|
|
let%expect_test "part 1" =
|
|
main' ok1 "../../data/day2";
|
|
[%expect{| 607 out of 1000 ok |}]
|
|
|
|
let%expect_test "part 2" =
|
|
main' ok2 "../../data/day2";
|
|
[%expect{| 321 out of 1000 ok |}]
|