51 lines
1.3 KiB
OCaml
51 lines
1.3 KiB
OCaml
|
let read_file_rev name =
|
||
|
let ic = open_in name in
|
||
|
let try_read () =
|
||
|
try Some (input_line ic)
|
||
|
with End_of_file -> None in
|
||
|
let rec loop acc =
|
||
|
match try_read () with
|
||
|
| Some s -> loop (s::acc)
|
||
|
| None -> close_in ic; acc in
|
||
|
List.rev (loop [])
|
||
|
|
||
|
|
||
|
let stepped_on_a_tree line pos =
|
||
|
let width = String.length line in
|
||
|
String.get line (pos mod width) = '#'
|
||
|
|
||
|
|
||
|
let rec skiii count pos_x pos_y right down = function
|
||
|
| [] -> count
|
||
|
| h :: t -> if pos_y mod down <> 0 then skiii count pos_x (pos_y + 1) right down t
|
||
|
else skiii (count + (if (stepped_on_a_tree h pos_x) then 1 else 0))
|
||
|
(pos_x + right)
|
||
|
(pos_y + 1)
|
||
|
right down t
|
||
|
|
||
|
let part1 l =
|
||
|
skiii 0 0 0 3 1 l
|
||
|
|
||
|
let part2 l =
|
||
|
(skiii 0 0 0 1 1 l) *
|
||
|
(skiii 0 0 0 3 1 l) *
|
||
|
(skiii 0 0 0 5 1 l) *
|
||
|
(skiii 0 0 0 7 1 l) *
|
||
|
(skiii 0 0 0 1 2 l)
|
||
|
|
||
|
|
||
|
let do_count filename = function
|
||
|
| 1 -> read_file_rev filename |> part1
|
||
|
| 2 -> read_file_rev filename |> part2
|
||
|
|
||
|
|
||
|
let () =
|
||
|
assert ((do_count "day3.test" 1) = 7)
|
||
|
let () =
|
||
|
print_endline (string_of_int (do_count "day3.input" 1))
|
||
|
|
||
|
let () =
|
||
|
assert ((do_count "day3.test" 2) = 336)
|
||
|
let () =
|
||
|
print_endline (string_of_int (do_count "day3.input" 2))
|