2024 day 10
This commit is contained in:
61
bin/day2410.ml
Normal file
61
bin/day2410.ml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
type grid = { grid : string; width : int; height : int }
|
||||||
|
|
||||||
|
let grid_of_file fname =
|
||||||
|
let strs = Aoc.strings_of_file fname in
|
||||||
|
let grid = List.fold_left String.cat "" strs in
|
||||||
|
let width = String.length (List.hd strs) in
|
||||||
|
let height = String.length grid / width in
|
||||||
|
{ grid; width; height }
|
||||||
|
|
||||||
|
let grid_length grid = String.length grid.grid
|
||||||
|
let grid_get_by_idx grid idx = grid.grid.[idx]
|
||||||
|
let grid_get_by_pos grid (x, y) = grid.grid.[x + (y * grid.width)]
|
||||||
|
let grid_pos_of_idx grid idx = (idx mod grid.width, idx / grid.width)
|
||||||
|
|
||||||
|
let grid_pos_is_valid grid (x, y) =
|
||||||
|
x >= 0 && y >= 0 && x < grid.width && y < grid.height
|
||||||
|
|
||||||
|
let next_char ch = Char.chr (1 + Char.code ch)
|
||||||
|
let ten = next_char '9'
|
||||||
|
let one = '1'
|
||||||
|
|
||||||
|
let find_trail grid pos0 =
|
||||||
|
let add_pos lst pos digit =
|
||||||
|
if grid_pos_is_valid grid pos && grid_get_by_pos grid pos = digit then
|
||||||
|
pos :: lst
|
||||||
|
else lst
|
||||||
|
in
|
||||||
|
let add_poses lst (x, y) digit =
|
||||||
|
let lst = add_pos lst (x - 1, y) digit in
|
||||||
|
let lst = add_pos lst (x + 1, y) digit in
|
||||||
|
let lst = add_pos lst (x, y - 1) digit in
|
||||||
|
let lst = add_pos lst (x, y + 1) digit in
|
||||||
|
lst
|
||||||
|
in
|
||||||
|
let rec find_next acc digit = function
|
||||||
|
| [] -> acc
|
||||||
|
| h :: t -> find_next (add_poses acc h digit) digit t
|
||||||
|
in
|
||||||
|
let rec impl acc digit =
|
||||||
|
if digit = ten then acc else impl (find_next [] digit acc) (next_char digit)
|
||||||
|
in
|
||||||
|
impl [ pos0 ] one
|
||||||
|
|
||||||
|
let find_trails grid =
|
||||||
|
let rec impl acc idx =
|
||||||
|
if idx >= grid_length grid then acc
|
||||||
|
else if grid_get_by_idx grid idx <> '0' then impl acc (idx + 1)
|
||||||
|
else (* grid_get_by_idx grid idx = 0 *)
|
||||||
|
impl (find_trail grid (grid_pos_of_idx grid idx) :: acc) (idx + 1)
|
||||||
|
in
|
||||||
|
impl [] 0 |> List.rev
|
||||||
|
|
||||||
|
let part1 grid =
|
||||||
|
find_trails grid
|
||||||
|
|> List.map (List.sort_uniq compare)
|
||||||
|
|> List.map List.length |> List.fold_left ( + ) 0
|
||||||
|
|
||||||
|
let part2 grid =
|
||||||
|
find_trails grid |> List.map List.length |> List.fold_left ( + ) 0
|
||||||
|
|
||||||
|
let _ = Aoc.main grid_of_file [ (string_of_int, part1); (string_of_int, part2) ]
|
Reference in New Issue
Block a user