From 6e927cd05b99848f3cd9c9edf8bc125538515423 Mon Sep 17 00:00:00 2001
From: John Costa <johncosta027@gmail.com>
Date: Mon, 2 Dec 2024 18:33:37 +0000
Subject: [PATCH] feat: day2

---
 AdventOfCode2024/bin/main.ml   |  2 +-
 AdventOfCode2024/lib/day_02.ml | 76 ++++++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+), 1 deletion(-)
 create mode 100644 AdventOfCode2024/lib/day_02.ml

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)