Files
ocaml-aoc/bin/day2404.ml
Matthew Gretton-Dann 003fac75d6 2024 day 4 part 2.
Not happy with this part - not so functional.
2024-12-04 15:30:05 +00:00

71 lines
1.9 KiB
OCaml

let search_string big little =
let re = Str.regexp_string little in
let rec impl acc pos =
try
let _ = Str.search_forward re big pos in
impl (acc + 1) (Str.match_end ())
with Not_found -> acc
in
impl 0 0
let is_inbounds sa (x, y) =
y >= 0 && y < Array.length sa && x >= 0 && x < String.length sa.(y)
let gen_string sa (x, y) (dx, dy) =
let rec impl acc x y =
if is_inbounds sa (x, y) then
impl (String.cat acc (String.make 1 sa.(y).[x])) (x + dx) (y + dy)
else acc
in
impl "" x y
let gen_strings sa (x, y) (dx, dy) (dx2, d2y) =
let rec impl acc x y =
if is_inbounds sa (x, y) then
let s = gen_string sa (x, y) (dx, dy) in
impl (s :: acc) (x + dx2) (y + d2y)
else acc
in
List.rev (impl [] x y)
let gen_search_strings sa =
let right = String.length sa.(0) - 1 in
gen_strings sa (0, 0) (1, 0) (0, 1)
@ gen_strings sa (0, 0) (0, 1) (1, 0)
@ gen_strings sa (0, 0) (1, 1) (1, 0)
@ gen_strings sa (0, 1) (1, 1) (0, 1)
@ gen_strings sa (right, 0) (-1, 1) (-1, 0)
@ gen_strings sa (right, 1) (-1, 1) (0, 1)
@ []
let find_xmas sa =
let search_strings = gen_search_strings sa in
List.fold_left (fun acc x -> acc + search_string x "XMAS") 0 search_strings
+ List.fold_left (fun acc x -> acc + search_string x "SAMX") 0 search_strings
let find_mas sa x y =
let find_ms a b c d =
sa.(y - 1).[x - 1] = a
&& sa.(y - 1).[x + 1] = b
&& sa.(y + 1).[x - 1] = c
&& sa.(y + 1).[x + 1] = d
in
sa.(y).[x] = 'A'
&& (find_ms 'M' 'M' 'S' 'S' || find_ms 'S' 'S' 'M' 'M'
|| find_ms 'M' 'S' 'M' 'S' || find_ms 'S' 'M' 'S' 'M')
let find_mases sa =
let acc = ref 0 in
for y = 1 to Array.length sa - 2 do
for x = 1 to String.length sa.(y) - 2 do
if find_mas sa x y then acc := !acc + 1
done
done;
!acc
let sa_of_file fname = Aoc.strings_of_file fname |> Array.of_list
let _ =
Aoc.main sa_of_file
[ (string_of_int, find_xmas); (string_of_int, find_mases) ]