diff --git a/AdventOfCode2024/bin/main.ml b/AdventOfCode2024/bin/main.ml index 9687989..d617642 100644 --- a/AdventOfCode2024/bin/main.ml +++ b/AdventOfCode2024/bin/main.ml @@ -13,7 +13,7 @@ let read_lines name = let () = print_endline "\nAdvent of Code 2024"; let part1, part2 = - read_lines "./inputs/01.txt" |> AdventOfCode2024.Day_01.solve + read_lines "./inputs/02.txt" |> AdventOfCode2024.Day_02.solve in Printf.printf "Part 1: %s\nPart 2: %s\n" (string_of_int part1) (string_of_int part2) diff --git a/AdventOfCode2024/lib/day_02.ml b/AdventOfCode2024/lib/day_02.ml new file mode 100644 index 0000000..39fdfa3 --- /dev/null +++ b/AdventOfCode2024/lib/day_02.ml @@ -0,0 +1,76 @@ +open Scanf + +let handle_line line = sscanf line "%d %d" (fun num1 num2 -> (num1, num2)) +let sort_list l = List.sort compare l +let print_list l = List.iter (Printf.printf "%d ") l + +let line_to_list line = + String.split_on_char ' ' line |> List.map (fun i -> int_of_string i) + +let is_valid_report l = + let rec increasing l = + match l with + | [] -> true + | [ _ ] -> true + | head :: h2 :: tail -> + if head >= h2 || h2 - head > 3 then false else increasing ([ h2 ] @ tail) + in + let rec decreasing l = + match l with + | [] -> true + | [ _ ] -> true + | head :: h2 :: tail -> + if head <= h2 || head - h2 > 3 then false else decreasing ([ h2 ] @ tail) + in + + match l with + | [] -> true + | [ _ ] -> true + | h1 :: h2 :: tail -> + if h1 > h2 then decreasing ([ h1; h2 ] @ tail) + else increasing ([ h1; h2 ] @ tail) + +let rec range x y = if x > y then [] else x :: range (x + 1) y + +let list_premutations l = + let rec loop original_list nth index acc = + match original_list with + | [] -> acc + | head :: tail -> + if index == nth then loop tail nth (index + 1) acc + else loop tail nth (index + 1) ([ head ] @ acc) + in + let indexes = range 0 (List.length l - 1) in + + let premutations = + List.fold_left + (fun acc index -> [ List.rev (loop l index 0 []) ] @ acc) + [] indexes + in + premutations + +let list_or l = + let rec loop l' acc = + match l' with [] -> acc | head :: tail -> head || loop tail acc + in + loop l false + +let solve lines = + let reports = List.map line_to_list lines in + let part1 = + List.fold_left + (fun acc i -> if is_valid_report i then acc + 1 else acc) + 0 reports + in + let premutations = List.map list_premutations reports in + + let attempted_gaps = + List.map (fun i -> List.map is_valid_report i) premutations + in + + let part2 = + List.fold_left + (fun acc bool_list -> if list_or bool_list then acc + 1 else acc) + 0 attempted_gaps + in + (part1, part2)