Day 3!
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
||||
./zig-cache
|
||||
_build
|
||||
*.txt
|
||||
dune.lock
|
||||
|
@ -12,6 +12,7 @@ bug-reports: "https://github.com/username/reponame/issues"
|
||||
depends: [
|
||||
"ocaml"
|
||||
"dune" {>= "3.16"}
|
||||
"re2"
|
||||
"odoc" {with-doc}
|
||||
]
|
||||
build: [
|
||||
|
@ -13,7 +13,7 @@ let read_lines name =
|
||||
let () =
|
||||
print_endline "\nAdvent of Code 2024";
|
||||
let part1, part2 =
|
||||
read_lines "./inputs/02.txt" |> AdventOfCode2024.Day_02.solve
|
||||
read_lines "./inputs/03.txt" |> AdventOfCode2024.Day_03.solve
|
||||
in
|
||||
Printf.printf "Part 1: %s\nPart 2: %s\n" (string_of_int part1)
|
||||
(string_of_int part2)
|
||||
|
@ -19,7 +19,7 @@
|
||||
(name AdventOfCode2024)
|
||||
(synopsis "A short synopsis")
|
||||
(description "A longer description")
|
||||
(depends ocaml dune)
|
||||
(depends ocaml dune re2)
|
||||
(tags
|
||||
(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
|
||||
(name AdventOfCode2024))
|
||||
(name AdventOfCode2024)
|
||||
(libraries re2))
|
||||
|
Reference in New Issue
Block a user