60 lines
1.3 KiB
OCaml
60 lines
1.3 KiB
OCaml
|
type space = Tree | Free
|
||
|
type map = space array array
|
||
|
|
||
|
let (.%()) arr i = arr.(i mod Array.length arr)
|
||
|
|
||
|
let iter_map ?(step_x=1) ?(step_y=1) f arr =
|
||
|
let i = ref 0 in
|
||
|
let j = ref 0 in
|
||
|
while !i < Array.length arr do
|
||
|
f arr.(!i).%(!j);
|
||
|
i := !i + step_x;
|
||
|
j := !j + step_y
|
||
|
done
|
||
|
|
||
|
|
||
|
exception Unknown_char of char
|
||
|
|
||
|
let make_line str =
|
||
|
Array.init (String.length str)
|
||
|
(fun i -> match str.[i] with
|
||
|
| '#' -> Tree
|
||
|
| '.' -> Free
|
||
|
| c -> raise (Unknown_char c))
|
||
|
|
||
|
let read_file = Bracket.infile_lines ~line:make_line ~of_seq:Array.of_seq
|
||
|
|
||
|
|
||
|
let count_trees ?step_x ?step_y map =
|
||
|
let count = ref 0 in
|
||
|
iter_map ?step_x ?step_y (function Tree -> incr count | _ -> ()) map;
|
||
|
!count
|
||
|
|
||
|
let main1 input =
|
||
|
Format.printf "%d trees\n"
|
||
|
(count_trees ~step_y:3 (read_file input))
|
||
|
|
||
|
let main2 input =
|
||
|
let map = read_file input in
|
||
|
let prod = List.fold_left ( * ) 1
|
||
|
[count_trees map;
|
||
|
count_trees map ~step_y:3;
|
||
|
count_trees map ~step_y:5;
|
||
|
count_trees map ~step_y:7;
|
||
|
count_trees map ~step_x:2] in
|
||
|
Format.printf "product: %d\n" prod
|
||
|
|
||
|
let mains = [|main1; main2|]
|
||
|
|
||
|
let main = function
|
||
|
| [part; input] -> mains.(int_of_string part - 1) input
|
||
|
| _ -> failwith "a"
|
||
|
|
||
|
let%expect_test _ =
|
||
|
main1 "../../data/day3";
|
||
|
[%expect{| 244 trees |}]
|
||
|
|
||
|
let%expect_test _ =
|
||
|
main2 "../../data/day3";
|
||
|
[%expect{| product: 9406609920 |}]
|