You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.6 KiB
OCaml
48 lines
1.6 KiB
OCaml
(* Common util. Should probably put this in a module or something.. *)
|
|
let get_one_line file =
|
|
try Some (input_line file) with
|
|
End_of_file -> None
|
|
|
|
let get_lines file =
|
|
let rec input lines =
|
|
match get_one_line file with
|
|
Some line -> input (line :: lines)
|
|
| None -> List.rev lines
|
|
in input []
|
|
|
|
let read_file file =
|
|
let channel = open_in(file) in
|
|
get_lines channel
|
|
|
|
let explode s = (* convert a string to a list of chars *)
|
|
let rec exp i l =
|
|
if i < 0 then l else exp (i - 1) (s.[i] :: l) in
|
|
exp (String.length s - 1) [];;
|
|
|
|
(* --- *)
|
|
|
|
let wrapped_y y map = (* wrap the y (horizontal) coordinate when off the map *)
|
|
y mod (List.length (List.nth map 1))
|
|
|
|
let read_cell map x y = (* return Some char at these coordinates, or None if below the map *)
|
|
if (x < List.length map)
|
|
then Some (List.nth (List.nth map x) (wrapped_y y map))
|
|
else None
|
|
|
|
let rec go map position slope count = (* move across the map, counting trees *)
|
|
let (x, y) = position in
|
|
let (dy, dx) = slope in (* suddenly regretting having x be the vertical axis.. *)
|
|
match read_cell map x y with
|
|
| None -> count (* off the map. stop counting *)
|
|
| Some '#' -> go map (x+dx, y+dy) slope (count+1)
|
|
| Some a -> go map (x+dx, y+dy) slope count
|
|
|
|
let map = read_file "day3.txt" |> List.map explode
|
|
let slopes = [(1, 1); (3, 1); (5, 1); (7, 1); (1, 2)]
|
|
let tree_counts = slopes |> List.map (fun slope -> go map (0, 0) slope 0);;
|
|
|
|
List.iter (fun count -> Printf.printf "Number of trees: %i\n" count) tree_counts;;
|
|
|
|
let product = List.fold_left ( * ) 1 tree_counts;;
|
|
Printf.printf "Product: %i\n" product
|