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))