Day 3!
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
|||||||
./zig-cache
|
./zig-cache
|
||||||
_build
|
_build
|
||||||
*.txt
|
*.txt
|
||||||
|
dune.lock
|
||||||
|
@ -12,6 +12,7 @@ bug-reports: "https://github.com/username/reponame/issues"
|
|||||||
depends: [
|
depends: [
|
||||||
"ocaml"
|
"ocaml"
|
||||||
"dune" {>= "3.16"}
|
"dune" {>= "3.16"}
|
||||||
|
"re2"
|
||||||
"odoc" {with-doc}
|
"odoc" {with-doc}
|
||||||
]
|
]
|
||||||
build: [
|
build: [
|
||||||
|
@ -13,7 +13,7 @@ let read_lines name =
|
|||||||
let () =
|
let () =
|
||||||
print_endline "\nAdvent of Code 2024";
|
print_endline "\nAdvent of Code 2024";
|
||||||
let part1, part2 =
|
let part1, part2 =
|
||||||
read_lines "./inputs/02.txt" |> AdventOfCode2024.Day_02.solve
|
read_lines "./inputs/03.txt" |> AdventOfCode2024.Day_03.solve
|
||||||
in
|
in
|
||||||
Printf.printf "Part 1: %s\nPart 2: %s\n" (string_of_int part1)
|
Printf.printf "Part 1: %s\nPart 2: %s\n" (string_of_int part1)
|
||||||
(string_of_int part2)
|
(string_of_int part2)
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
(name AdventOfCode2024)
|
(name AdventOfCode2024)
|
||||||
(synopsis "A short synopsis")
|
(synopsis "A short synopsis")
|
||||||
(description "A longer description")
|
(description "A longer description")
|
||||||
(depends ocaml dune)
|
(depends ocaml dune re2)
|
||||||
(tags
|
(tags
|
||||||
(topics "to describe" your project)))
|
(topics "to describe" your project)))
|
||||||
|
|
||||||
|
117
AdventOfCode2024/lib/day_03.ml
Normal file
117
AdventOfCode2024/lib/day_03.ml
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
let rec print_list l =
|
||||||
|
match l with
|
||||||
|
| [] -> print_endline ""
|
||||||
|
| head :: tail ->
|
||||||
|
print_int head;
|
||||||
|
print_string " | ";
|
||||||
|
print_list tail
|
||||||
|
|
||||||
|
let rec print_s_list l =
|
||||||
|
match l with
|
||||||
|
| [] -> print_endline ""
|
||||||
|
| head :: tail ->
|
||||||
|
print_string head;
|
||||||
|
print_string " | ";
|
||||||
|
print_s_list tail
|
||||||
|
|
||||||
|
let rec print_tuple_list l =
|
||||||
|
match l with
|
||||||
|
| [] -> print_endline ""
|
||||||
|
| (index, value) :: tail ->
|
||||||
|
print_int index;
|
||||||
|
print_string ", ";
|
||||||
|
print_string (string_of_bool value);
|
||||||
|
print_string " | ";
|
||||||
|
print_tuple_list tail
|
||||||
|
|
||||||
|
let get_toggle_positions line =
|
||||||
|
let toggle_on_regex = Re2.create_exn {|do\(\)|} in
|
||||||
|
let toggle_off_regex = Re2.create_exn {|don't\(\)|} in
|
||||||
|
let on_matches = Re2.get_matches_exn toggle_on_regex line in
|
||||||
|
let off_matches = Re2.get_matches_exn toggle_off_regex line in
|
||||||
|
let get_indexes =
|
||||||
|
List.fold_left
|
||||||
|
(fun acc i ->
|
||||||
|
let start, _ = Re2.Match.get_pos_exn ~sub:(`Index 0) i in
|
||||||
|
[ start ] @ acc)
|
||||||
|
[]
|
||||||
|
in
|
||||||
|
|
||||||
|
let on_indexes = get_indexes on_matches in
|
||||||
|
let off_indexes = get_indexes off_matches in
|
||||||
|
List.sort
|
||||||
|
(fun (i, _) (j, _) -> i - j)
|
||||||
|
((List.rev on_indexes |> List.map (fun i -> (i, true)))
|
||||||
|
@ (List.rev off_indexes |> List.map (fun i -> (i, false))))
|
||||||
|
|
||||||
|
let get_all_numbers_positions line =
|
||||||
|
let instruction_regex = Re2.create_exn {|mul\((\d+),(\d+)\)|} in
|
||||||
|
let matches_indexes = Re2.get_matches_exn instruction_regex line in
|
||||||
|
let indexes =
|
||||||
|
List.fold_left
|
||||||
|
(fun acc i ->
|
||||||
|
let start, _ = Re2.Match.get_pos_exn ~sub:(`Index 0) i in
|
||||||
|
[ start ] @ acc)
|
||||||
|
[] matches_indexes
|
||||||
|
in
|
||||||
|
List.rev indexes
|
||||||
|
|
||||||
|
let get_all_numbers line =
|
||||||
|
let instruction_regex = Re2.create_exn {|mul\((\d+),(\d+)\)|} in
|
||||||
|
let matches = Re2.find_all_exn instruction_regex line in
|
||||||
|
let nums =
|
||||||
|
List.fold_left
|
||||||
|
(fun acc m ->
|
||||||
|
let num1, num2 = Scanf.sscanf m "mul(%d,%d)" (fun n1 n2 -> (n1, n2)) in
|
||||||
|
[ (num1, num2) ] @ acc)
|
||||||
|
[] matches
|
||||||
|
in
|
||||||
|
List.rev nums
|
||||||
|
|
||||||
|
let get_closest_item l item starting =
|
||||||
|
let rec get_closest_item' l closest item =
|
||||||
|
match l with
|
||||||
|
| [] -> closest
|
||||||
|
| (head, v) :: tail ->
|
||||||
|
if head < item then get_closest_item' tail (head, v) item else closest
|
||||||
|
in
|
||||||
|
get_closest_item' l (0, starting) item
|
||||||
|
|
||||||
|
let solve lines =
|
||||||
|
let part1 =
|
||||||
|
List.fold_left
|
||||||
|
(fun acc line ->
|
||||||
|
let line_value =
|
||||||
|
List.fold_left
|
||||||
|
(fun acc (num1, num2) -> acc + (num1 * num2))
|
||||||
|
0 (get_all_numbers line)
|
||||||
|
in
|
||||||
|
acc + line_value)
|
||||||
|
0 lines
|
||||||
|
in
|
||||||
|
|
||||||
|
let part2, _ =
|
||||||
|
List.fold_left
|
||||||
|
(fun (acc, toggle) line ->
|
||||||
|
let mul_indexes = get_all_numbers_positions line in
|
||||||
|
let mul_intructions = get_all_numbers line in
|
||||||
|
let toggles = get_toggle_positions line in
|
||||||
|
let closest_check = get_closest_item toggles in
|
||||||
|
|
||||||
|
let rec loop indexes instructions acc last_toggle =
|
||||||
|
match (indexes, instructions) with
|
||||||
|
| [], [] -> (acc, last_toggle)
|
||||||
|
| head :: tail, (n1, n2) :: in_tail ->
|
||||||
|
let _, is_on = closest_check head toggle in
|
||||||
|
|
||||||
|
let acc' = if is_on then acc + (n1 * n2) else acc in
|
||||||
|
loop tail in_tail acc' is_on
|
||||||
|
| _ -> (acc, last_toggle)
|
||||||
|
in
|
||||||
|
|
||||||
|
let acc', last_toggle = loop mul_indexes mul_intructions 0 toggle in
|
||||||
|
(acc + acc', last_toggle))
|
||||||
|
(0, true) lines
|
||||||
|
in
|
||||||
|
|
||||||
|
(part1, part2)
|
@ -1,2 +1,3 @@
|
|||||||
(library
|
(library
|
||||||
(name AdventOfCode2024))
|
(name AdventOfCode2024)
|
||||||
|
(libraries re2))
|
||||||
|
Reference in New Issue
Block a user