summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Program.fs6
-rw-r--r--solutions/day11.fs108
2 files changed, 112 insertions, 2 deletions
diff --git a/Program.fs b/Program.fs
index fb79423..048cc71 100644
--- a/Program.fs
+++ b/Program.fs
@@ -26,7 +26,9 @@ match (day, part) with
 | (8, 2) -> printf $"{Day8.part2 ()}\n"
 | (9, 1) -> printf $"{Day9.part1 ()}\n"
 | (9, 2) -> printf $"{Day9.part2 ()}\n"
-| (10, 1) -> printf $"{Day10.part1()}\n"
-| (10, 2) -> printf $"{Day10.part2()}\n"
+| (10, 1) -> printf $"{Day10.part1 ()}\n"
+| (10, 2) -> printf $"{Day10.part2 ()}\n"
+| (11, 1) -> printf $"{Day11.part1 ()}\n"
+| (11, 2) -> printf $"{Day11.part2 ()}\n"
 | (x, y) when (1 <= x && x <= 25) && (y = 1 || y = 2)  -> raise (NotImplemented("not implemented yet"))
 | _ -> raise (NotImplemented("invalid values"))
\ No newline at end of file
diff --git a/solutions/day11.fs b/solutions/day11.fs
new file mode 100644
index 0000000..2b93042
--- /dev/null
+++ b/solutions/day11.fs
@@ -0,0 +1,108 @@
+namespace Solutions
+
+module Day11 =
+    type Monkey = {
+        Items: int64 list
+        Operation: int64 -> int64
+        Test: int64
+        TrueMonkey: int
+        FalseMonkey: int
+        Inspections: int64
+    }
+
+    let monkeys = 
+        [ { Items = [89; 95; 92; 64; 87; 68]
+            Operation = (*) 11L
+            Test = 2
+            TrueMonkey = 7
+            FalseMonkey = 4
+            Inspections = 0 }
+          { Items = [87; 67]
+            Operation = (+) 1L;
+            Test = 13;
+            TrueMonkey = 3
+            FalseMonkey = 6
+            Inspections = 0 }
+          { Items = [95; 79; 92; 82; 60]
+            Operation = (+) 6L
+            Test = 3
+            TrueMonkey = 1
+            FalseMonkey = 6
+            Inspections = 0 }
+          { Items = [67; 97; 56]
+            Operation = fun x -> x * x
+            Test = 17
+            TrueMonkey = 7
+            FalseMonkey = 0
+            Inspections = 0 }
+          { Items = [80; 68; 87; 94; 61; 59; 50; 68]
+            Operation = (*) 7L
+            Test = 19
+            TrueMonkey = 5
+            FalseMonkey = 2
+            Inspections = 0 }
+          { Items = [73; 51; 76; 59]
+            Operation = (+) 8L
+            Test = 7
+            TrueMonkey = 2
+            FalseMonkey = 1
+            Inspections = 0 }
+          { Items = [92]
+            Operation = (+) 5L
+            Test = 11
+            TrueMonkey = 3
+            FalseMonkey = 0
+            Inspections = 0 }
+          { Items = [99; 76; 78; 76; 79; 90; 89]
+            Operation = (+) 7L
+            Test = 5
+            TrueMonkey = 4
+            FalseMonkey = 5
+            Inspections = 0 } ]
+    
+    let throw item target monkeys =
+        let monkey = List.item target monkeys
+        
+        List.updateAt target {monkey with Items = (List.append monkey.Items [item])} monkeys
+
+    let doItem operation monkey monkeys item =
+        let worryLevel = monkey.Operation item
+        let boredLevel = operation worryLevel
+        let target = if boredLevel % monkey.Test = 0L then monkey.TrueMonkey else monkey.FalseMonkey
+        throw boredLevel target monkeys
+    
+    let playTurn operation monkeys id =
+        let monkey = List.item id monkeys
+
+        let cleared = monkeys 
+                      |> List.updateAt 
+                                id 
+                                {monkey with Items = []
+                                             Inspections = monkey.Inspections + (int64 monkey.Items.Length)}
+        
+        monkey.Items |> List.fold (doItem operation monkey) cleared
+    
+    let playRound operation monkeys =
+        let players = [ 0 .. (List.length monkeys - 1)]
+        List.fold (playTurn operation) monkeys players
+    
+    let rec playRounds operation nb monkeys =
+        if nb = 0 then monkeys
+        else
+            let next = playRound operation monkeys
+            playRounds operation (nb - 1) next
+
+    let solve operation count =
+        monkeys
+        |> playRounds operation count
+        |> List.map (fun m -> m.Inspections)
+        |> List.sortDescending
+        |> List.take 2
+        |> List.reduce (*)
+
+    let part1 () = 
+        solve (fun x -> x / 3L) 20
+    
+    let part2 () = 
+        let safeMod = monkeys |> Seq.map (fun m -> m.Test) |> Seq.reduce (*)
+        solve (fun x -> x % safeMod) 10_000