From 68615a9ad2c942254135cffb00cf25a84a3b1356 Mon Sep 17 00:00:00 2001 From: Prefetch Date: Sat, 31 Dec 2022 22:21:39 +0100 Subject: Initial commit --- .gitignore | 1 + 01/input.txt | 1 + 01/main.py | 35 ++ 01/test.py | 60 ++++ 02/input.txt | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 02/main.py | 42 +++ 02/test.py | 32 ++ 03/input.txt | 1 + 03/main.py | 48 +++ 03/test.py | 40 +++ 04/main.py | 33 ++ 04/test.py | 21 ++ 05/input.txt | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 05/main.py | 73 +++++ 05/test.py | 32 ++ 06/input.txt | 300 ++++++++++++++++++ 06/main.py | 53 ++++ 06/test.py | 36 +++ 07/input.txt | 339 ++++++++++++++++++++ 07/main.py | 61 ++++ 07/test.py | 57 ++++ 08/input.txt | 300 ++++++++++++++++++ 08/main.py | 64 ++++ 08/test.py | 18 ++ 09/input.txt | 28 ++ 09/main.py | 60 ++++ 09/test.py | 22 ++ 10/main.py | 41 +++ 10/test.py | 28 ++ 11/main.py | 71 +++++ 11/test.py | 23 ++ 12/input.txt | 1 + 12/main.py | 41 +++ 12/test.py | 65 ++++ 13/input.txt | 56 ++++ 13/main.py | 72 +++++ 13/test.py | 30 ++ 14/input.txt | 9 + 14/main.py | 75 +++++ 14/test.py | 21 ++ 15/input.txt | 4 + 15/main.py | 78 +++++ 15/test.py | 23 ++ 16/input.txt | 500 +++++++++++++++++++++++++++++ 16/main.py | 66 ++++ 17/input.txt | 20 ++ 17/main.py | 52 +++ 17/test.py | 19 ++ 18/input.txt | 100 ++++++ 18/main.py | 59 ++++ 18/test.py | 25 ++ 19/input.txt | 45 +++ 19/main.py | 128 ++++++++ 19/test.py | 39 +++ 20/main.py | 45 +++ 20/test.py | 16 + 21/input.txt | 3 + 21/main.py | 155 +++++++++ 21/test.py | 27 ++ 22/input.txt | 2 + 22/main.py | 137 ++++++++ 22/test.py | 39 +++ 23/input.txt | 47 +++ 23/main.py | 65 ++++ 23/test.py | 22 ++ 24/input.txt | 28 ++ 24/main.py | 86 +++++ 24/test.py | 18 ++ 25/input.txt | 1 + 25/main.py | 47 +++ 25/test.py | 17 + 71 files changed, 6203 insertions(+) create mode 100644 .gitignore create mode 100644 01/input.txt create mode 100755 01/main.py create mode 100755 01/test.py create mode 100644 02/input.txt create mode 100755 02/main.py create mode 100755 02/test.py create mode 100644 03/input.txt create mode 100755 03/main.py create mode 100755 03/test.py create mode 100755 04/main.py create mode 100755 04/test.py create mode 100644 05/input.txt create mode 100755 05/main.py create mode 100755 05/test.py create mode 100644 06/input.txt create mode 100755 06/main.py create mode 100755 06/test.py create mode 100644 07/input.txt create mode 100755 07/main.py create mode 100755 07/test.py create mode 100644 08/input.txt create mode 100755 08/main.py create mode 100755 08/test.py create mode 100644 09/input.txt create mode 100755 09/main.py create mode 100755 09/test.py create mode 100755 10/main.py create mode 100755 10/test.py create mode 100755 11/main.py create mode 100755 11/test.py create mode 100644 12/input.txt create mode 100755 12/main.py create mode 100755 12/test.py create mode 100644 13/input.txt create mode 100755 13/main.py create mode 100755 13/test.py create mode 100644 14/input.txt create mode 100755 14/main.py create mode 100755 14/test.py create mode 100644 15/input.txt create mode 100755 15/main.py create mode 100755 15/test.py create mode 100644 16/input.txt create mode 100755 16/main.py create mode 100644 17/input.txt create mode 100755 17/main.py create mode 100755 17/test.py create mode 100644 18/input.txt create mode 100755 18/main.py create mode 100755 18/test.py create mode 100644 19/input.txt create mode 100755 19/main.py create mode 100755 19/test.py create mode 100755 20/main.py create mode 100755 20/test.py create mode 100644 21/input.txt create mode 100755 21/main.py create mode 100755 21/test.py create mode 100644 22/input.txt create mode 100755 22/main.py create mode 100755 22/test.py create mode 100644 23/input.txt create mode 100755 23/main.py create mode 100755 23/test.py create mode 100644 24/input.txt create mode 100755 24/main.py create mode 100755 24/test.py create mode 100644 25/input.txt create mode 100755 25/main.py create mode 100755 25/test.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/01/input.txt b/01/input.txt new file mode 100644 index 0000000..becde71 --- /dev/null +++ b/01/input.txt @@ -0,0 +1 @@ +((((()(()(((((((()))(((()((((()())(())()(((()((((((()((()(()(((()(()((())))()((()()())))))))))()((((((())((()))(((((()(((((((((()()))((()(())()((())((()(()))((()))()))()(((((()(((()()))()())((()((((())()())()((((())()(()(()(((()(())(()(())(((((((())()()(((())(()(()(()(())))(()((((())((()))(((()(()()(((((()()(()(((()(((((())()))()((()(()))()((()((((())((((())(()(((())()()(()()()()()(())((((())((())(()()))()((((())))((((()())()((((())((()())((())(())(((((()((((()(((()((((())(()(((()()))()))((((((()((())()())))(((()(()))(()()(()(((()(()))((()()()())((()()()(((())())()())())())((()))(()(()))(((((()(()(())((()(())(())()((((()())()))((((())(())((())())((((()(((())(())((()()((((()((((((()(())()()(()(()()((((()))(())()())()))(())))(())))())()()(())(()))()((()(()(())()()))(()())))))(()))(()()))(())(((((()(()(()()((())()())))))((())())((())(()(())((()))(())(((()((((((((()()()(()))()()(((()))()((()()(())(())())()(()(())))(((((()(())(())(()))))())()))(()))()(()(((((((()((((())))())())())())()((((((((((((((()()((((((()()()())())()())())())(())(())))())((()())((()(()))))))()))))))))))))))))())((())((())()()))))))(((()((()(()()))((())(()()))()()())))(())))))))(()(((())))())()())))()()(())()))()(()))())((()()))))(()))))()))(()()(())))))))()(((()))))()(()))(())())))))()))((()))((()))())(())))))))))((((())()))()))()))())(())()()(())))())))(()())()))((()()(())))(())((((((()(())((()(((()(()()(())))()))))))()))()(()((()))()(()))(()(((())((((())())(())(()))))))))())))))))())())))))())))))()()(((())()(()))))))))())))))(())()()()))()))()))(()(())()()())())))))))())()(()(()))))()()()))))())(()))))()()))))()())))))(((())()()))(()))))))))))()()))))()()()))))(()())())()()())()(()))))()(()))(())))))))(((((())(())())()()))()()))(())))))()(()))))(())(()()))()())()))()))()))()))))())()()))())())))(()))(()))))))())()(((())()))))))))()))()())))())))())))()))))))))))()()))(()()))))))(())()(()))))())(()))))(()))))(()())))))())())()()))))())()))))))))(()))))()))))))()(()())))))))()))())))())))())))())))))))())(()()))))))(()())())))()())()))))))))))))))())))()(())))()))())()()(())(()()))(())))())()())(()(()(()))))())))))))))))())(()))()))()))))(())()())()())))))))))))()()))))))))))))())())))))(()())))))))))))())(())))()))))))))())())(()))()))(())))()))()()(())()))))))()((((())()))())())))))()))()))))((()())()))))())))(())))))))))))))))))()))))()()())()))()()))))())()))((()())))())))(()))(()())))))))()))()))))(())))))))(())))))())()()(()))())()))()()))))())()()))))())()))())))))))(()))))()())()))))))))(()))())))(()))()))))(())()))())())(())())())))))))((((())))))()))()))()())()(())))()))()))()())(()())()()(()())()))))())())))))(()))()))))())(()()(())))))(())()()((())())))))(())(())))))))())))))))))()(())))))))()())())())()(()))))))))(()))))))))())()()))()(()))))))()))))))())))))))(())))()()(())()())))))(((())))()((())()))())))(()()))())(())())))()(((()())))))()(()()())))()()(()()(()()))())()(()()()))())()()))()())(()))))())))))())))(())()()))))(()))))(())(()))(())))))()()))()))))())()))()()(())())))((()))())()))))))()()))))((()(()))))()()))))))())))))())(()((()())))))))))))()())())))()))(()))))))(()))(())()())))(()))))))))())()()()()))))(()())))))))((())))()))(()))(())(())()())()))))))))(())))())))(()))()()))(()()))(()))())))()(())))())((()((()(())))((())))()))))((((())())()())))(())))()))))))())(()()((())))())()(()())))))(()())()))())))))))((())())))))))(()(()))())()()(()()(((()(((()())))))()))))))()(())(()()((()()(())()()))())()())()))()())())())))))))(((())))))))()()))))))(((())()))(()()))(()()))))(()(()()((((())()())((()()))))(()(())))))()((()()()())()()((()((()()))(()))(((()()()))(((())))()(((())()))))))((()(())())))(()())(((((()(()))(()((()))(()())()))))(()(()))()(()))(())(((())(()()))))()()))(((()))))(()()()()))())))((()()()(())()))()))))()()))()))))))((((((()()()))))())((()()(((()))))(()(())(()()())())())))()(((()()))(())((())))(()))(()()()())((())())())(()))))()))()((()(())()(()()(())(()))(())()))(())(()))))(())(())())(()()(()((()()((())))((()))()((())))(((()()()()((((()))(()()))()()()(((())((())())(()()(()()()))()((())(())()))())(((()()(())))()((()()())()())(()(())())(((())(())())((())(())()(((()()))(())))((())(()())())(())((()()()((((((())))((()(((((())()))()))(())(()()))()))(())()()))(())((()()())()()(()))())()((())))()((()()())((((()())((())())())((()((()))()))((())((()()(()((()()(((())(()()))))((()((())()(((())(()((())())((())(()((((((())())()(()())()(())(((())((((((()(())(()((()()()((()()(()()()())))()()(((((()()))()((((((()))()(()(()(()(((()())((()))())()((()))(())))()))()()))())()()))())((((())(()(()))(((((((())(((()(((((()(((()()((((())(((())())))(()()()(()(()))()))((((((()))((()(((()(())((()((((()((((((())(((((())))(((()(()))))(((()(((())()((())(()((()))(((()()(((())((((()(()(((((()))(((()(((((((()(()()()(()(()(()()())(())(((((()(())())()())(()(()(()))()(()()()())(()()(()((()))()((())())()(()))((())(()))()(()))()(((()(()(()((((((()()()()())()(((((()()(((()()()((()(((((()))((((((((()()()(((((()))))))(()()()(())(()))(()()))))(())()))(((((()(((((()()(()(()())(((()))((((()((()(()(()((()(()((())))()(((()((()))((()))(((((((((()((()((()(())))()((((()((()()))((())(((()(((((()()(()(()()((()(()()()(((((((())())()())))))((((()()(()))()))(()((())()(()(((((((((()()(((()(()())(()((()())((())())((((()(((()(((()((((()((()((((()(()((((((())((((((((((((()()(()()((((((((((((((()((()()))()((((((((((((())((((()(()())((()(()(()))()(((((()()(((()()))()())(())((()(((((()((())(((((()((()(((((()))()()((((())()((((())(((((((((()(())(()(())))())(()((())(((())(())(())())(()(()(())()()((()((())()(((()(((((()(())))()(((()((())))((()()()(((()(((()((()(()(())(()((()())(()(()(((()(((((((((())(()((((()()))(()((((()()()()(((()((((((((()(()()((((((()(()()(()((()((((((((((()()(((((((()())(())))(((()()))(((((()((()()())(()()((((())((()((((()))))(())((()(()()(((()(()(((()((((()(((((()))())())(()((())()))(((()())((())((())((((()((()((((((())(()((((()()))((((((())()(()))((()(((())((((((((((()()(((((()(((((()((()()()((((())))(()))()((()(())()()((()((((((((((()((())(())(((((()(()(()()))((((()((((()()((()(((()(((((((((()(()((()((()))((((((()(((())()()((()(((((((()())))()()(()((()((()()(((()(()()()()((((()((())((((()(((((((((()(((()()(((()(()(((()(((()((())()(()((()(()(()(()))()(((()))(()((((()((())((((())((((((())(()))(()((((())((()(()((((((((()()((((((()(()(()()()(())((()((()()(((()(((((((()()((()(((((((()))(((((()(((()(()()()(()(((()((()()((())(()(((((((((()(()((()((((((()()((())()))(((((()((())()())()(((((((((((()))((((()()()()())(()()(()(()()))()))(()))(()(((()()))())(()(()))()()((())(()())()())()(()))()))(()()(()((((((())((()(((((((((((()(())()((()(()((()((()(()((()((((((((((()()())((())()(())))((())()())()(((((()(()())((((()((()(())(()))(((())()((()))(((((())(()))()()(()))(((())((((()((((()(())))(((((((()))))())()())(())((())()(()()((()(()))()(()()(()()((()())((())((()()))((((()))()()))(()()(())()()(((((()(())((()((((()))()))(()())())(((()()(()()))(())))))(()))((())(((((()((((()))()((((()))()((())(((())))(((()())))((()(()()(( diff --git a/01/main.py b/01/main.py new file mode 100755 index 0000000..cd3ec34 --- /dev/null +++ b/01/main.py @@ -0,0 +1,35 @@ +#!/usr/bin/python + + + +def solve_partn(partn, data): + floor = 0 + for i, d in enumerate(data): + if d == "(": + floor += 1 + elif d == ")": + floor -= 1 + + if partn == 2: + if floor < 0: + return i + 1 + + if partn == 1: + return floor + else: # partn == 2 + return -1 # only reached if he never goes underground + + + +def main(): + # Read instructions from input text file + with open("input.txt", "r") as f: + data = f.read() + + print("Part 1 solution:", solve_partn(1, data)) # 74 for me + print("Part 2 solution:", solve_partn(2, data)) # 1795 for me + + + +if __name__ == "__main__": + main() diff --git a/01/test.py b/01/test.py new file mode 100755 index 0000000..98cbd7d --- /dev/null +++ b/01/test.py @@ -0,0 +1,60 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + data = "(())" + self.assertEqual(main.solve_partn(1, data), 0) + + def test_example2(self): + data = "()()" + self.assertEqual(main.solve_partn(1, data), 0) + + def test_example3(self): + data = "(((" + self.assertEqual(main.solve_partn(1, data), 3) + + def test_example4(self): + data = "(()(()(" + self.assertEqual(main.solve_partn(1, data), 3) + + def test_example5(self): + data = "))(((((" + self.assertEqual(main.solve_partn(1, data), 3) + + def test_example6(self): + data = "())" + self.assertEqual(main.solve_partn(1, data), -1) + + def test_example7(self): + data = "))(" + self.assertEqual(main.solve_partn(1, data), -1) + + def test_example8(self): + data = ")))" + self.assertEqual(main.solve_partn(1, data), -3) + + def test_example9(self): + data = ")())())" + self.assertEqual(main.solve_partn(1, data), -3) + + + +class ExamplesPart2(unittest.TestCase): + def test_example1(self): + data = ")" + self.assertEqual(main.solve_partn(2, data), 1) + + def test_example2(self): + data = "()())" + self.assertEqual(main.solve_partn(2, data), 5) + + + +if __name__ == "__main__": + unittest.main() diff --git a/02/input.txt b/02/input.txt new file mode 100644 index 0000000..5f3335f --- /dev/null +++ b/02/input.txt @@ -0,0 +1,1000 @@ +29x13x26 +11x11x14 +27x2x5 +6x10x13 +15x19x10 +26x29x15 +8x23x6 +17x8x26 +20x28x3 +23x12x24 +11x17x3 +19x23x28 +25x2x25 +1x15x3 +25x14x4 +23x10x23 +29x19x7 +17x10x13 +26x30x4 +16x7x16 +7x5x27 +8x23x6 +2x20x2 +18x4x24 +30x2x26 +6x14x23 +10x23x9 +29x29x22 +1x21x14 +22x10x13 +10x12x10 +20x13x11 +12x2x14 +2x16x29 +27x18x26 +6x12x20 +18x17x8 +14x25x1 +30x15x22 +17x18x7 +28x23x24 +15x12x25 +14x7x20 +29x23x8 +24x5x22 +6x22x8 +1x15x26 +14x5x1 +24x28x28 +17x23x23 +4x15x7 +23x8x11 +6x15x1 +23x18x13 +17x1x26 +23x13x17 +2x18x8 +22x22x1 +10x22x6 +28x29x20 +22x21x25 +14x8x23 +12x30x14 +8x7x5 +3x30x15 +4x3x29 +25x18x3 +16x7x16 +4x3x8 +9x16x30 +20x28x3 +28x24x6 +4x18x2 +23x18x5 +22x4x30 +15x30x9 +7x12x12 +3x22x29 +12x1x9 +9x2x25 +17x11x10 +25x24x7 +7x27x26 +26x4x12 +29x2x26 +19x24x12 +23x23x3 +26x28x16 +18x4x16 +25x30x18 +29x19x19 +16x3x27 +29x25x29 +18x19x5 +14x21x30 +19x13x26 +19x10x15 +9x4x7 +18x6x6 +24x25x29 +9x12x27 +15x3x22 +30x17x21 +18x19x28 +9x11x12 +8x28x22 +11x3x4 +28x17x20 +24x18x15 +11x12x13 +6x19x24 +28x4x5 +28x22x23 +13x29x2 +9x16x15 +29x28x1 +10x18x30 +19x11x12 +26x28x25 +23x17x13 +25x1x21 +17x1x27 +17x27x28 +28x13x15 +14x13x25 +11x29x7 +22x29x5 +13x6x14 +23x18x13 +25x7x17 +18x9x20 +21x11x2 +28x11x13 +13x25x1 +19x29x25 +16x29x4 +10x21x10 +7x25x17 +5x9x3 +1x15x6 +8x27x29 +23x6x30 +22x22x29 +6x20x30 +26x25x29 +10x19x19 +20x30x9 +5x30x24 +17x10x27 +30x14x30 +8x17x4 +7x18x6 +3x5x4 +24x17x15 +14x20x17 +22x27x15 +18x14x15 +23x9x11 +21x16x29 +7x18x21 +9x3x29 +10x13x4 +2x30x4 +23x20x4 +8x22x21 +29x28x4 +13x16x25 +21x9x11 +7x26x26 +13x23x30 +19x7x10 +9x23x21 +21x9x17 +9x21x15 +20x29x22 +23x13x15 +19x25x2 +12x11x30 +20x21x6 +21x6x17 +24x26x9 +29x21x29 +29x26x16 +6x16x1 +2x12x6 +6x7x20 +7x2x22 +6x22x4 +13x11x27 +25x27x14 +11x8x6 +26x11x14 +30x3x29 +27x21x20 +15x16x26 +6x22x10 +11x9x25 +23x13x6 +13x9x3 +30x22x13 +29x23x14 +25x19x6 +7x29x11 +19x18x5 +29x25x13 +25x24x27 +1x9x12 +22x9x17 +14x12x28 +19x21x17 +13x25x17 +14x25x12 +4x14x30 +7x15x28 +3x6x25 +6x2x16 +15x19x11 +17x30x20 +20x23x7 +26x21x6 +26x29x24 +2x4x30 +4x22x18 +13x3x28 +27x6x21 +5x3x27 +12x7x11 +28x11x9 +12x9x2 +1x22x20 +15x13x28 +14x19x16 +28x20x3 +20x4x9 +26x7x26 +18x19x25 +7x1x13 +20x23x29 +27x26x8 +11x15x15 +10x21x23 +29x2x11 +21x28x20 +3x18x23 +26x17x17 +14x26x17 +20x7x17 +18x12x8 +4x8x8 +8x15x23 +24x29x5 +1x25x8 +1x28x17 +16x18x13 +29x24x22 +13x16x10 +14x7x16 +15x11x29 +12x15x19 +17x6x28 +4x3x9 +15x16x8 +29x27x11 +2x24x20 +4x21x3 +29x24x27 +18x22x22 +7x8x18 +20x7x8 +19x9x2 +20x17x2 +2x29x10 +19x25x1 +28x9x3 +29x27x20 +7x21x7 +10x4x22 +26x8x5 +26x14x1 +5x27x9 +2x18x3 +3x27x17 +30x17x23 +30x11x20 +4x6x7 +6x29x27 +30x16x20 +24x30x28 +19x20x26 +18x1x25 +26x12x12 +19x15x29 +16x21x24 +23x13x26 +25x16x10 +8x9x18 +24x14x1 +24x15x21 +19x9x14 +8x23x11 +22x2x16 +29x9x26 +3x16x25 +15x20x30 +3x11x12 +15x2x3 +13x7x4 +2x7x27 +9x26x11 +30x24x19 +28x17x21 +10x8x2 +11x15x26 +10x12x20 +24x24x27 +25x26x16 +13x4x20 +25x13x11 +12x22x3 +20x7x1 +12x18x6 +26x8x20 +14x2x7 +23x12x1 +26x24x24 +27x26x23 +26x17x5 +17x24x2 +26x5x6 +23x5x1 +5x18x30 +24x21x19 +5x28x11 +21x20x14 +25x4x22 +26x24x11 +7x5x8 +13x1x30 +5x1x6 +14x5x2 +8x11x7 +13x20x1 +17x30x14 +29x22x10 +12x26x3 +27x17x3 +26x27x4 +5x26x17 +22x11x19 +8x26x3 +24x19x22 +7x1x4 +6x27x30 +4x28x14 +16x14x18 +4x5x20 +19x25x4 +15x15x1 +10x14x14 +16x18x24 +21x27x15 +5x5x10 +1x7x13 +16x2x8 +13x15x11 +3x25x10 +20x29x8 +12x3x2 +10x13x12 +25x27x1 +11x30x19 +7x19x13 +27x6x18 +16x21x19 +21x29x5 +16x23x12 +29x19x15 +5x5x10 +27x15x1 +13x16x22 +29x19x5 +8x12x9 +3x18x5 +13x25x3 +5x9x21 +10x20x16 +9x9x11 +23x21x1 +22x2x15 +27x8x13 +23x7x3 +26x30x15 +29x15x16 +16x27x13 +2x18x9 +10x27x8 +20x9x25 +10x2x17 +16x13x13 +21x26x1 +27x26x24 +9x30x16 +19x17x28 +25x15x1 +10x26x6 +10x11x11 +5x26x25 +30x4x15 +9x8x23 +14x25x7 +8x28x8 +28x18x24 +4x4x25 +16x25x11 +17x27x8 +15x16x9 +24x13x21 +17x3x27 +27x5x26 +8x27x12 +29x2x8 +24x23x30 +1x30x21 +6x18x20 +13x14x12 +25x30x23 +24x6x24 +12x7x21 +11x6x8 +8x30x30 +26x3x12 +28x6x5 +18x7x1 +7x6x20 +14x16x18 +11x22x15 +4x20x10 +19x24x19 +8x24x11 +4x9x10 +6x6x22 +10x9x29 +1x5x28 +19x25x29 +20x30x3 +15x13x13 +9x9x24 +20x14x29 +26x24x13 +2x25x8 +10x26x2 +12x19x12 +18x6x20 +4x5x14 +26x27x10 +16x26x20 +3x21x15 +2x26x18 +14x11x17 +26x26x25 +10x1x11 +17x19x19 +27x28x26 +9x2x10 +19x30x15 +23x30x14 +15x3x20 +2x14x22 +21x18x8 +22x4x29 +19x6x29 +9x26x29 +16x10x9 +22x12x22 +13x28x14 +25x14x28 +28x3x30 +10x17x1 +10x27x22 +10x23x19 +14x25x9 +11x24x8 +30x25x10 +22x13x28 +2x7x6 +11x20x8 +9x22x14 +19x16x9 +11x24x4 +11x17x2 +6x4x10 +26x10x10 +12x14x5 +27x10x3 +15x3x6 +11x7x19 +22x10x12 +21x26x10 +13x20x3 +27x8x8 +1x24x23 +24x9x22 +23x17x23 +3x28x19 +2x20x28 +23x17x24 +26x1x4 +4x1x12 +5x6x16 +13x22x13 +25x21x21 +20x21x12 +9x24x25 +17x16x12 +12x28x9 +18x16x27 +29x12x2 +30x12x15 +24x11x10 +4x9x22 +4x24x5 +19x11x5 +6x25x6 +1x20x17 +22x8x21 +11x26x4 +16x19x3 +8x12x8 +13x2x18 +10x5x11 +8x12x17 +21x2x5 +26x17x26 +23x18x17 +28x11x14 +1x4x27 +29x5x28 +5x9x10 +5x7x25 +20x15x27 +15x11x17 +12x14x1 +29x14x4 +18x14x18 +14x25x24 +26x14x18 +13x8x11 +30x1x23 +3x4x12 +12x24x9 +8x6x16 +14x15x30 +12x30x8 +22x11x18 +16x30x28 +17x18x4 +13x14x23 +2x28x8 +3x28x30 +29x30x8 +4x6x26 +6x30x17 +11x30x30 +19x4x3 +12x15x20 +22x28x4 +26x30x2 +6x12x7 +1x10x5 +25x29x7 +17x9x18 +16x21x29 +21x14x7 +15x16x11 +26x6x15 +8x24x7 +2x20x4 +2x9x3 +19x8x13 +18x7x22 +27x14x17 +2x13x8 +18x15x26 +15x27x27 +18x11x15 +1x29x20 +21x12x11 +20x2x15 +28x23x9 +1x1x17 +7x23x9 +30x9x27 +9x16x18 +15x24x28 +30x11x18 +29x26x10 +9x5x25 +2x1x19 +14x3x14 +6x3x6 +30x15x20 +20x17x27 +28x10x9 +14x24x28 +17x11x6 +12x3x6 +8x8x15 +23x14x21 +11x21x7 +5x13x30 +4x29x25 +30x28x24 +18x4x9 +3x15x6 +13x9x19 +30x14x7 +7x9x9 +17x11x26 +24x26x13 +16x21x16 +27x17x25 +2x21x11 +9x11x27 +3x3x7 +13x8x14 +20x20x26 +13x29x22 +30x11x1 +7x10x19 +27x5x9 +23x17x15 +21x6x13 +24x15x16 +18x4x14 +18x16x6 +22x11x18 +14x2x5 +15x3x7 +10x20x29 +16x1x10 +30x23x1 +10x15x11 +17x14x5 +22x8x13 +7x11x28 +26x17x3 +2x23x2 +28x13x19 +18x12x28 +22x23x16 +14x12x1 +20x8x19 +17x19x13 +29x2x12 +2x26x27 +29x16x4 +13x8x18 +16x15x30 +23x16x2 +28x8x27 +21x8x23 +13x20x26 +19x6x17 +17x30x15 +7x4x30 +2x13x30 +18x7x19 +4x13x27 +8x6x5 +18x20x25 +2x3x30 +23x27x13 +22x30x4 +23x25x25 +23x16x19 +25x3x1 +5x6x15 +11x29x12 +25x24x7 +16x7x20 +20x3x2 +12x27x15 +16x10x12 +1x3x14 +22x1x26 +2x24x18 +11x29x16 +15x2x9 +10x1x24 +21x8x11 +30x11x23 +6x30x21 +13x27x29 +14x6x5 +18x29x19 +12x4x28 +29x3x14 +10x30x28 +5x7x15 +14x1x10 +9x25x14 +7x24x18 +28x17x21 +18x13x25 +26x15x1 +21x1x19 +12x16x21 +4x6x13 +7x15x26 +17x19x5 +12x28x2 +1x20x19 +27x7x5 +17x26x8 +12x15x19 +5x23x10 +8x2x8 +16x13x12 +14x27x1 +26x29x3 +24x16x14 +14x13x13 +7x22x23 +2x9x30 +4x27x8 +26x27x15 +23x1x6 +25x29x18 +5x18x1 +20x8x20 +5x10x25 +30x25x15 +7x22x25 +28x26x17 +29x4x1 +21x11x27 +20x9x8 +25x22x12 +2x11x11 +23x2x16 +23x27x20 +2x13x28 +27x2x24 +11x1x17 +12x4x27 +16x20x22 +30x12x10 +5x15x4 +5x2x27 +12x4x25 +1x16x4 +27x4x4 +21x16x3 +27x26x3 +24x6x6 +24x12x12 +20x20x25 +8x29x2 +21x4x5 +2x4x8 +4x13x19 +3x20x10 +12x15x16 +6x5x4 +12x16x20 +22x19x17 +8x17x22 +25x16x15 +7x1x19 +10x1x7 +23x23x5 +28x6x12 +2x25x12 +10x27x12 +24x27x19 +14x14x20 +4x1x5 +16x27x29 +20x20x24 +28x24x30 +6x15x15 +9x15x30 +23x26x3 +17x24x21 +22x25x25 +18x29x10 +20x25x1 +24x11x16 +20x7x21 +20x7x9 +7x26x2 +5x18x1 +16x26x28 +4x10x18 +27x30x21 +26x9x9 +8x16x14 +6x27x8 +28x9x20 +13x13x4 +9x18x16 +18x15x18 +22x19x14 +14x10x17 +25x29x11 +1x18x19 +8x11x26 +18x6x14 +30x24x13 +27x1x27 +15x9x3 +2x29x17 +2x26x21 +22x9x9 +20x20x20 +22x28x2 +26x5x16 +11x3x14 +21x16x16 +18x26x7 +18x30x6 +7x11x12 +15x10x2 +27x2x16 +27x30x24 +28x14x24 +7x4x8 +6x28x15 +13x19x1 +22x26x30 +7x30x24 +2x17x21 +19x26x2 +19x24x15 +14x23x2 +21x27x15 +30x15x14 +21x29x5 +23x30x2 +4x1x2 +15x5x13 +21x2x30 +20x7x16 +1x21x25 +2x25x1 +12x29x5 +28x13x16 +26x3x12 +29x20x23 +28x12x20 +4x30x8 +16x15x16 +6x16x29 +2x28x13 +24x25x2 +26x15x22 +17x20x11 +18x12x7 +19x1x18 +8x27x13 +22x16x8 +19x26x17 +13x11x10 +22x12x3 +13x12x14 +29x17x9 +6x14x10 +14x20x10 +8x26x9 +25x13x22 +3x30x25 +14x28x1 +30x29x12 +3x17x15 +3x24x14 +28x24x22 +16x6x1 +20x25x14 +17x17x13 +6x19x27 +10x15x20 +8x23x20 +7x29x21 +18x9x25 +10x5x22 +2x27x27 +16x18x30 +15x5x12 +26x29x29 +28x11x10 +9x29x28 +24x15x23 +26x9x10 +5x1x25 +22x27x16 +7x29x3 +1x3x5 +8x7x29 +19x21x11 +28x13x30 +17x16x20 +5x10x25 +9x14x15 +15x14x23 +16x4x17 +21x8x2 +9x9x8 +22x22x4 +10x2x27 +12x19x10 +15x29x4 +22x14x7 +29x18x5 +1x7x27 +24x1x15 +23x23x26 +12x17x23 +26x10x24 +8x22x2 +8x1x10 +22x19x12 +2x23x13 +11x27x25 +26x15x27 +27x7x21 +18x9x6 +22x21x22 +7x12x26 +23x21x13 +14x3x8 +5x9x28 +29x29x15 +27x25x23 +12x2x24 +8x2x20 +29x19x4 +12x24x29 +2x27x28 +14x20x9 +28x6x25 +18x29x8 +19x11x30 +15x11x23 +18x7x7 +14x20x14 +26x18x22 +27x25x13 +12x10x30 +30x2x7 +28x10x1 +18x10x30 +22x11x5 +22x16x3 +25x15x9 +5x10x24 +4x28x8 +19x24x18 +3x4x25 +14x4x30 +11x26x3 +12x12x12 +26x7x24 +3x2x14 +1x27x7 +2x2x13 +3x26x26 +12x4x11 +12x17x20 +4x19x30 +5x18x10 +17x6x18 +19x30x20 +11x2x17 +30x13x19 +22x23x7 +17x28x2 +5x17x30 +7x11x4 +21x26x18 +15x28x4 +5x6x27 +12x6x16 +9x17x12 +27x20x5 +14x5x20 +27x14x6 +2x14x21 +4x28x30 +24x5x1 +19x29x29 +11x23x1 +8x16x21 +3x17x19 +10x13x5 +20x21x16 +23x3x6 +27x26x11 +3x2x22 +14x3x5 +10x9x8 diff --git a/02/main.py b/02/main.py new file mode 100755 index 0000000..0a1697d --- /dev/null +++ b/02/main.py @@ -0,0 +1,42 @@ +#!/usr/bin/python + + + +def solve_part1(boxes): + result = 0 + for b in boxes: + faces = [b[0]* b[1], b[1] * b[2], b[2] * b[0]] + result += 2 * sum(faces) + min(faces) + return result + + + +def solve_part2(boxes): + result = 0 + for b in boxes: + perims = [2 * (b[0] + b[1]), 2 * (b[1] + b[2]), 2 * (b[2] + b[0])] + volume = b[0] * b[1] * b[2] + result += min(perims) + volume + return result + + + +def main(): + # Read box dimensions from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + # Parse the dimensions into tuples (x, y, z) + boxes = [] + for line in lines: + dims = line.split("x") + b = tuple([int(d) for d in dims]) + boxes.append(b) + + print("Part 1 solution:", solve_part1(boxes)) # 1586300 for me + print("Part 2 solution:", solve_part2(boxes)) # 3737498 for me + + + +if __name__ == "__main__": + main() diff --git a/02/test.py b/02/test.py new file mode 100755 index 0000000..965adef --- /dev/null +++ b/02/test.py @@ -0,0 +1,32 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + boxes = [(2, 3, 4)] + self.assertEqual(main.solve_part1(boxes), 58) + + def test_example2(self): + boxes = [(1, 1, 10)] + self.assertEqual(main.solve_part1(boxes), 43) + + + +class ExamplesPart2(unittest.TestCase): + def test_example1(self): + boxes = [(2, 3, 4)] + self.assertEqual(main.solve_part2(boxes), 34) + + def test_example2(self): + boxes = [(1, 1, 10)] + self.assertEqual(main.solve_part2(boxes), 14) + + + +if __name__ == "__main__": + unittest.main() diff --git a/03/input.txt b/03/input.txt new file mode 100644 index 0000000..1757219 --- /dev/null +++ b/03/input.txt @@ -0,0 +1 @@ +>^^v^<>v<<>v^^^^^><^<<^vv>>>^<<^>><>>><>v<><>^^<^^^<><>>vv>vv>v<<^>v<>^>vv>><>^v<<<v^>>>vv>v^^^<^^<>>v<^^v<>^<<>^>><^<>>><><>v<<<><><>v><<>^^^^v>>^>^^^v^^^^^v<><^v><<><^v^>v<<>^<>^^v^<>vv>^^<^<>^v<><^><><><<<<>^vv^>^vvvvv><><^v<<^<^^v^<>^>^^^v^>v<><^vv<<^<>v<>^^>^^>v^>^<<<v><^v>^>>v>>>>^v^^>v^>^vv^>vv^^v<<^<^^<>v>vv^v>><>>>v^>^>^^v<>^^vv>v^<v<<>^vvvv><<^<>>^v^>>^v<^<>>v^<>>v<>>v^^^><^>>vvvv>^v<^><<>>^<>^>vv>>^^>v^^^><^<<^^v>v<^<<>v>^^vvv^v^>v^<>^^<>v^v>v>vvv>^^v<>v>>^<>><>v>v^<^v<>>^>><>^vvv^>>vvv<>v>v>^>>v<<>^<>^<>>>^v<<<^<^v>vv^>><<>^v^^^v<>^^vv><>><>>^>v^v<>>^<<^v>^^^<>^v^><>v<vv^>vv<<>>><<^v^<>v>>^^<>^><<^>vv>>^<>>v><^>>^^<>>^<^v><>vv^^^v>vvv>^><<>^^>^<vvv<^<<>^>^vvvv>v>vv^<>>^vv<^^^vv><^vv<<^>^^>v^<>^v<<>v^>^>v<<^vvv<<^^>^<<<<>vv>>^<>^>>>v^^>>vv>^^v<<>>>^^v><<^^><><^<>>><^<><><^<>v>v^<><^^v^>^>^vv^>^^<vv<^vvv<>>^^<^>v^>^>^>>v<<<><^v<<><^v<^^vv>vvvvv<<>^v^v>vv>>>vvv^^<^<^<><>v><^v><^<<<>><<^>v<>^>^v>>^<>v^<^>><<>^^>^^^>^^>>><>^v^v><<<vv>v<>v^v><>>>v^<><^vvv>vv^<^<<^<^^v>^>>>v<^<^v^^<^<^>>>vv>^<<><>^>>v>^<<>><^<>v<>vv^^>^>vvv^v<<^<^^^vvv<^^v^vv^>>v<^>^^v<^<^vv>v<vv>^>vvv>>>^^>v<>^v>v^<^>>v>^^v>>>>v^v<^>v>^v<^^<^<>>^<>v<^v<>><^>vv>^^>>vv^<>>^vv<>vv<><<>>v>vv^><>>^^v^>>v^v^><<<>>^^<^v<<^<>>>>^<^>v^><<^>v<^v<^>>^^<<<<><^<^v^v<>>^v<^<<^^vv>^>>^>^vv^>^v<>>^v^^><>v>vv><^>>vvvvv^v^^<^<>v^^^^<><<>>>^v><^>^><^><<^vv<>>v^<v><>^>>v^<^^><>>><^>>>^^<^>vvvv<>^<<>^>>v<^v>^>v>>>vv>v>>v^^^<^^>^v>^>vv>vvv<>v<^>v>^^>>^v^^^^^v^vv><^<><>^>vv<^>>^vvvv^^^>^^v<<^><^^>^<>^^>^<>>^><<^^>v^v>>^>vvvv>^^v>>vv><<v>^^^v^vvv<^><<^>^<>^><<<<^<>v^>^>><>v^v<^vv^^>vv<vv^vvv<<<<>^vv<^^<>^vv^^>^>^v^vv^>>v^vv^^<v^v^^^^v<^<^>v>^>v>^vv^v^^^<^^^<^^<>^<>>>^<>>^^>v^^v^<<^v><^v>v<^><^>vv^^>v>^<><^^^>vv<<<<<^<>^v^v>^vv^<>v>v<^>vv<<^vv>vv<>>v>>><^<<><^^>^<^>>^>^^<^v>^vv><v<<>>^>v>>v>>v<^<<^<^>>>v>^^^v><^>^^>>v<<>^v>vvv^vv<<<>vvv<<>^>>>v^<^>v^^v<^^v<>>^^>^v^>v<<<<^<>v^><<>>><v>><>>^<<<^<^^>v<>>v<>vv<<^<<><<^>v^^^vv^>vvvv>>v>v^><vv^<<><^>>>^<<<^<^<^>v<>>v>>vv^^><<<<^^^v>><<^>>v<><><<>^><^><^v<>v^>>>v<^><^<>^v><^><^^^><^^v^<<><>>^>v^<^v^vv<><^>vv^>v^vvv^<>>^><^<^<>^<<>^v>^>>^v^vv>>^v<<>^><^>>>v<<^^v>>><><><v^^vv>vv^<^v<>^v>>v^v>v<^^vv><>^v<<>v^<>v^>>v>vvv<^><><^^>^vv^>>v^>^<^^<><>><<>^^^><^v^v><<<><<^v^vv>v>><^>>>v<>v^^>>v<<>v>v<>v^^<>>v<^vv<>^<<>v>vv^^<>>^^^<>^^>^v>v>>>^v^v>^^v^v<^<^^><^<>><<>^>>^>^^><>v<><>><<<>>>>vv>>>^>>^v<^>v^^^v<><<<^<<<>>>>>^>vv<^v^<>^^v>vvv<>>>^v^^^v<<<<>>^^^<>v<^<<<>><>>v<^<>^><><^^^>^^<^^v^>><<^vv>^v>>^v>^^>^v>^vvv<>v^v^^<>vv^>>><>v<^><<<>^v>^v<<<^>^>^>v^v<<>^>>>>>v^>vv<<^v^v<<><^v>>vv<>>>>^vv>v^<>vv>v^vvv<><<^<^^^vv^<>^^^^<^><^<>v^>^>>vvv<<>><^vvv^<<^^<<>>>^<>>>v^^><>><<>>>>>>><>>>v<>>v^<>vv<><^^^^v^<<^<<^^>v<^vvv^v>>v>^>>v>^^><v<>vv<^v^vv><>v^>>v<^^^>^><^><>v>>>vvv>^v^<^^^^^v><>v><>v^v^vvvvv<>vv<<^<^>^^v^<<>^<^><<>v^<<^<>v<<^v>>^v<>^>>^^><>v^<^^>^<<<<>vv>^v^v<^^^><>^^<>>v^v<<^^^^v^<><^^<^^^<^v>^>^vv><<<^vvv>v<>v^vv^>>>v^v<>^v<<>^vv>v>v>v^<^>v^^<^>^^^^vv>^^><^>vv^>>^^v>><<<<^><>v<>^^^><<^>v^>^^<^>>><>>>>>^>^><>v>v^v^^><<>vv^v>v^<^<>^^<^>v>^<><<^<^<^>^>^>^^v^<<^^v^^<^<>><^>v>>^^<>^^^<<<^v<^vv>^<<<vv>>>v><>>><>>v<<<>^v>v<^>><^><>^v^>^v>^v<<><<^<>>v>^><>^>><>><^<^^>^v^^<>v^^^^<^v><>^^<<<><<<<<^^>v^vvvv>v<>>vv<^>^v^>v<^vv^v<<><v^v>^^><><^v><>>><<>^vv<>v>>v<^v>>>vv>v>^vv<<>^^vvvv<>^<^<<>^>><^v>vv^^v<<^^><<>v^^<><>^>^>^>v<^^v^^>v<>vvv<^v<<<^^><^<v<>^>v><>^^<^^^>^v<<><<><>vv>v^<>v^><><v<>v>^<<<>vv>>vvv>^^vv^v^^<^^<>v^^<>v>>^^>^>^>v>><^>><>>^<<>><^>v<<<<<<<^v^v^<><v^>v^vv<<^^vv^>>>>^<>v<^v<>v>v^vv>vv>v>>>>vv^<<<v<<<<^^>^^v^><<^v^>^^vvv^>^<>vvvv^<><>v^^^>vv><><<<^^vvv<>><<^vv^>^<^>^^^<<vv^<^<<>^>^v><^>^^>>>vv^><^^vv><>^vv><<v^>v<^v^>>^^^^>vv>>vv^><^vv^vv<<^>vv>^v^^v^v>>>^vv<>v>^^^^<^>><>^v^^^>v<^^<<^^vvvv<^>><><^>>^><^<>v<><^>v><v<^vvv^^>v>^v^v^<>v>^>>vv>><^^^vv<><><<^vv<<>><^v>v^>vvv^v^<<^>^vv^>v^>v>^<<<<>v>^>^^>^<>^>^><<<^<<^<<^>^v>>>><<<>>>>>>^<^v<^>v<>vv<><>v>>^>>^>vv^^><<^>^^<<^>v<^>>vv>^<>v><^>v>>>>>^v<^<<>vv<<><<>v<^^^^v^^<^^^<^<<^>><>v<<>v>>><>v^vv>^>^>>vv^v<^v>vv^>v^v<^>vv<<^^v><^>>^^vv<^<>>v^^>>^v>>>^>>v>v<>v<^vv><>^<<^>vv>>><><>v^><>v^>v>v><^v<>^v<<^vv^><^^>><^^^<<<^>v>^v>>><^>><^>>>^^^<^>vv<><<^<^^>>^^^v^v^v>v>>><^>>>v>^vv<<^^^<^^vv>v<<>v>><<^>^<^>^v^>v><^<^vv>v>><>^<v^>^>><^^^v^v<><<>vvv<^^><>^>vvv>>>^><<>>>^vvv^v^>v<^<^>>^>v<^>^v<<><<<^>^<^^^>vv<^^^^vv<<>vv>>><^<^<>>>^>^>>^<<<<<^^v>^>^<>vvv^^<^><^>^^v>^vv^><^><^>>>v>^v>^>^v><^>v^>^<><<><>vvvv^>^>>v<>^><^>^>^^v^v>v<>^v^><^>>v>v^><<<^>>^<>^<>>v><>>v^>^>^^<>>v^>^>vv^^vv<>v<>^v>^^><^>vv^<^v^<<^<^<><>>>^v^<<^><^>vvv<^>vv^>v<<<>^<>v><^^<>^<^><>vvvv^v^^^>v<>>><<>vvv<<^^^>v>v>>v<^^v>^><^<><<>v^^^vv<>^>^^vv>^<<^v<^v>>>^>>><^<<>^v>>^>vv<<^v>v^^v^>><<^v<<<<>v>v>v^^<^><>^^<<vv<>>>^>>v<>^<>v>v^v>^>><<^^<^^v><<vvv^vv><>><<<^<<>^<^<>>vvv<>^<>v^v<><>>v^v><<>>>vvv>v<>^>>^><^>vv<<>>v<<^><>v>>^^^>^<<>><^<<>>>><^^>vv<>^<>vvvvv^vv<>>^<<><>^^vvv>>>vv<<^^><^v^^v<>^^>^><^>v^^^^v<^<vv^^>v^vv>v><>>vv>^<^>v^v^^v>^>vv^>v^v>^^v<<^>^^<<>^><^v>>>vv^>^^>vvvv>>v<^^>>>v^<><^<^^vv^^>v^<>^^^>>><^^v>v>^<<>^vvv^>^^^>>v>^v><<><<>v<^<<>^><>^>vv>^^^v<<^v^vvv^^>^vv^<^>^>^^v>v^>^<<><<^>v>>vv^vv>>^<<^<^^<^^>v^^^<^<>^<>>^v<^vvv^^v^<><^>>>>>v><><<<>vv<^v>><<>vvv<><v^^>>^>^v>><><^^v<>><>>v^>^<<<>><><^^<>>v<><^vv<^v>^<<<>^<><^>><<>^>v>^^^v>>^<^^v>^><<><>>^>>^<^v<>^>^>vv>^vvv<^>^<<^^<>^^^^vvv<>^vv^^<^>>><>v^<><^<<^>v^^v<>>^vv<>v^^<>>v^vvvvv<>>><^>vv>v^v^^^><^>^^^^v<><^v<<>v^>v>>vv<<>^vvv>^^vv^><>>^>>^>v><>>^^v>^>^>>>^>v<^v>v>^<^^^^^>>v>v<<^>^^^>><<^><>v<>^^^vv<>^^>><<^^>v>vv>vv>v^>^v>v^^<>>><>v><>vvv^^v>^^>^vvvv^>^<>^vvvv>>><>^<^vv<>^v<^v<>^vvv<<>>>^><^^^<^^v^>v<>v^v><>>>^vvv><^vv>v^<^<^v>>v^^>^vvv^v<^<>>^<>>>^^<><^^vv<>^vv^<>>>>^^<<^^<>vv^^><>^^^^v<><><>vvv>^v^>>vv<<^v<<>>^><^>>>^<^<^^>vv^<<^<>>^^><><^^>v<^v^vv>><^^<<^>>v>v<^^^<^><^^vv>^vv<^v><^<><^^^>>^<><^>>>v^>>>>v<><^^>v<^<^>>^>vv>^^v^v^<<<<^v^><<^<><<<><<<>v>>vv><<^<^<>^^^^<>v<<<vv<>vv^^^>><>vv^><>>^vv<<><^^vv<>v^>>^<<>^v< diff --git a/03/main.py b/03/main.py new file mode 100755 index 0000000..35c2308 --- /dev/null +++ b/03/main.py @@ -0,0 +1,48 @@ +#!/usr/bin/python + + + +def get_path(data): + visited = [] + loc = (0, 0) + visited.append(loc) + + for d in data: + if d == "^": + loc = (loc[0], loc[1] + 1) + elif d == "v": + loc = (loc[0], loc[1] - 1) + elif d == "<": + loc = (loc[0] - 1, loc[1]) + elif d == ">": + loc = (loc[0] + 1, loc[1]) + visited.append(loc) + + return visited + + + +def solve_part1(data): + return len([*set(get_path(data))]) + + + +def solve_part2(data): + data1 = data[0::2] + data2 = data[1::2] + return len([*set(get_path(data1) + get_path(data2))]) + + + +def main(): + # Read delivery instructions from input text file + with open("input.txt", "r") as f: + data = f.read() + + print("Part 1 solution:", solve_part1(data)) # 2592 for me + print("Part 2 solution:", solve_part2(data)) # 2360 for me + + + +if __name__ == "__main__": + main() diff --git a/03/test.py b/03/test.py new file mode 100755 index 0000000..693584b --- /dev/null +++ b/03/test.py @@ -0,0 +1,40 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + data = ">" + self.assertEqual(main.solve_part1(data), 2) + + def test_example2(self): + data = "^>v<" + self.assertEqual(main.solve_part1(data), 4) + + def test_example3(self): + data = "^v^v^v^v^v" + self.assertEqual(main.solve_part1(data), 2) + + + +class ExamplesPart2(unittest.TestCase): + def test_example1(self): + data = "^v" + self.assertEqual(main.solve_part2(data), 3) + + def test_example2(self): + data = "^>v<" + self.assertEqual(main.solve_part2(data), 3) + + def test_example3(self): + data = "^v^v^v^v^v" + self.assertEqual(main.solve_part2(data), 11) + + + +if __name__ == "__main__": + unittest.main() diff --git a/04/main.py b/04/main.py new file mode 100755 index 0000000..1014062 --- /dev/null +++ b/04/main.py @@ -0,0 +1,33 @@ +#!/usr/bin/python + +from hashlib import md5 + + + +def solve_partn(partn, key): + if partn == 1: + prefix = "00000" + else: # partn == 2 + prefix = "000000" + + n = 0 + h = "undefined" + while not h.startswith(prefix): + n += 1 + d = key + str(n) + h = md5(d.encode()).hexdigest() + return n + + + +def main(): + # My personal input string + key = "ckczppom" + + print("Part 1 solution:", solve_partn(1, key)) # 117946 for me + print("Part 2 solution:", solve_partn(2, key)) # 3938038 for me + + + +if __name__ == "__main__": + main() diff --git a/04/test.py b/04/test.py new file mode 100755 index 0000000..4078e83 --- /dev/null +++ b/04/test.py @@ -0,0 +1,21 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + key = "abcdef" + self.assertEqual(main.solve_partn(1, key), 609043) + + def test_example2(self): + key = "pqrstuv" + self.assertEqual(main.solve_partn(1, key), 1048970) + + + +if __name__ == "__main__": + unittest.main() diff --git a/05/input.txt b/05/input.txt new file mode 100644 index 0000000..5642100 --- /dev/null +++ b/05/input.txt @@ -0,0 +1,1000 @@ +rthkunfaakmwmush +qxlnvjguikqcyfzt +sleaoasjspnjctqt +lactpmehuhmzwfjl +bvggvrdgjcspkkyj +nwaceixfiasuzyoz +hsapdhrxlqoiumqw +lsitcmhlehasgejo +hksifrqlsiqkzyex +dfwuxtexmnvjyxqc +iawwfwylyrcbxwak +mamtkmvvaeeifnve +qiqtuihvsaeebjkd +skerkykytazvbupg +kgnxaylpgbdzedoo +plzkdktirhmumcuf +pexcckdvsrahvbop +jpocepxixeqjpigq +vnsvxizubavwrhtc +lqveclebkwnajppk +ikbzllevuwxscogb +xvfmkozbxzfuezjt +ukeazxczeejwoxli +tvtnlwcmhuezwney +hoamfvwwcarfuqro +wkvnmvqllphnsbnf +kiggbamoppmfhmlf +ughbudqakuskbiik +avccmveveqwhnjdx +llhqxueawluwmygt +mgkgxnkunzbvakiz +fwjbwmfxhkzmwtsq +kzmtudrtznhutukg +gtvnosbfetqiftmf +aoifrnnzufvhcwuy +cldmefgeuwlbxpof +xdqfinwotmffynqz +pajfvqhtlbhmyxai +jkacnevnrxpgxqal +esxqayxzvortsqgz +glfoarwvkzgybqlz +xdjcnevwhdfsnmma +jyjktscromovdchb +pvguwmhdvfxvapmz +iheglsjvxmkzgdbu +lwjioxdbyhqnwekv +zcoguugygkwizryj +ogvnripxxfeqpxdh +hkvajhsbfnzsygbm +cnjqeykecopwabpq +wojjtbcjinoiuhsj +kpwpvgxbyzczdzjq +wrvhylisemlewgzk +uiezkmnhilfzahtm +mucteynnuxpxzmvt +zaiwbgxefusfhmst +apptbogpxivjwink +qryboarjtwjhjgjb +irehxupgyseaahzd +fobstqxguyubggoh +ysriumfghtxtfxwe +auchdmasvfeliptw +mztuhefcrnknyrdl +tyjmkhihbwabjtaa +yquzkdtgsljkaebw +almvdvofjtkyzbmd +emqftiuqqpdwwbrv +hrrhmqfpepvbawvw +atrkgykycvgxbpyb +dhthetnealksbdan +zzqafhgicubptiyo +qdtaieaziwhbttnw +kyskgapdgqrtrefw +edwzlpqztpydmdlr +awszjnlmvlyqsuvl +kcrtmtshtsgixvcp +jtaskgkijivbbkri +mmggfwapsetemiuj +itagrrnjbnmhgppd +uqmbezechbrpbnqq +nnyimvtascflpzsa +knqeimypkdttyudj +vgoiyvtvegwyxjjd +qubzdxsbecktzrho +zehojtvktsbbxijb +xepmjrekwcgoxyoh +bnptxnocbpbqbyeq +sfvynsywscbnymos +dsltfbpcmffbluba +kncrlzlmkikylppa +siwudrvmildgaozv +jhhefbvbvneqzvtc +lqjgztxitbuccqbp +himmwlbhjqednltt +vwognchyertnnfil +eejakhapkbodrntf +qxuijkkhhlskgrba +aankpfxxicfpllog +vuxykvljyqexfhrn +epgygflbxlbwybzq +zuxmwvetmvcszayc +xttwhfqmemgtjnkf +hftwldmivyfunfvl +bejlyxfamzliilrj +zkehazcxyyvtrxti +dsgafehmcfpycvgz +igremmqdojqdvwmb +swnjzvmhcslvkmiw +fchzbfbmtqtxmaef +xwjmyyrlznxrcytq +brwcwzpcvbwdrthl +fvrlridacsiojdmb +mhsturxdlmtxozvy +usxvqyrwywdyvjvz +gwazuslvmarfpnzm +rgkbudaqsnolbcqo +dpxvlbtavdhdedkj +nnqmjzejhodyfgyd +ozoazxkfhujgtzvy +psdgvhzdiwnuaxpl +tznkilxpogbzgijz +wnpytcseirtborhh +lhauurlfsmagfges +oqfbzixnlywkzwwy +yoehapoyjpakziom +vtjftdcsfdzbmtrn +zcshfnodiwixcwqj +wapbxpaxgjvtntkm +qfyypkyvblrtaenh +bsxhbxkovgukhcza +kitdmvpiwzdonoyy +slkbhxmehzavbdsf +dovzjouqkzkcmbkl +qpbigdcqkfnfkxvq +eaiaquhnesvtcdsv +mhbezlhqojdsuryj +dqprkkzxlghkoccx +xqepmorryeivhrhm +frwmrjpezwmjflvf +gjpfgwghodfslwlf +fzyvajisdjbhfthq +pvzxkxdscdbilrdb +mtaxmqcnagmplvnm +rlyafujuuydrqwnc +gvqvrcxwyohufehq +lmrkircgfrfusmfd +ovlpnkxcpimyaspb +xhyjremmqhdqywju +pxfczlhpzbypfarm +utjhprzhtggausyp +utzkkzlnyskjtlqh +cecbcnxpazvkedic +xwvoaggihrbhmijq +krredhmtwlfmyagw +lwfhxgbknhwudkzw +vyczyvuxzmhxmdmn +swcoaosyieqekwxx +waohmlfdftjphpqw +gaclbbfqtiqasijg +ybcyaxhluxmiiagp +xgtxadsytgaznndw +wzqhtjqpaihyxksm +fdwltsowtcsmsyhm +rpoelfbsararhfja +tswgdacgnlhzwcvz +xjgbhdlxllgeigor +ksgthvrewhesuvke +whgooqirdjwsfhgi +toztqrxzavxmjewp +hbkayxxahipxnrtl +lazimkmdnhrtflcu +ndoudnupbotwqgmr +niwuwyhnudxmnnlk +hlmihzlrpnrtwekr +wzkttdudlgbvhqnc +rfyzzgytifkqlxjx +skddrtwxcyvhmjtb +mljspkvjxbuyhari +xwkhozaoancnwaud +nookruxkdffeymdz +oiqfvpxmcplyfgoa +qoxggshmrjlzarex +lsroezewzkrwdchx +nkoonmvdydgzspcl +lygxeqztdqklabov +jempjyzupwboieye +hpdaqkhjiddzybly +cvcizjlnzdjfjlbh +vaaddsbkcgdjhbkj +pjxmtxoyrkmpnenf +ujqdvyqnkbusxlps +miyvzkzqploqaceb +gapcsbkulicvlnmo +xqpcyriqhjhaeqlj +ipumdjwlldzqhmgh +swdstecnzttmehxe +ucmqordmzgioclle +aywgqhmqlrzcxmqx +ptkgyitqanvjocjn +wcesxtmzbzqedgfl +rnetcouciqdesloe +chpnkwfdjikqxwms +onpyrjowcuzdtzfg +tydnqwaqwkskcycz +dhamguhmkjzzeduy +oecllwyrlvsyeeuf +gsukajpoewxhqzft +sgdnffdixtxidkih +pqqzjxzydcvwwkmw +wnjltltufkgnrtgm +hylaicyfrqwolnaq +ovfnugjjwyfjunkm +xknyzsebmqodvhcl +uwfmrjzjvvzoaraw +zaldjvlcnqbessds +zphvjuctrsksouvz +ceqbneqjwyshgyge +wmelhaoylbyxcson +nghuescieaujhgkj +dhjmflwwnskrdpph +exvanqpoofjgiubf +aidkmnongrzjhsvn +mdbtkyjzpthewycc +izctbwnzorqwcqwz +hrvludvulaopcbrv +mrsjyjmjmbxyqbnz +sjdqrffsybmijezd +geozfiuqmentvlci +duzieldieeomrmcg +ehkbsecgugsulotm +cymnfvxkxeatztuq +bacrjsgrnbtmtmdl +kbarcowlijtzvhfb +uwietqeuupewbjav +ypenynjeuhpshdxw +fwwqvpgzquczqgso +wjegagwkzhmxqmdi +vocvrudgxdljwhcz +nnytqwspstuwiqep +axapfrlcanzgkpjs +lklrjiszochmmepj +gxadfpwiovjzsnpi +qidsjxzgwoqdrfie +wgszciclvsdxxoej +kwewlmzxruoojlaq +ywhahockhioribnz +ucbqdveieawzucef +mdyyzmfoaxmzddfv +hsxnabxyqfzceijv +vivruyvbrtaqeebr +jxfeweptjtgvmcjc +mmypqxmpurhculwd +mpiaphksvctnryli +xqzqnuxmuzylkkun +fndmtefjxxcygtji +dnorqlldvzqprird +nutokyajmjpwjaqu +vlupfperqyqkjcaj +dgihjeokrphkpdnk +nvbdyrlheqzixuku +mhrkntnxvsmvrpka +kvhkyanlhhymwljf +fhipumtegqfgeqqw +vpfjgveycdefuabu +kzincljffncylcsf +tsezxymwmjtyegqw +wxhcdrqedkdcwxli +ueihvxviirnooomi +kfelyctfvwyovlyh +horzapuapgtvzizz +iiqkdpmfvhwwzmtj +rsaclclupiicstff +quwkkhrafypkaoum +gyrgkgmwqfkeudfe +noydhbqacwptyfmy +efwwuipzgtkwffhf +suyojcitomdxsduh +lbcxnsykojkufkml +zpglsvoutvzkgdep +usgrufyvgsbsmbpr +katrrwuhwvunjqor +btngwrpcxoyfbgbc +bxjscjdiowjrkpns +nwxvnfrnlkgqxvhf +ikhyqkvljucgdlag +xibnxsjopmxvflkl +mzplumcfivqcjqnz +jqflcxoxzlbwlxry +fcscvmfepdxrshxe +wlpffwunffklzbuc +emvrlqajjgwzfmle +rhaheurtzrfoqkyq +ifuuhpxmadaysfsx +ncyfvleyzqntpcoo +zeogmyaqccmtvokd +jqppbzebppdnpurn +xixarswxsiwjzgni +ezruwzajsoombphs +hmiqfeizyprielxf +jnaoxljnftymsfey +extgzrxzovlsixnf +yhyfmovvlrwoezsv +ffnybaolppuzpjym +pqowimdiusccaagn +jgceiosiihpjsmnu +hkoexeaopebktngx +njhzuvsygymejqav +yjkgcclgtvushcfk +gmbjxhnkkxlihups +pdlwysadiebsidjz +omrwmgzulfoaqros +ofvvgdezwvcffdcy +otytpuklhxcpxhgd +eyfaosxdauumvlux +mvdthjfstrlqlyuo +mdgdchgnlxaxspdm +bakjezmhbwqxzevd +msakswaphdwaodhg +vjcqscgdbnsxdllh +jjywaovewbuzreoj +nqvplhwacylifvwk +lpwmpixbxysmsign +flcvbpxrchcpbgcb +qjpkeuenenwawlok +bnqkflfmdmntctya +fzsgzpoqixvpsneq +icwfdisutoilejld +relchofohnkwbumi +aljalgdaqwhzhfwr +cahkvnwnbwhodpqs +dnrzeunxiattlvdm +nsmkhlrpwlunppjs +mqqsexlwfqnogwub +tfavelkqrtndpait +ooguafrnmprfxcnz +ntynkiordzxtwrqa +rkkyzlxekqqlkvym +ofxcivdnwcmgfnme +ywotqwbrqxlrnobh +nrbbiypwhrqihvev +flqsjixxtydheufs +lcfrfzypstrqctja +hyzbuzawuzjrynny +exfbywcnstebnvmq +vydzwnbmcihvqrnj +qmwqaaylinzrdmiw +lpxpztpvfggspeun +lhxmqqbracsuyrfm +zgkwsrabaseidbrw +yjlmbhbqsqgszsun +mqfzqtbxtuteabtd +izomzdmcqmfrevwd +iqijrlqurdwrkoln +fxhqzpgoxxjkkhql +oulwontmgrjeopnk +edaigfydjexvzzvj +vjhybiklxpxjqpwc +ypxfbfnpbmqmwtte +xzvcsgasztrxdzud +rpulqmobptfarboo +palacmdijxzzykrf +jmllwukplufohiby +dnswayomusiekfmy +sxbrjqtqgzzwhcfo +lylvndsgbnbqiejm +jaxxhoulxnxnaenr +nblissutfazbcpwn +zmlsjszzldvbiacr +kewojtlchfkclqwk +eqvfjasddggvfame +yibzqlvxtraxpdon +dgnbxsbmdrtyvaac +uoxrcxfimhgtxqhy +xfdxalrwcwudlviq +xmtbdklqptoswpwl +zezyopzdztdjerfl +xuzluhjsqvhytgbc +qdjtmeckispmgzki +phakupesplzmmmvc +gpuoqfffumzszybn +bhywxqkrrlwuebbw +ibvwgoyvelzenkzl +ncohvvbmiekbaksa +fzuvqzvxvdbeirrp +lshtzniokucwojjd +punrduvlnrulkium +gnfpikidnfobrrme +vxkvweekmnvkzgyl +rhydssudkcjlqgxn +cjtqvlaahohcgumo +jwzmfyinsfwecgcb +blpeseqhlzfilpuf +jvtpjkyokzcvagon +qjomincbcobjczpe +ugsyzkzgdhxtmsfz +hleaqgwzqjwajcra +coumfghptpnxvvov +hqpnbupnzwpdvgqd +cpouyodqxgviasem +lljvxeyozckifhfd +huqtnvutdyfgwtwa +yenlveuynmlmmymu +ojdyufkomxiwjmbf +spjzgvcwvzgffjkk +vxykmjhyvmhyssbp +tazdeqggfcjfvwwn +uumwcngwcytvpufx +avovuzkrevloneop +owczrtbnrvjfemkt +hzpugcanaxyvaokj +iishlodnxvjtgzyn +qosdonclrnxirham +eonqlnwevahydddg +ryqmnuikftlxuoqy +whqepbcwabzbthha +vekisvnwhgpyemxr +lrwxzoamnvpnlhap +ywepvqthnorfswjv +evqwvsoazmwyypjy +bgwoojddubppmjxf +jypkfrthzgtyeddi +tynabbhfjzkrqsju +adxstbfqheuqbcuk +gqwqiocdyqoiblrx +ybuddlyuskdlegxv +luwynbsmpgyeqsbr +ltyqgqoyljibqndo +jaedpajzphfybajh +epglnrxofptsqvmy +zjdpxkngfkstxbxh +ekegphcwanoickfu +cqvhuucvejqirvfs +uqudnnqumsqcgefo +qnzunermlnpcfflo +ovyxaniqaawzfuxx +djekxcezjowdhopq +bwtwbmdehrhpjnlk +nilsnlacerweikfa +hyrigsrmsrzcyaus +gvmdmgddduylmxic +ewzovdblhmjgjwsk +ojjfsknlonzguzlq +yjgfruvpjvlvrvvq +cyoryodwyhzwprbv +crsjclrurcquqgut +sjhfhobwtojxcmem +ibxfjudilmdeksea +uqbhdbjoeupyhbcz +uqbxigzxuxgmjgnw +jashafmtzrhswirg +dexiolovaucyooka +czjbwwnlwcoqnoiu +ojigosazigfhttjc +zfiqtgrqbmftknzn +dlzbmvmolssbqlzl +sgmchcurrutdtsmw +scdwjqsdohcdrwry +cgtdvecqwplpprxn +iiplenflfczaktwi +wmgnwfxfcjhyeiqg +giihshowtcatecvl +nqhzfincclumvkaz +kxstpzgdfvepionc +agbhxcijxjxerxyi +hmgfqevgdyvisyvs +tthakmvpowpvhtao +ottalcghygpaafbo +aplvozayycremgqg +dbjxlnaouxqtdpfz +peeyallzjsdvpalc +ndtdjyboixuyhfox +llabnbcobexfoldn +cweuvfnfyumbjvxr +ewkhhepaosalnvkk +pivyiwsiqpwhagyx +auzsnwdcerfttawt +grbfrekupciuzkrt +byfwzadtzrbndluf +lluypxjeljzquptk +pskwsnhqanemtfou +sxvrtqqjdjkfhhrm +ulsmqgmshvijyeqh +qigofesfhekoftkf +zhatniakqtqcxyqa +uuczvylgnxkenqee +mlitvtuxknihmisc +srrtrxdvcokpyfmz +osispuucklxcfkeb +vqhazlaulmnpipql +umkiueljberqhdig +knvpbkbvgoqzwprp +nbsocqikhuvsbloj +wjnpepjkzkednqbm +agbhmytsofuyqcor +gvogzhkkpxyfecko +ardafguxifeipxcn +yiajcskbgykyzzkw +sejunbydztyibnpq +dqrgfggwcnxeiygy +xnqqwilzfbhcweel +jjtifhlvmyfxajqi +gwszrpgpmbpiwhek +kydzftzgcidiohfd +efprvslgkhboujic +kecjdfwqimkzuynx +rildnxnexlvrvxts +dlnhjbqjrzpfgjlk +qluoxmzyhkbyvhub +crydevvrjfmsypbi +dosaftwumofnjvix +pwsqxrfwigeffvef +nzyfmnpwqyygjvfx +iccbckrkxlwjsjat +bmputypderxzrwab +bhuakynbwnlreixb +qmrzfyqjiwaawvvk +juvtixbkwyludftn +zapmjxmuvhuqlfol +paiwrqjhpjavuivm +tsepfbiqhhkbyriz +jpprewufiogxoygk +mmapyxbsugcsngef +pduhmgnepnpsshnh +aetndoqjvqyjrwut +fnfvlorhwpkkemhz +gedfidpwvoeazztl +beclvhospgtowaue +wsclsvthxustmczm +tjbxhnpniuikijhe +rhetyhvfcemponeg +mavonujurprbeexi +argbrpomztrdyasa +bzvtffbtygjxmkvh +maqyqkhsqgzfzvve +seeirbiynilkhfcr +wxmanwnozfrlxhwr +dieulypsobhuvswb +nxevassztkpnvxtb +jclxuynjsrezvlcy +xlolzyvgmwjsbmyf +tguzoeybelluxwxc +fkchoysvdoaasykz +cyynwbfcqpqapldf +rhifmzpddjykktuy +ndvufsyusbxcsotm +txutnzvdsorrixgg +qjoczhukbliojneu +ufhwujotncovjjsz +kclsgsdwcrxsycbr +yscwmlrdaueniiic +nxhivrovpkgsmugb +fdxqfyvwwvgeuqkv +femtamfylysohmpr +amsyzslvyxsoribh +nhmqxncwsonhgbcz +uomqsvcbpthlmcue +kxtfapcqrnjkkslj +xtieihonlfubeync +adpcjqxgydulchgj +cjynnzsmmujsxxpd +neeapmzweidordog +szoivgqyqwnyjsnk +uwgrtzaqezgphdcu +ptpgttqxocjwxohi +fhltebsizfwzpgpf +emmsazsidspkhgnh +dxcprkbcjeqxqzgn +tpxzqwxbzwigdtlt +afsmksnmzustfqyt +xyehnftstacyfpit +vcrfqumhjcmnurlw +rrznpjzcjgnugoch +gbxnzkwsjmepvgzk +jwobshgwerborffm +zmuvfkhohoznmifs +buyuwgynbtujtura +bevncenmpxfyzwtf +hqqtcrhzfsrcutjh +kbpzshllpiowepgc +alspewedcukgtvso +xvsvzzdcgjuvutrw +pmwulqraatlbuski +abuzsiinbueowpqn +oedruzahyfuchijk +avhcuhqqjuqkesoq +azqgplkzsawkvnhb +rjyoydogkzohhcvx +aezxwucqvqxuqotb +kxobnsjvzvenyhbu +nnjoiilshoavzwly +aijttlxjrqwaewgk +cvsaujkqfoixarsw +zngtoacpxcsplgal +qhkxliqtokvepcdv +aixihrtdmxkfvcqw +owbgdgdymxhhnoum +tajsagmruwzuakkd +ckrfduwmsodeuebj +alfdhuijuwyufnne +xpchlkijwuftgmnm +rwcrvgphistiihlg +xdaksnorrnkihreq +akeschycpnyyuiug +rgputhzsvngfuovz +lerknhznuxzdhvre +mqiqmyladulbkzve +csnmupielbbpyops +kwgrwgmhfzjbwxxz +npwtvbslvlxvtjsd +zxleuskblzjfmxgf +hexvporkmherrtrn +rhtdhcagicfndmbm +qhnzyuswqwoobuzz +dpvanjuofrbueoza +kjcqujmnhkjdmrrf +gholddsspmxtpybg +jihlvyqdyzkshfsi +zuviqmuqqfmtneur +kzexjowatvkohrtx +wgijnfhibsiruvnl +zevkrkmhsxmicijb +khxrcteqourjvoxa +ylpxlkcnenbxxtta +zrfsvctbojjkpvtw +nlzbudxibnmcrxbt +cqnscphbicqmyrex +ywvdohheukipshcw +riwatbvjqstubssf +idlztqqaxzjiyllu +sdpdgzemlqtizgxn +rjtbovqlgcgojyjx +fnfrfwujmjwdrbdr +osnppzzmrpxmdhtj +ljhwngclvydkwyoe +chwqkrkzrvjwarat +jmydkwpibkvmqlgs +zvhfmbxnlxtujpcz +jsnhsphowlqupqwj +fzhkkbpasthopdev +jerntjdsspdstyhf +gctwmaywbyrzwdxz +xemeaiuzlctijykr +xulrqevtbhplmgxc +yfejfizzsycecqpu +gboxrvvxyzcowtzm +lpvhcxtchwvpgaxp +wdiwucbdyxwnjdqf +qgwoqazzjlvnjrwj +prtlnkakjfqcjngn +fagvxsvjpuvqxniz +xacmxveueaakfbsm +ginvtonnfbnugkpz +qpvggsppewfzvwin +reoqnlzruyyfraxa +kolwtqhifjbbuzor +vrkcywvdhdprztww +ngdvyfmvjqhbzbxt +rooxeoilqzqjunmp +efxmdprtogtxgyqs +qrhjuqndgurcmwgu +ouitjprueefafzpl +kirdwcksqrbwbchp +fpumsmogojuywezo +lgjrgykywugzjees +xigioqcpjabpbdas +ewkhuprpqzikmeop +fgrgxsqeducigxvr +bclkursnqkzmjihl +jozidniwvnqhvsbc +oghcilcyozrmmpta +xbgmaungzcpasapi +iqowypfiayzbcvhv +opdehgwdgkocrgkf +zfzvdjeinlegcjba +vhakxvlcayuzukap +xyradgyiebpevnwe +eamhtflgedwyshkn +igteqdgchjeulfth +kwsfkigxzpbgdxod +vapnpsbdboiewpzp +wbuqhjsngxpqshen +vxxilouxuytitwgm +cpnwlkwnkeanqnet +wdmbtqvvlowftvgb +wjtmcecpyqzwpbqg +jnxmoxdhvsphcdeg +wabxfxpotoywwodn +mwbsoxzlqpqobvvh +coktshbyzjkxnwlt +rzhnggpslwzvyqrp +dgzuqbzarbutlkfx +wunajaiiwgijfvjh +uotdbcgmsvbsfqlb +kxdtlgmqbccjqldb +ngmjzjwvwbegehfr +cvpsabqfpyygwncs +wqluvqlhdhskgmzj +rbveperybfntcfxs +fbmoypqdyyvqyknz +zxpgzwnvmuvkbgov +yexcyzhyrpluxfbj +ltqaihhstpzgyiou +munhsdsfkjebdicd +plecvjctydfbanep +kjrxnnlqrpcieuwx +zbcdtcqakhobuscf +kgovoohchranhmsh +llxufffkyvuxcmfx +tgaswqyzqopfvxtw +kojcqjkdpzvbtjtv +xggdlkmkrsygzcfk +vvitpsnjtdqwyzhh +gcqjuwytlhxsecci +vbsghygcsokphnrg +vejqximdopiztjjm +hudqtwmwkviiuslp +vwswfvpcwwpxlyry +gxmfiehdxptweweq +qjmekjdcedfasopf +pqyxdxtryfnihphf +felnavctjjojdlgp +hbimufguekgdxdac +dhxhtnqgfczywxlr +pssottpdjxkejjrh +edieanguabapxyig +sciinanyqblrbzbb +irxpsorkpcpahiqi +qsxecaykkmtfisei +ivfwlvxlbnrzixff +hqxzzfulfxpmivcw +vvbpaepmhmvqykdg +cetgicjasozykgje +wuetifzdarhwmhji +gaozwhpoickokgby +eldnodziomvdfbuv +favpaqktqaqgixtv +twbcobsayaecyxvu +lzyzjihydpfjgqev +wnurwckqgufskuoh +fxogtycnnmcbgvqz +aetositiahrhzidz +dyklsmlyvgcmtswr +ykaxtdkjqevtttbx +kfmnceyxyhiczzjm +nnizopcndipffpko +yjmznhzyfinpmvkb +sljegcvvbnjhhwdd +zmkeadxlwhfahpwg +rwvcogvegcohcrmx +aguqwrfymwbpscau +vlusytjagzvsnbwe +smvzhburcgvqtklh +rfuprvjkhazrcxpv +megqlnoqmymcrclc +gvldhkewtmlwqvqv +awynhvtyziemnjoa +voprnvtnzspfvpeh +dhlguqwmunbbekih +goayirdhnjrfuiqi +eoghydfykxdslohz +chpippjykogxpbxq +hqbycjweqczwjwgf +pvefsrvwumrlvhmt +eghwdovaynmctktk +crwkxoucibumzawc +bzbtahvhkdigvvtj +bnbptgihhfubxhho +ddqmbwyfmfnjjaro +gvtswqyzazihctif +vmqctjpgadxztqqb +dgnndowtpeooaqqf +sxdvctfdtalufxty +ylgeexosibsmmckw +sxplpyskbpqnojvw +coarhxtsvrontyeg +fyoaurggjupvzvlv +jlyrkqsiwuggvjem +uwbsjoxonreuucyi +gihuqvwxovbgokes +dxzaaxupbcgnxcwf +gidrgmvyrlqqslve +csflmlvqmonoywpx +jkxkpixlythlacnk +ejkarcdkdslldugv +dbzmsusevohhjkmr +cbrqzualjpdtworc +kpgidqlmcbpfmmwu +zwghjuofexfowqam +ncdlxmcrsmsocetz +kfprzqacefifjkbd +swwzivrxulkhvldc +wgqejhigbjwunscp +rsstnwcyybfauqxu +qhngfxyhdqopyfgk +zrndpyyejsmqsiaj +xxknxwpvafxiwwjc +mmaahwgoiwbxloem +tabacndyodmpuovp +yriwomauudscvdce +duvyscvfidmtcugl +mgipxnqlfpjdilge +imeeqcdetjuhfjnw +dvkutrdofpulqkyh +jefvtlktxegpmbya +iyzudqgpvlzjfydh +giohapxnpaqayryd +qheqdprmnqlpztls +rdxhijmzegxkotoq +hdnmaspumdwnrcdz +wafpbgehbuzdgsnc +tbtrfztsferdmhsy +vusndcyjngtkrtmk +ilqblestzxebcifh +urfgjbjgzlrfsdlv +aptcdvpsqwleqttn +bigczjvzokvfofiw +zjnjeufonyqgkbpx +trcdebioegfqrrdi +jrdvdriujlmbqewt +jqrcmuxpwurdhaue +yjlermsgruublkly +zwarvgszuqeesuwq +xthhhqzwvqiyctvs +mzwwaxnbdxhajyyv +nclsozlqrjvqifyi +gcnyqmhezcqvksqw +deuakiskeuwdfxwp +tclkbhqqcydlgrrl +qbpndlfjayowkcrx +apjhkutpoiegnxfx +oaupiimsplsvcsie +sdmxrufyhztxzgmt +ukfoinnlbqrgzdeh +azosvwtcipqzckns +mydyeqsimocdikzn +itfmfjrclmglcrkc +swknpgysfscdrnop +shyyuvvldmqheuiv +tljrjohwhhekyhle +dayinwzuvzimvzjw +qgylixuuervyylur +klqqaiemurawmaaz +hdmzgtxxjabplxvf +xiivzelzdjjtkhnj +ktgplkzblgxwrnvo +gvbpyofzodnknytd +lqhlmnmhakqeffqw +ltzdbngrcxwuxecy +obxnfjeebvovjcjz +zexpwallpocrxpvp +tjpkkmcqbbkxaiak +qiedfixxgvciblih +qcxkhghosuslbyih +gnsfidwhzaxjufgm +xrghwgvyjakkzidw +tftftwedtecglavz +wquqczzkzqrlfngr +twibtkijpvzbsfro +bmplypdsvzuhrjxp +zanrfmestvqpwbuh +zonrhfqowyimcukm +kpvajjfmqpbhrjma +kujzluicngigjbtp +iusguantsrwxdjal +kwxeuylcnszswahw +visdhnkobxnemldu +rogeadmmaicwtabl +pxqycifbgevqudvs +osaiozyvlyddylqr +vffjxrolrpuxcatx +jbmsetccdrywssjd +qgxyhjfpbfifmvgc +npejgalglldxjdhs +mbbtqgmttastrlck +whapaqwdtpkropek +dulbdboxazfyjgkg +xaymnudlozbykgow +lebvqmxeaymkkfoy +bmicnfuubkregouj +dieatyxxxlvhneoj +yglaapcsnsbuvrva +bbpjaslqpzqcwkpk +xehuznbayagrbhnd +ikqmeovaurmqfuvr +ylyokwuzxltvxmgv +hqtfinrkllhqtoiz +pjmhtigznoaejifx +fqdbmowkjtmvvrmx +uvqtqfoulvzozfxv +rpajajukuxtchrjd +sznucejifktvxdre +ufvibsmoushmjbne +xirdqoshngthfvax +iafpkddchsgdqmzl +vmualmlduipvykzh +fnmuahmblwyceejb +ilsaapnswfoymiov +lenvylifraahaclv +cukqxlipuyxedqfh +zgwecslpniqvtvuz +cdcdfpsxuyrhsmag +dszjinhantnxgqra +ioimwotsgnjeacgt +dqcymnvjystbynhp +yibaudyfefbfgunx +cabslcvunjavqkbf +goymzvmgkvlsmugf +zxteiitpthzskjjx +agnxcnaqhjhlurzs +cvmgyxhhnykuxbmb +cgqmjexydmvgwxpp +sygjajofieojiuna +clpvxbrbjvqfbzvu +cbntswqynsdqnhyv +bztpbtwbefiotkfa +pnxccbgajvhyeybu +asyzrvgzumtuissa +facjyblvcqqginxa +rvwnucnbsvberxuv +ghrbeykzrxclasie +ekujtselepgjtaql +krtrzsmduhsifyiw +ticjswvsnyrwhpnt +clmjhsftkfjzwyke +lbxlcixxcztddlam +xhfeekmxgbloguri +azxqwlucwhahtvep +kitdjrwmockhksow +keznwwcusgbtvfrs +ljvzxoywcofgwajj +vebjnhnkcfzbhrcw +eqfcxkavstxcuels +ldattkyawjrvcido +bsqqeilshcwtqyil +foqqsxahfiozcqrw +liswfmuhzfbyzjhf +sulbdcyzmolapfbs +zuggzkelwxjpsgxb +betioxrgtnhpivcw +xmtbixstdipibhgs +ttvurgqmulryyaji +viobnljznzppfmxw +qlzabfopydtxrlet +tusvydegfxhaxolk +thoufvvfjferxhwp +cfyyzppfarjiilbs +jwmhxtgafkkgseqs +pqwuuaxbeklodwpt +vndyveahdiwgkjyx +ssrjgasfhdouwyoh +thbavfcisgvvyekf +yjdvxmubvqadgypa +tlbmcxaelkouhsvu +bonohfnlboxiezzr +rktlxcbkhewyvcjl +rsmoutcbcssodvsc +qszdratuxcrhsvoh +eypyfahpuzqwzwhi +yhkrleqmqlmwdnio +vpnvxusvmngsobmq +hkzyhopvxrsimzys +dblriiwnrvnhxykl +xkriqxkrprjwpncs +rcymltrbszhyhqti +mzbvneplsnpiztzn +vkqtnptgbqefvfoc +nwdtfiaozkcjtlax +crximadpvdaccrsm +lrbajafxwwnxvbei +rbexzesrytpwwmjf +stxwjarildpnzfpg +btamaihdivrhhrrv +acqbucebpaulpotl +dkjhzghxxtxgdpvm +rsbzwsnvlpqzyjir +mizypbwvpgqoiams +nvrslorjpqaasudn +wvexcpzmconqkbvk +rfwfumhjwzrvdzam +eaghdaqorkhdsmth +gtuntmpqaivosewh +nzlsmdgjrigghrmy +dhuvxwobpzbuwjgk +kkcuvbezftvkhebf +aeediumxyljbuyqu +rfkpqeekjezejtjc +wkzasuyckmgwddwy +eixpkpdhsjmynxhi +elrlnndorggmmhmx +ayxwhkxahljoxggy +mtzvvwmwexkberaw +evpktriyydxvdhpx +otznecuqsfagruls +vrdykpyebzyblnut +cnriedolerlhbqjy +uajaprnrrkvggqgx +xdlxuguloojvskjq +mfifrjamczjncuym +otmgvsykuuxrluky +oiuroieurpyejuvm diff --git a/05/main.py b/05/main.py new file mode 100755 index 0000000..876d20c --- /dev/null +++ b/05/main.py @@ -0,0 +1,73 @@ +#!/usr/bin/python + + + +def solve_part1(lines): + result = 0 + + for line in lines: + # Rule 1: at least three vowels + nvowels = 0 + for v in "aeiou": + nvowels += line.count(v) + rule1 = nvowels >= 3 + + # Rule 2: at least one double letter + rule2 = False + for i in range(len(line) - 1): + if line[i] == line[i + 1]: + rule2 = True + break + + # Rule 3: no "ab", "cd", "pq" or "xy" + rule3 = True + for s in ["ab", "cd", "pq", "xy"]: + if line.count(s) > 0: + rule3 = False + break + + if rule1 and rule2 and rule3: + result += 1 + + return result + + + +def solve_part2(lines): + result = 0 + + for line in lines: + # Rule 1: twice-occurring two-letter sequence + rule1 = False + for i in range(len(line) - 1): + s = line[i : i + 2] + if line.count(s) >= 2: + rule1 = True + break + + # Rule 2: ABA-like sequence + rule2 = False + for i, c in enumerate(line): + if i < len(line) - 2 and line[i + 2] == c: + rule2 = True + break + + if rule1 and rule2: + result += 1 + + return result + + + +def main(): + # Read list of strings from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_part1(lines)) # 258 for me + print("Part 2 solution:", solve_part2(lines)) # 53 for me + + + +if __name__ == "__main__": + main() diff --git a/05/test.py b/05/test.py new file mode 100755 index 0000000..66fc927 --- /dev/null +++ b/05/test.py @@ -0,0 +1,32 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + lines = ["ugknbfddgicrmopn", "aaa"] + self.assertEqual(main.solve_part1(lines), 2) + + def test_example2(self): + lines = ["jchzalrnumimnmhp", "haegwjzuvuyypxyu", "dvszwmarrgswjxmb"] + self.assertEqual(main.solve_part1(lines), 0) + + + +class ExamplesPart2(unittest.TestCase): + def test_example1(self): + lines = ["qjhvhtzxzqqjkmpb", "xxyxx"] + self.assertEqual(main.solve_part2(lines), 2) + + def test_example2(self): + lines = ["uurcxstgmygtbstg", "ieodomkazucvgmuy"] + self.assertEqual(main.solve_part2(lines), 0) + + + +if __name__ == "__main__": + unittest.main() diff --git a/06/input.txt b/06/input.txt new file mode 100644 index 0000000..495311e --- /dev/null +++ b/06/input.txt @@ -0,0 +1,300 @@ +turn off 660,55 through 986,197 +turn off 341,304 through 638,850 +turn off 199,133 through 461,193 +toggle 322,558 through 977,958 +toggle 537,781 through 687,941 +turn on 226,196 through 599,390 +turn on 240,129 through 703,297 +turn on 317,329 through 451,798 +turn on 957,736 through 977,890 +turn on 263,530 through 559,664 +turn on 158,270 through 243,802 +toggle 223,39 through 454,511 +toggle 544,218 through 979,872 +turn on 313,306 through 363,621 +toggle 173,401 through 496,407 +toggle 333,60 through 748,159 +turn off 87,577 through 484,608 +turn on 809,648 through 826,999 +toggle 352,432 through 628,550 +turn off 197,408 through 579,569 +turn off 1,629 through 802,633 +turn off 61,44 through 567,111 +toggle 880,25 through 903,973 +turn on 347,123 through 864,746 +toggle 728,877 through 996,975 +turn on 121,895 through 349,906 +turn on 888,547 through 931,628 +toggle 398,782 through 834,882 +turn on 966,850 through 989,953 +turn off 891,543 through 914,991 +toggle 908,77 through 916,117 +turn on 576,900 through 943,934 +turn off 580,170 through 963,206 +turn on 184,638 through 192,944 +toggle 940,147 through 978,730 +turn off 854,56 through 965,591 +toggle 717,172 through 947,995 +toggle 426,987 through 705,998 +turn on 987,157 through 992,278 +toggle 995,774 through 997,784 +turn off 796,96 through 845,182 +turn off 451,87 through 711,655 +turn off 380,93 through 968,676 +turn on 263,468 through 343,534 +turn on 917,936 through 928,959 +toggle 478,7 through 573,148 +turn off 428,339 through 603,624 +turn off 400,880 through 914,953 +toggle 679,428 through 752,779 +turn off 697,981 through 709,986 +toggle 482,566 through 505,725 +turn off 956,368 through 993,516 +toggle 735,823 through 783,883 +turn off 48,487 through 892,496 +turn off 116,680 through 564,819 +turn on 633,865 through 729,930 +turn off 314,618 through 571,922 +toggle 138,166 through 936,266 +turn on 444,732 through 664,960 +turn off 109,337 through 972,497 +turn off 51,432 through 77,996 +turn off 259,297 through 366,744 +toggle 801,130 through 917,544 +toggle 767,982 through 847,996 +turn on 216,507 through 863,885 +turn off 61,441 through 465,731 +turn on 849,970 through 944,987 +toggle 845,76 through 852,951 +toggle 732,615 through 851,936 +toggle 251,128 through 454,778 +turn on 324,429 through 352,539 +toggle 52,450 through 932,863 +turn off 449,379 through 789,490 +turn on 317,319 through 936,449 +toggle 887,670 through 957,838 +toggle 671,613 through 856,664 +turn off 186,648 through 985,991 +turn off 471,689 through 731,717 +toggle 91,331 through 750,758 +toggle 201,73 through 956,524 +toggle 82,614 through 520,686 +toggle 84,287 through 467,734 +turn off 132,367 through 208,838 +toggle 558,684 through 663,920 +turn on 237,952 through 265,997 +turn on 694,713 through 714,754 +turn on 632,523 through 862,827 +turn on 918,780 through 948,916 +turn on 349,586 through 663,976 +toggle 231,29 through 257,589 +toggle 886,428 through 902,993 +turn on 106,353 through 236,374 +turn on 734,577 through 759,684 +turn off 347,843 through 696,912 +turn on 286,699 through 964,883 +turn on 605,875 through 960,987 +turn off 328,286 through 869,461 +turn off 472,569 through 980,848 +toggle 673,573 through 702,884 +turn off 398,284 through 738,332 +turn on 158,50 through 284,411 +turn off 390,284 through 585,663 +turn on 156,579 through 646,581 +turn on 875,493 through 989,980 +toggle 486,391 through 924,539 +turn on 236,722 through 272,964 +toggle 228,282 through 470,581 +toggle 584,389 through 750,761 +turn off 899,516 through 900,925 +turn on 105,229 through 822,846 +turn off 253,77 through 371,877 +turn on 826,987 through 906,992 +turn off 13,152 through 615,931 +turn on 835,320 through 942,399 +turn on 463,504 through 536,720 +toggle 746,942 through 786,998 +turn off 867,333 through 965,403 +turn on 591,477 through 743,692 +turn off 403,437 through 508,908 +turn on 26,723 through 368,814 +turn on 409,485 through 799,809 +turn on 115,630 through 704,705 +turn off 228,183 through 317,220 +toggle 300,649 through 382,842 +turn off 495,365 through 745,562 +turn on 698,346 through 744,873 +turn on 822,932 through 951,934 +toggle 805,30 through 925,421 +toggle 441,152 through 653,274 +toggle 160,81 through 257,587 +turn off 350,781 through 532,917 +toggle 40,583 through 348,636 +turn on 280,306 through 483,395 +toggle 392,936 through 880,955 +toggle 496,591 through 851,934 +turn off 780,887 through 946,994 +turn off 205,735 through 281,863 +toggle 100,876 through 937,915 +turn on 392,393 through 702,878 +turn on 956,374 through 976,636 +toggle 478,262 through 894,775 +turn off 279,65 through 451,677 +turn on 397,541 through 809,847 +turn on 444,291 through 451,586 +toggle 721,408 through 861,598 +turn on 275,365 through 609,382 +turn on 736,24 through 839,72 +turn off 86,492 through 582,712 +turn on 676,676 through 709,703 +turn off 105,710 through 374,817 +toggle 328,748 through 845,757 +toggle 335,79 through 394,326 +toggle 193,157 through 633,885 +turn on 227,48 through 769,743 +toggle 148,333 through 614,568 +toggle 22,30 through 436,263 +toggle 547,447 through 688,969 +toggle 576,621 through 987,740 +turn on 711,334 through 799,515 +turn on 541,448 through 654,951 +toggle 792,199 through 798,990 +turn on 89,956 through 609,960 +toggle 724,433 through 929,630 +toggle 144,895 through 201,916 +toggle 226,730 through 632,871 +turn off 760,819 through 828,974 +toggle 887,180 through 940,310 +toggle 222,327 through 805,590 +turn off 630,824 through 885,963 +turn on 940,740 through 954,946 +turn on 193,373 through 779,515 +toggle 304,955 through 469,975 +turn off 405,480 through 546,960 +turn on 662,123 through 690,669 +turn off 615,238 through 750,714 +turn on 423,220 through 930,353 +turn on 329,769 through 358,970 +toggle 590,151 through 704,722 +turn off 884,539 through 894,671 +toggle 449,241 through 984,549 +toggle 449,260 through 496,464 +turn off 306,448 through 602,924 +turn on 286,805 through 555,901 +toggle 722,177 through 922,298 +toggle 491,554 through 723,753 +turn on 80,849 through 174,996 +turn off 296,561 through 530,856 +toggle 653,10 through 972,284 +toggle 529,236 through 672,614 +toggle 791,598 through 989,695 +turn on 19,45 through 575,757 +toggle 111,55 through 880,871 +turn off 197,897 through 943,982 +turn on 912,336 through 977,605 +toggle 101,221 through 537,450 +turn on 101,104 through 969,447 +toggle 71,527 through 587,717 +toggle 336,445 through 593,889 +toggle 214,179 through 575,699 +turn on 86,313 through 96,674 +toggle 566,427 through 906,888 +turn off 641,597 through 850,845 +turn on 606,524 through 883,704 +turn on 835,775 through 867,887 +toggle 547,301 through 897,515 +toggle 289,930 through 413,979 +turn on 361,122 through 457,226 +turn on 162,187 through 374,746 +turn on 348,461 through 454,675 +turn off 966,532 through 985,537 +turn on 172,354 through 630,606 +turn off 501,880 through 680,993 +turn off 8,70 through 566,592 +toggle 433,73 through 690,651 +toggle 840,798 through 902,971 +toggle 822,204 through 893,760 +turn off 453,496 through 649,795 +turn off 969,549 through 990,942 +turn off 789,28 through 930,267 +toggle 880,98 through 932,434 +toggle 568,674 through 669,753 +turn on 686,228 through 903,271 +turn on 263,995 through 478,999 +toggle 534,675 through 687,955 +turn off 342,434 through 592,986 +toggle 404,768 through 677,867 +toggle 126,723 through 978,987 +toggle 749,675 through 978,959 +turn off 445,330 through 446,885 +turn off 463,205 through 924,815 +turn off 417,430 through 915,472 +turn on 544,990 through 912,999 +turn off 201,255 through 834,789 +turn off 261,142 through 537,862 +turn off 562,934 through 832,984 +turn off 459,978 through 691,980 +turn off 73,911 through 971,972 +turn on 560,448 through 723,810 +turn on 204,630 through 217,854 +turn off 91,259 through 611,607 +turn on 877,32 through 978,815 +turn off 950,438 through 974,746 +toggle 426,30 through 609,917 +toggle 696,37 through 859,201 +toggle 242,417 through 682,572 +turn off 388,401 through 979,528 +turn off 79,345 through 848,685 +turn off 98,91 through 800,434 +toggle 650,700 through 972,843 +turn off 530,450 through 538,926 +turn on 428,559 through 962,909 +turn on 78,138 through 92,940 +toggle 194,117 through 867,157 +toggle 785,355 through 860,617 +turn off 379,441 through 935,708 +turn off 605,133 through 644,911 +toggle 10,963 through 484,975 +turn off 359,988 through 525,991 +turn off 509,138 through 787,411 +toggle 556,467 through 562,773 +turn on 119,486 through 246,900 +turn on 445,561 through 794,673 +turn off 598,681 through 978,921 +turn off 974,230 through 995,641 +turn off 760,75 through 800,275 +toggle 441,215 through 528,680 +turn off 701,636 through 928,877 +turn on 165,753 through 202,780 +toggle 501,412 through 998,516 +toggle 161,105 through 657,395 +turn on 113,340 through 472,972 +toggle 384,994 through 663,999 +turn on 969,994 through 983,997 +turn on 519,600 through 750,615 +turn off 363,899 through 948,935 +turn on 271,845 through 454,882 +turn off 376,528 through 779,640 +toggle 767,98 through 854,853 +toggle 107,322 through 378,688 +turn off 235,899 through 818,932 +turn on 445,611 through 532,705 +toggle 629,387 through 814,577 +toggle 112,414 through 387,421 +toggle 319,184 through 382,203 +turn on 627,796 through 973,940 +toggle 602,45 through 763,151 +turn off 441,375 through 974,545 +toggle 871,952 through 989,998 +turn on 717,272 through 850,817 +toggle 475,711 through 921,882 +toggle 66,191 through 757,481 +turn off 50,197 through 733,656 +toggle 83,575 through 915,728 +turn on 777,812 through 837,912 +turn on 20,984 through 571,994 +turn off 446,432 through 458,648 +turn on 715,871 through 722,890 +toggle 424,675 through 740,862 +toggle 580,592 through 671,900 +toggle 296,687 through 906,775 diff --git a/06/main.py b/06/main.py new file mode 100755 index 0000000..cf9f85c --- /dev/null +++ b/06/main.py @@ -0,0 +1,53 @@ +#!/usr/bin/python + +import numpy as np + + + +def solve_partn(partn, lines): + # In part 1, we treat an int32 as a boolean: 1 = True, 0 = False + grid = np.zeros((1000, 1000), dtype="int32") + + for line in lines: + words = line.split() + if words[0] == "turn": + xi, yi = [int(n) for n in words[2].split(",")] + xf, yf = [int(n) + 1 for n in words[4].split(",")] + + if partn == 1: + if words[1] == "on": + grid[xi : xf, yi : yf] = 1 + elif words[1] == "off": + grid[xi : xf, yi : yf] = 0 + else: # partn == 2 + if words[1] == "on": + grid[xi : xf, yi : yf] += 1 + elif words[1] == "off": + grid[xi : xf, yi : yf] -= 1 + grid = np.clip(grid, 0, 1000000) + + elif words[0] == "toggle": + xi, yi = [int(n) for n in words[1].split(",")] + xf, yf = [int(n) + 1 for n in words[3].split(",")] + + if partn == 1: + grid[xi : xf, yi : yf] = 1 - grid[xi : xf, yi : yf] # NOT + else: # partn == 2 + grid[xi : xf, yi : yf] += 2 + + return np.sum(grid) + + + +def main(): + # Read instructions from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_partn(1, lines)) # 400410 for me + print("Part 2 solution:", solve_partn(2, lines)) # 15343601 for me + + + +if __name__ == "__main__": + main() diff --git a/06/test.py b/06/test.py new file mode 100755 index 0000000..ea9380a --- /dev/null +++ b/06/test.py @@ -0,0 +1,36 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + lines = ["turn on 0,0 through 999,999"] + self.assertEqual(main.solve_partn(1, lines), 1000000) + + def test_example2(self): + lines = ["turn on 0,0 through 999,999", "toggle 0,0 through 999,0"] + self.assertEqual(main.solve_partn(1, lines), 999000) + + def test_example3(self): + lines = ["turn on 0,0 through 999,999", "turn off 499,499 through 500,500"] + self.assertEqual(main.solve_partn(1, lines), 999996) + + + +class ExamplesPart2(unittest.TestCase): + def test_example1(self): + lines = ["turn on 0,0 through 0,0"] + self.assertEqual(main.solve_partn(2, lines), 1) + + def test_example2(self): + lines = ["toggle 0,0 through 999,999"] + self.assertEqual(main.solve_partn(2, lines), 2000000) + + + +if __name__ == "__main__": + unittest.main() diff --git a/07/input.txt b/07/input.txt new file mode 100644 index 0000000..1b7dfc9 --- /dev/null +++ b/07/input.txt @@ -0,0 +1,339 @@ +bn RSHIFT 2 -> bo +lf RSHIFT 1 -> ly +fo RSHIFT 3 -> fq +cj OR cp -> cq +fo OR fz -> ga +t OR s -> u +lx -> a +NOT ax -> ay +he RSHIFT 2 -> hf +lf OR lq -> lr +lr AND lt -> lu +dy OR ej -> ek +1 AND cx -> cy +hb LSHIFT 1 -> hv +1 AND bh -> bi +ih AND ij -> ik +c LSHIFT 1 -> t +ea AND eb -> ed +km OR kn -> ko +NOT bw -> bx +ci OR ct -> cu +NOT p -> q +lw OR lv -> lx +NOT lo -> lp +fp OR fv -> fw +o AND q -> r +dh AND dj -> dk +ap LSHIFT 1 -> bj +bk LSHIFT 1 -> ce +NOT ii -> ij +gh OR gi -> gj +kk RSHIFT 1 -> ld +lc LSHIFT 1 -> lw +lb OR la -> lc +1 AND am -> an +gn AND gp -> gq +lf RSHIFT 3 -> lh +e OR f -> g +lg AND lm -> lo +ci RSHIFT 1 -> db +cf LSHIFT 1 -> cz +bn RSHIFT 1 -> cg +et AND fe -> fg +is OR it -> iu +kw AND ky -> kz +ck AND cl -> cn +bj OR bi -> bk +gj RSHIFT 1 -> hc +iu AND jf -> jh +NOT bs -> bt +kk OR kv -> kw +ks AND ku -> kv +hz OR ik -> il +b RSHIFT 1 -> v +iu RSHIFT 1 -> jn +fo RSHIFT 5 -> fr +be AND bg -> bh +ga AND gc -> gd +hf OR hl -> hm +ld OR le -> lf +as RSHIFT 5 -> av +fm OR fn -> fo +hm AND ho -> hp +lg OR lm -> ln +NOT kx -> ky +kk RSHIFT 3 -> km +ek AND em -> en +NOT ft -> fu +NOT jh -> ji +jn OR jo -> jp +gj AND gu -> gw +d AND j -> l +et RSHIFT 1 -> fm +jq OR jw -> jx +ep OR eo -> eq +lv LSHIFT 15 -> lz +NOT ey -> ez +jp RSHIFT 2 -> jq +eg AND ei -> ej +NOT dm -> dn +jp AND ka -> kc +as AND bd -> bf +fk OR fj -> fl +dw OR dx -> dy +lj AND ll -> lm +ec AND ee -> ef +fq AND fr -> ft +NOT kp -> kq +ki OR kj -> kk +cz OR cy -> da +as RSHIFT 3 -> au +an LSHIFT 15 -> ar +fj LSHIFT 15 -> fn +1 AND fi -> fj +he RSHIFT 1 -> hx +lf RSHIFT 2 -> lg +kf LSHIFT 15 -> kj +dz AND ef -> eh +ib OR ic -> id +lf RSHIFT 5 -> li +bp OR bq -> br +NOT gs -> gt +fo RSHIFT 1 -> gh +bz AND cb -> cc +ea OR eb -> ec +lf AND lq -> ls +NOT l -> m +hz RSHIFT 3 -> ib +NOT di -> dj +NOT lk -> ll +jp RSHIFT 3 -> jr +jp RSHIFT 5 -> js +NOT bf -> bg +s LSHIFT 15 -> w +eq LSHIFT 1 -> fk +jl OR jk -> jm +hz AND ik -> im +dz OR ef -> eg +1 AND gy -> gz +la LSHIFT 15 -> le +br AND bt -> bu +NOT cn -> co +v OR w -> x +d OR j -> k +1 AND gd -> ge +ia OR ig -> ih +NOT go -> gp +NOT ed -> ee +jq AND jw -> jy +et OR fe -> ff +aw AND ay -> az +ff AND fh -> fi +ir LSHIFT 1 -> jl +gg LSHIFT 1 -> ha +x RSHIFT 2 -> y +db OR dc -> dd +bl OR bm -> bn +ib AND ic -> ie +x RSHIFT 3 -> z +lh AND li -> lk +ce OR cd -> cf +NOT bb -> bc +hi AND hk -> hl +NOT gb -> gc +1 AND r -> s +fw AND fy -> fz +fb AND fd -> fe +1 AND en -> eo +z OR aa -> ab +bi LSHIFT 15 -> bm +hg OR hh -> hi +kh LSHIFT 1 -> lb +cg OR ch -> ci +1 AND kz -> la +gf OR ge -> gg +gj RSHIFT 2 -> gk +dd RSHIFT 2 -> de +NOT ls -> lt +lh OR li -> lj +jr OR js -> jt +au AND av -> ax +0 -> c +he AND hp -> hr +id AND if -> ig +et RSHIFT 5 -> ew +bp AND bq -> bs +e AND f -> h +ly OR lz -> ma +1 AND lu -> lv +NOT jd -> je +ha OR gz -> hb +dy RSHIFT 1 -> er +iu RSHIFT 2 -> iv +NOT hr -> hs +as RSHIFT 1 -> bl +kk RSHIFT 2 -> kl +b AND n -> p +ln AND lp -> lq +cj AND cp -> cr +dl AND dn -> do +ci RSHIFT 2 -> cj +as OR bd -> be +ge LSHIFT 15 -> gi +hz RSHIFT 5 -> ic +dv LSHIFT 1 -> ep +kl OR kr -> ks +gj OR gu -> gv +he RSHIFT 5 -> hh +NOT fg -> fh +hg AND hh -> hj +b OR n -> o +jk LSHIFT 15 -> jo +gz LSHIFT 15 -> hd +cy LSHIFT 15 -> dc +kk RSHIFT 5 -> kn +ci RSHIFT 3 -> ck +at OR az -> ba +iu RSHIFT 3 -> iw +ko AND kq -> kr +NOT eh -> ei +aq OR ar -> as +iy AND ja -> jb +dd RSHIFT 3 -> df +bn RSHIFT 3 -> bp +1 AND cc -> cd +at AND az -> bb +x OR ai -> aj +kk AND kv -> kx +ao OR an -> ap +dy RSHIFT 3 -> ea +x RSHIFT 1 -> aq +eu AND fa -> fc +kl AND kr -> kt +ia AND ig -> ii +df AND dg -> di +NOT fx -> fy +k AND m -> n +bn RSHIFT 5 -> bq +km AND kn -> kp +dt LSHIFT 15 -> dx +hz RSHIFT 2 -> ia +aj AND al -> am +cd LSHIFT 15 -> ch +hc OR hd -> he +he RSHIFT 3 -> hg +bn OR by -> bz +NOT kt -> ku +z AND aa -> ac +NOT ak -> al +cu AND cw -> cx +NOT ie -> if +dy RSHIFT 2 -> dz +ip LSHIFT 15 -> it +de OR dk -> dl +au OR av -> aw +jg AND ji -> jj +ci AND ct -> cv +dy RSHIFT 5 -> eb +hx OR hy -> hz +eu OR fa -> fb +gj RSHIFT 3 -> gl +fo AND fz -> gb +1 AND jj -> jk +jp OR ka -> kb +de AND dk -> dm +ex AND ez -> fa +df OR dg -> dh +iv OR jb -> jc +x RSHIFT 5 -> aa +NOT hj -> hk +NOT im -> in +fl LSHIFT 1 -> gf +hu LSHIFT 15 -> hy +iq OR ip -> ir +iu RSHIFT 5 -> ix +NOT fc -> fd +NOT el -> em +ck OR cl -> cm +et RSHIFT 3 -> ev +hw LSHIFT 1 -> iq +ci RSHIFT 5 -> cl +iv AND jb -> jd +dd RSHIFT 5 -> dg +as RSHIFT 2 -> at +NOT jy -> jz +af AND ah -> ai +1 AND ds -> dt +jx AND jz -> ka +da LSHIFT 1 -> du +fs AND fu -> fv +jp RSHIFT 1 -> ki +iw AND ix -> iz +iw OR ix -> iy +eo LSHIFT 15 -> es +ev AND ew -> ey +ba AND bc -> bd +fp AND fv -> fx +jc AND je -> jf +et RSHIFT 2 -> eu +kg OR kf -> kh +iu OR jf -> jg +er OR es -> et +fo RSHIFT 2 -> fp +NOT ca -> cb +bv AND bx -> by +u LSHIFT 1 -> ao +cm AND co -> cp +y OR ae -> af +bn AND by -> ca +1 AND ke -> kf +jt AND jv -> jw +fq OR fr -> fs +dy AND ej -> el +NOT kc -> kd +ev OR ew -> ex +dd OR do -> dp +NOT cv -> cw +gr AND gt -> gu +dd RSHIFT 1 -> dw +NOT gw -> gx +NOT iz -> ja +1 AND io -> ip +NOT ag -> ah +b RSHIFT 5 -> f +NOT cr -> cs +kb AND kd -> ke +jr AND js -> ju +cq AND cs -> ct +il AND in -> io +NOT ju -> jv +du OR dt -> dv +dd AND do -> dq +b RSHIFT 2 -> d +jm LSHIFT 1 -> kg +NOT dq -> dr +bo OR bu -> bv +gk OR gq -> gr +he OR hp -> hq +NOT h -> i +hf AND hl -> hn +gv AND gx -> gy +x AND ai -> ak +bo AND bu -> bw +hq AND hs -> ht +hz RSHIFT 1 -> is +gj RSHIFT 5 -> gm +g AND i -> j +gk AND gq -> gs +dp AND dr -> ds +b RSHIFT 3 -> e +gl AND gm -> go +gl OR gm -> gn +y AND ae -> ag +hv OR hu -> hw +1674 -> b +ab AND ad -> ae +NOT ac -> ad +1 AND ht -> hu +NOT hn -> ho diff --git a/07/main.py b/07/main.py new file mode 100755 index 0000000..7babff9 --- /dev/null +++ b/07/main.py @@ -0,0 +1,61 @@ +#!/usr/bin/python + + + +def eval_wire(wires, w): + # Shortcut for cleaner code + if w.isdigit(): + return int(w) & 65535 + + result = 0 + tokens = wires[w] + + if len(tokens) == 1: + result = eval_wire(wires, tokens[0]) + + if len(tokens) == 2: + if tokens[0] == "NOT": + result = ~eval_wire(wires, tokens[1]) + + if len(tokens) == 3: + if tokens[1] == "AND": + result = eval_wire(wires, tokens[0]) & eval_wire(wires, tokens[2]) + if tokens[1] == "OR": + result = eval_wire(wires, tokens[0]) | eval_wire(wires, tokens[2]) + if tokens[1] == "LSHIFT": + result = eval_wire(wires, tokens[0]) << eval_wire(wires, tokens[2]) + if tokens[1] == "RSHIFT": + result = eval_wire(wires, tokens[0]) >> eval_wire(wires, tokens[2]) + + result &= 65535 + wires[w] = [str(result)] # cache result + return int(result) + + + +def solve_partn(partn, lines): + # Parse input into a marginally nicer form + wires = {} + for line in lines: + words = line.split(" ") + wires[words[-1]] = words[0 : -2] + + if partn == 2: + wires["b"] = ["46065"] + + return eval_wire(wires, "a") + + + +def main(): + # Read wire configuration from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_partn(1, lines)) # 46065 for me + print("Part 2 solution:", solve_partn(2, lines)) # 14134 for me + + + +if __name__ == "__main__": + main() diff --git a/07/test.py b/07/test.py new file mode 100755 index 0000000..a171571 --- /dev/null +++ b/07/test.py @@ -0,0 +1,57 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def setUp(self): + self.lines = [ + "123 -> x", + "456 -> y", + "x AND y -> d", + "x OR y -> e", + "x LSHIFT 2 -> f", + "y RSHIFT 2 -> g", + "NOT x -> h", + "NOT y -> i" + ] + + def test_example1(self): + lines = "\n".join(self.lines).replace("d", "a").splitlines() + self.assertEqual(main.solve_partn(1, lines), 72) + + def test_example2(self): + lines = "\n".join(self.lines).replace("e", "a").splitlines() + self.assertEqual(main.solve_partn(1, lines), 507) + + def test_example3(self): + lines = "\n".join(self.lines).replace("f", "a").splitlines() + self.assertEqual(main.solve_partn(1, lines), 492) + + def test_example4(self): + lines = "\n".join(self.lines).replace("g", "a").splitlines() + self.assertEqual(main.solve_partn(1, lines), 114) + + def test_example5(self): + lines = "\n".join(self.lines).replace("h", "a").splitlines() + self.assertEqual(main.solve_partn(1, lines), 65412) + + def test_example6(self): + lines = "\n".join(self.lines).replace("i", "a").splitlines() + self.assertEqual(main.solve_partn(1, lines), 65079) + + def test_example7(self): + lines = "\n".join(self.lines).replace("x", "a").splitlines() + self.assertEqual(main.solve_partn(1, lines), 123) + + def test_example8(self): + lines = "\n".join(self.lines).replace("y", "a").splitlines() + self.assertEqual(main.solve_partn(1, lines), 456) + + + +if __name__ == "__main__": + unittest.main() diff --git a/08/input.txt b/08/input.txt new file mode 100644 index 0000000..3309605 --- /dev/null +++ b/08/input.txt @@ -0,0 +1,300 @@ +"sjdivfriyaaqa\xd2v\"k\"mpcu\"yyu\"en" +"vcqc" +"zbcwgmbpijcxu\"yins\"sfxn" +"yumngprx" +"bbdj" +"czbggabkzo\"wsnw\"voklp\"s" +"acwt" +"aqttwnsohbzian\"evtllfxwkog\"cunzw" +"ugvsgfv" +"xlnillibxg" +"kexh\"pmi" +"syvugow" +"m\"ktqnw" +"yrbajyndte\\rm" +"f\"kak\x70sn\xc4kjri" +"yxthr" +"alvumfsjni\"kohg" +"trajs\x5brom\xf1yoijaumkem\"\"tahlzs" +"\"oedr\"pwdbnnrc" +"qsmzhnx\"" +"\"msoytqimx\\tbklqz" +"mjdfcgwdshrehgs" +"\"rivyxahf\"" +"ciagc\x04bp" +"xkfc" +"xrgcripdu\x4c\xc4gszjhrvumvz\"mngbirb" +"gvmae\"yiiujoqvr\"mkxmgbbut\"u" +"ih" +"ncrqlejehs" +"mkno\x43pcfdukmemycp" +"uanzoqxkpsksbvdnkji\"feamp" +"axoufpnbx\\ao\x61pfj\"b" +"dz\\ztawzdjy" +"ihne\"enumvswypgf" +"\"dgazthrphbshdo\\vuqoiy\"" +"dlnmptzt\\zahwpylc\\b\"gmslrqysk" +"mhxznyzcp" +"rebr\"amvxw\x5fmbnfpkkeghlntavj" +"lades\x47ncgdof\"\"jmbbk" +"dwxuis\xa5wdkx\\z\"admgnoddpgkt\\zs" +"g\\k\x27qsl\x34hwfglcdxqbeclt\xca\\" +"lhyjky\\m\"pvnm\\xmynpxnlhndmahjl" +"c\"uxabbgorrpprw\"xas\\vefkxioqpt" +"rfrvjxpevcmma\x71gtfipo" +"fgh\"kcwoqwfnjgdlzfclprg\"q" +"onxnwykrba" +"hkkg\x60f\"tjzsanpvarzgkfipl" +"\"aintes\"ofq\"juiaqlqxmvpe\\a" +"wiyczzs\"ciwk" +"mfqeu" +"v\xe1z\x7ftzalmvdmncfivrax\\rjwq" +"k\"vtg" +"exhrtdugeml\xf0" +"behnchkpld" +"mhgxy\"mfcrg\xc5gnp\"\"osqhj" +"rlvjy" +"awe" +"ctwy" +"vt" +"\x54t" +"zugfmmfomz" +"cv\"cvcvfaada\x04fsuqjinbfh\xa9cq\xd2c\"d" +"oj" +"xazanf\"wbmcrn" +"\\\\zkisyjpbzandqikqjqvee" +"dpsnbzdwnxk\\v" +"sj\"tuupr\\oyoh" +"myvkgnw\x81q\xaaokt\\emgejbsyvxcl\\\xee" +"ejeuqvunjcirdkkpt\"nlns" +"twmlvwxyvfyqqzu" +"\"xwtzdp\x98qkcis\"dm\\\"ep\"xyykq" +"vvcq\\expok" +"wgukjfanjgpdjb" +"\"mjcjajnxy\\dcpc" +"wdvgnecw\\ab\x44klceduzgsvu" +"dqtqkukr\"iacngufbqkdpxlwjjt" +"\"xj\"\x66qofsqzkoah" +"nptiwwsqdep" +"gsnlxql\x30mjl" +"yeezwokjwrhelny\"" +"bjauamn\\izpmzqqasid" +"tvjdbkn\"tiziw\x82r" +"w" +"xwoakbbnjnypnaa\xa9wft\"slrmoqkl" +"vwxtnlvaaasyruykgygrvpiopzygf\"vq" +"qdancvnvmhlmpj\\isdxs" +"xzc\\elw" +"b\"wxeqvy\"qf\"g\xcaoklsucwicyw\"dovr" +"yomlvvjdbngz\"rly\"afr" +"bfb\"x\"aweuwbwmoa\x13\"t\"zhr" +"\"dmfoxb\"qvpjzzhykt\xd2\"\"ryhxi" +"psqef\"yu\\qiflie\"\x79w" +"arzewkej\"lqmh\\sayyusxxo\\" +"vuvvp" +"hc\"lg\x6bcpupsewzklai\"l" +"cjdfygc\"auorqybnuqghsh\x10" +"j" +"wqjexk\"eyq\\lbroqhk\\dqzsqk" +"dws\"ru\"dvxfiwapif\"oqwzmle" +"agcykg\\jt\\vzklqjvknoe" +"kksd\"jmslja\\z\"y\\b\xaagpyojct" +"nnpipxufvbfpoz\"jno" +"dtw" +"xlolvtahvgqkx\\dgnhj\\spsclpcxv\\" +"mxea\\mbjpi" +"lgbotkk\"zmxh\\\\qji\"jszulnjsxkqf" +"lwckmhwhx\"gmftlb\x91am" +"xxdxqyxth" +"\"lmqhwkjxmvayxy" +"tf" +"qy" +"wdqmwxdztax\"m\"\x09\x11xdxmfwxmtqgwvf" +"\xcbnazlf\"ghziknszmsrahaf" +"e\x6aupmzhxlvwympgjjpdvo\"kylfa" +"\x81vhtlillb\xactgoatva" +"dvnlgr" +"f" +"xg\xfacwizsadgeclm" +"vnnrzbtw\"\\prod\\djbyppngwayy\"" +"lrt\xf4jahwvfz" +"aqpnjtom\"ymkak\\dadfybqrso\\fwv" +"gz\"aac\"mrbk\"ktommrojraqh" +"wycamwoecsftepfnlcdkm" +"nrhddblbuzlqsl\x9cben" +"vckxhyqkmqmdseazcykrbysm" +"sil\xbbtevmt\"gvrvybui\"faw\"j" +"cjex\\tp\x45pzf" +"asjobvtxszfodgf\"ibftg" +"gkyjyjdrxdcllnh\"sjcibenrdnxv" +"oswsdpjyxpbwnqbcpl\"yrdvs\\zq" +"\"\"tyowzc\\fycbp\"jbwrbvgui" +"cbpcabqkdgzmpgcwjtrchxp" +"iyrzfh\x45gw\"fdlfpiaap\x31xqq" +"evgksznidz" +"b\\w\\" +"loufizbiy\x57aim\"bgk" +"qjfyk" +"g\"anmloghvgr\x07zwqougqhdz" +"usbbmwcxd\\bdgg" +"htitqcpczml" +"eke\\cqvpexqqk\"to\"tqmljrpn\xe6lji\"" +"g\xd2ifdsej" +"h\"sk\"haajajpagtcqnzrfqn\xe6btzo" +"wfkuffdxlvm\\cvlyzlbyunclhmpp" +"myaavh\"spue" +"hqvez\x68d\"eo\"eaioh" +"s\"qd\"oyxxcglcdnuhk" +"ilqvar" +"srh" +"puuifxrfmpc\"bvalwi\x2blu\\" +"yywlbutufzysbncw\\nqsfbhpz\"mngjq" +"zbl\\jfcuop" +"hjdouiragzvxsqkreup\\" +"qi" +"ckx\\funlj\xa7ahi" +"k" +"ufrcnh\"ajteit" +"cqv\"bgjozjj\x60x\xa8yhvmdvutchjotyuz" +"hkuiet\"oku\x8cfhumfpasl" +"\"\\sbe\x4d" +"vhknazqt" +"eyyizvzcahgflvmoowvs\\jhvygci" +"kki\x3ewcefkgtjap\"xtpxh\"lzepoqj" +"wvtk" +"\"ynet" +"zh\\obk\"otagx\x59txfzf" +"ocowhxlx\xe6zqg\x63wx\\tclkhq\\vmaze" +"w\"cf" +"qpniprnrzrnvykghqnalr" +"jctcqra\"\x05dhlydpqamorqjsijt\\xjdgt" +"sig" +"qhlbidbflwxe\"xljbwls\x20vht" +"irmrebfla\xefsg\"j" +"nep" +"hjuvsqlizeqobepf" +"guzbcdp\"obyh" +"\"mjagins\xf9tqykaxy\"" +"knvsdnmtr\"zervsb" +"hzuy" +"zza\"k\"buapb\\elm\xfeya" +"lrqar\"dfqwkaaqifig\"uixjsz" +"\"azuo\x40rmnlhhluwsbbdb\x32pk\\yu\"pbcf" +"dplkdyty" +"rfoyciebwlwphcycmguc" +"ivnmmiemhgytmlprq\\eh" +"lhkyzaaothfdhmbpsqd\\yyw" +"tnlzifupcjcaj" +"\\qiyirsdrfpmu\\\x15xusifaag" +"\\lcomf\\s" +"uramjivcirjhqcqcg" +"kkbaklbxfxikffnuhtu\xc6t\"d" +"n\xefai" +"\"toy\"bnbpevuzoc\"muywq\"gz\"grbm" +"\"muu\\wt" +"\\srby\"ee" +"erf\"gvw\"swfppf" +"pbqcgtn\"iuianhcdazfvmidn\\nslhxdf" +"uxbp" +"up\\mgrcyaegiwmjufn" +"nulscgcewj\\dvoyvhetdegzhs\"" +"masv\"k\\rzrb" +"qtx\x79d\"xdxmbxrvhj" +"fid\\otpkgjlh\"qgsvexrckqtn\xf4" +"tagzu" +"bvl\\\"noseec" +"\\xgicuuh" +"w\"a\"npemf" +"sxp" +"nsmpktic\x8awxftscdcvijjobnq\"gjd" +"uks\"\"jxvyvfezz\"aynxoev\"cuoav" +"m" +"lkvokj" +"vkfam\"yllr\"q\x92o\x4ebecnvhshhqe\\" +"efdxcjkjverw" +"lmqzadwhfdgmep\x02tzfcbgrbfekhat" +"cpbk\x9azqegbpluczssouop\x36ztpuoxsw" +"cqwoczxdd\"erdjka" +"cwvqnjgbw\\fxdlby" +"mvtm" +"lt\"bbqzpumplkg" +"ntd\xeeuwweucnuuslqfzfq" +"y\xabl\"dbebxjrlbmuoo\\\x1au" +"qjoqx\\a" +"pu\"ekdnfpmly\xbago\"" +"fjhhdy" +"arl" +"xcywisim\"bwuwf\"\"raepeawwjub" +"pbe" +"dbnqfpzyaumxtqnd\xc5dcqrkwyop" +"ojv\x40vtkwgkqepm\x8bzft\\vedrry" +"wggqkfbwqumsgajqwphjec\"mstxpwz" +"zjkbem" +"icpfqxbelxazlls" +"pvpqs\\abcmtyielugfgcv\"tjxapxqxnx" +"oqddwlvmtv\"\x39lyybylfb\"jmngnpjrdw" +"gisgbve" +"\"aglg" +"y\"\"ss\xafvhxlrjv" +"qbgqjsra" +"ihshbjgqpdcljpmdwdprwloy" +"djja\\wcdn\"svkrgpqn\"uz\"hc\x43hj" +"cbjm" +"pnn" +"pqvh\"noh" +"\"\\fdktlp" +"ncea" +"pqgzphiyy" +"\xbedovhxuipaohlcvkwtxwmpz\"ckaif\"r" +"arjuzbjowqciunfwgxtph\"vlhy\"n" +"c" +"nrpdxunulgudqzlhtae" +"iefheu\"uru\"" +"aqijysxuijud\"np\\opbichhudil\xbesum" +"pfpevmtstl\"lde\"bzr\"vspdxs" +"vparfbdjwvzsocpnzhp" +"g\x4ffxaarafrsjthq\\\xc1rw" +"ng\\rqx\\gwpzucbh\xafl" +"rw\"nf\\dna" +"jkkeahxurxla\\g\xb3czrlsyimmwcwthr" +"twaailoypu\"oas\"kpuuyedlaw\\\xb0vzt" +"hznex\\gdiqvtugi" +"imdibsunjeswhk" +"ta\\icileuzpxro\"cfmv\"mzp" +"coykr\x57luiysucfaflmilhlehmvzeiepo" +"u\x3dfh\xd4yt" +"piw\x1bz\"eowy\"vfk\"wqiekw" +"gan\"y" +"p\"bevidoazcznr\"hddxuuq\"" +"bwzucczznutbxe" +"z\"viqgyqjisior\\iecosmjbknol" +"dmlpcglcfkfsctxydjvayhymv\x3c\\gp" +"bfvkqrintbbvgfv" +"xlzntrgdck\"cprc\xadczyarbznqmuhxyuh" +"uqdxnuwioc\"kdytxq\\ig" +"xrafmucpmfi" +"vr\"hltmfrge" +"eonf\"nt\\wtcnsocs" +"j\xb7xoslyjeyjksplkqixncgkylkw" +"njw\"pefgfbez\x9axshdmplxzquqe" +"di\x58bvptfsafirpc" +"l\x1fkco" +"x" +"mprndo\"n" +"psegit" +"svbdnkkuuqs\"sqxu\"oqcyz\"aizashk" +"cwkljukxer\\\"\\nff\"esjwiyaoy" +"ilxrkgbjjxpvhdtq\"cpiuoofdnkpp" +"hlngi\"ulxep\\qohtmqnqjb\"rkgerho" +"gxws\"bcgm\"p" +"bv\"mds\\zhfusiepgrz\\b\x32fscdzz" +"l\xfampwtme\x69qvxnx\"\"\xc4jruuymjxrpsv" +"qqmxhrn" +"xziq\\\x18ybyv\x9am\"neacoqjzytertisysza" +"aqcbvlvcrzceeyx\\j\"\"x" +"yjuhhb" +"\x5em\"squulpy" +"dpbntplgmwb" +"utsgfkm\\vbftjknlktpthoeo" +"ccxjgiocmuhf\"ycnh" +"lltj\"kbbxi" diff --git a/08/main.py b/08/main.py new file mode 100755 index 0000000..bfd5b08 --- /dev/null +++ b/08/main.py @@ -0,0 +1,64 @@ +#!/usr/bin/python + + + +def solve_part1(lines): + result = 0 + + for line in lines: + len_code = len(line) + + len_data = 0 + i = 0 + while i < len(line): + if line[i] == "\"": + pass + elif line[i] == "\\": + if line[i + 1] == "\"" or line[i + 1] == "\\": + len_data += 1 + i += 1 + elif line[i + 1] == "x": + len_data += 1 + i += 3 + else: + len_data += 1 + i += 1 + + result += len_code - len_data + + return result + + + +def solve_part2(lines_old): + # Escape all the provided strings once + lines_new = [] + for old in lines_old: + new = "\"" + for c in old: + if c == "\"": + new += "\\\"" + elif c == "\\": + new += "\\\\" + else: + new += c + new += "\"" + lines_new.append(new) + + # Then we can just run part 1 on the new input + return solve_part1(lines_new) + + + +def main(): + # Read (escaped) strings from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_part1(lines)) # 1333 for me + print("Part 2 solution:", solve_part2(lines)) # 2046 for me + + + +if __name__ == "__main__": + main() diff --git a/08/test.py b/08/test.py new file mode 100755 index 0000000..1d97b53 --- /dev/null +++ b/08/test.py @@ -0,0 +1,18 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class Examples(unittest.TestCase): + def test_example1(self): + lines = ["\"\"", "\"abc\"", "\"aaa\\\"aaa\"", "\"\\x27\""] + self.assertEqual(main.solve_part1(lines), 12) + self.assertEqual(main.solve_part2(lines), 19) + + + +if __name__ == "__main__": + unittest.main() diff --git a/09/input.txt b/09/input.txt new file mode 100644 index 0000000..9850564 --- /dev/null +++ b/09/input.txt @@ -0,0 +1,28 @@ +Faerun to Norrath = 129 +Faerun to Tristram = 58 +Faerun to AlphaCentauri = 13 +Faerun to Arbre = 24 +Faerun to Snowdin = 60 +Faerun to Tambi = 71 +Faerun to Straylight = 67 +Norrath to Tristram = 142 +Norrath to AlphaCentauri = 15 +Norrath to Arbre = 135 +Norrath to Snowdin = 75 +Norrath to Tambi = 82 +Norrath to Straylight = 54 +Tristram to AlphaCentauri = 118 +Tristram to Arbre = 122 +Tristram to Snowdin = 103 +Tristram to Tambi = 49 +Tristram to Straylight = 97 +AlphaCentauri to Arbre = 116 +AlphaCentauri to Snowdin = 12 +AlphaCentauri to Tambi = 18 +AlphaCentauri to Straylight = 91 +Arbre to Snowdin = 129 +Arbre to Tambi = 53 +Arbre to Straylight = 40 +Snowdin to Tambi = 15 +Snowdin to Straylight = 99 +Tambi to Straylight = 70 diff --git a/09/main.py b/09/main.py new file mode 100755 index 0000000..d082678 --- /dev/null +++ b/09/main.py @@ -0,0 +1,60 @@ +#!/usr/bin/python + +from itertools import permutations + + + +def parse_input(lines): + edges = {} + + for line in lines: + words = line.split() + x = words[0] + y = words[2] + d = int(words[4]) + + if x not in edges: + edges[x] = {} + if y not in edges: + edges[y] = {} + + edges[x][y] = d + edges[y][x] = d + + return edges + + + +def solve_partn(partn, lines): + edges = parse_input(lines) + nodes = list(edges.keys()) + + # This is simply the famous travelling salesman problem, + # so exhaustively trying all routes is the only solution. + routes = permutations(nodes) + totals = [] + for r in routes: + t = 0 + for i in range(len(r) - 1): + t += edges[r[i]][r[i + 1]] + totals.append(t) + + if partn == 1: + return min(totals) + else: # partn == 2 + return max(totals) + + + +def main(): + # Read distances (graph edges) from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_partn(1, lines)) # 207 for me + print("Part 2 solution:", solve_partn(2, lines)) # 804 for me + + + +if __name__ == "__main__": + main() diff --git a/09/test.py b/09/test.py new file mode 100755 index 0000000..932c12b --- /dev/null +++ b/09/test.py @@ -0,0 +1,22 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class Examples(unittest.TestCase): + def test_example1(self): + lines = [ + "London to Dublin = 464", + "London to Belfast = 518", + "Dublin to Belfast = 141" + ] + self.assertEqual(main.solve_partn(1, lines), 605) + self.assertEqual(main.solve_partn(2, lines), 982) + + + +if __name__ == "__main__": + unittest.main() diff --git a/10/main.py b/10/main.py new file mode 100755 index 0000000..b2ec42c --- /dev/null +++ b/10/main.py @@ -0,0 +1,41 @@ +#!/usr/bin/python + + + +def play_round(old): + new = "" + + i = 0 + while i < len(old): + c = old[i] + + count = 0 + while i < len(old) and old[i] == c: + count += 1 + i += 1 + + new += str(count) + c + + return new + + + +def solve_partn(partn, string): + rounds = 40 if partn == 1 else 50 + for i in range(rounds): + string = play_round(string) + return len(string) + + + +def main(): + # My personal input string + string = "1113122113" + + print("Part 1 solution:", solve_partn(1, string)) # 360154 for me + print("Part 2 solution:", solve_partn(2, string)) # 5103798 for me + + + +if __name__ == "__main__": + main() diff --git a/10/test.py b/10/test.py new file mode 100755 index 0000000..a311b2e --- /dev/null +++ b/10/test.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + self.assertEqual(main.play_round("1"), "11") + + def test_example2(self): + self.assertEqual(main.play_round("11"), "21") + + def test_example3(self): + self.assertEqual(main.play_round("21"), "1211") + + def test_example4(self): + self.assertEqual(main.play_round("1211"), "111221") + + def test_example5(self): + self.assertEqual(main.play_round("111221"), "312211") + + + +if __name__ == "__main__": + unittest.main() diff --git a/11/main.py b/11/main.py new file mode 100755 index 0000000..9939d42 --- /dev/null +++ b/11/main.py @@ -0,0 +1,71 @@ +#!/usr/bin/python + + + +def increment(string): + last = string[-1] + if last == "z": + return increment(string[0:-1]) + "a" + else: + return string[0:-1] + chr(ord(last) + 1) + + + +def solve_part1(old): + valid = False + while not valid: + new = increment(old) + + # Rule 2: no "i", "o" or "l" + # Cheap to check and likely to fail, so we do this first + rule2 = True + for c in ["i", "o", "l"]: + if new.count(c) > 0: + rule2 = False + break + if not rule2: + old = new + continue + + # Rule 1: one increasing straight of three letters + rule1 = False + ords = [ord(c) for c in new] + for i in range(len(new) - 2): + if ords[i + 1] == ords[i] + 1 and ords[i + 2] == ords[i] + 2: + rule1 = True + break + + # Rule 3: two different pair of letters + rule3 = False + count = 0 + taken = [] + for i in range(len(new) - 1): + if new[i] not in taken and new[i] == new[i + 1]: + count += 1 + taken.append(new[i]) + if count >= 2: + rule3 = True + + old = new + valid = rule1 and rule3 + + return new + + + +def solve_part2(old): + return solve_part1(solve_part1(old)) + + + +def main(): + # My personal input password + passwd = "vzbxkghb" + + print("Part 1 solution:", solve_part1(passwd)) # "vzbxxyzz" for me + print("Part 2 solution:", solve_part2(passwd)) # "vzcaabcc" for me + + + +if __name__ == "__main__": + main() diff --git a/11/test.py b/11/test.py new file mode 100755 index 0000000..b77bd46 --- /dev/null +++ b/11/test.py @@ -0,0 +1,23 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + old = "abcdefgh" + new = "abcdffaa" + self.assertEqual(main.solve_part1(old), new) + + def test_example2(self): + old = "ghijklmn" + new = "ghjaabcc" + self.assertEqual(main.solve_part1(old), new) + + + +if __name__ == "__main__": + unittest.main() diff --git a/12/input.txt b/12/input.txt new file mode 100644 index 0000000..d813484 --- /dev/null +++ b/12/input.txt @@ -0,0 +1 @@ +{"e":{"a":{"e":-39,"c":119,"a":{"c":65,"a":"orange","b":"green","d":"orange"},"g":"violet","b":{"e":6,"c":{"c":"violet","a":8,"b":["red",{"a":37},"green",84,"yellow","green",[24,45,"blue","blue",56,"yellow"],"orange"]},"a":"violet","b":{"a":85},"d":[109,66,["yellow","violet",21,-30],"violet","blue",-43,{"e":"violet","c":"red","a":"blue","b":-22,"d":[71,"red",30,"violet","red",26,120],"f":["red"]},"red"]},"d":{"e":"violet","a":"blue","d":"blue","c":"blue","h":"orange","b":{"e":"red","a":{"c":115,"a":137,"b":"green"},"d":-25,"c":"blue","h":{"a":161,"b":["yellow",56,129,-31,"yellow","red","green",105,"orange",130]},"b":142,"g":194,"f":122,"i":-16},"g":173,"f":["orange","green",54,-9],"i":-23},"f":{"c":110,"a":"yellow","b":[{"a":155},156,"violet",94,"yellow"],"d":{"e":91,"a":-18,"d":"red","c":["green","orange","orange",190,"yellow",158,"blue","orange","blue",4],"h":143,"b":"orange","g":145,"f":["orange",37,"yellow",-22,{"c":30,"a":78,"b":196,"d":84},-7,["yellow"]]}}},"b":[[{"c":0,"a":108,"b":"green","d":{"e":59,"c":119,"a":104,"b":167,"d":"blue"}},[189,"blue",121,[["green","orange","orange",-17,192,"red"],{"a":"violet"},"green",{"c":42,"a":"blue","b":"red"},{"e":78,"a":"blue","d":"violet","c":-9,"h":"violet","b":115,"g":"orange","f":"violet","i":"red"}],57,"violet"],"green"],[["blue",[1,53,"orange"],{"e":["green",-12,"blue","orange","green",136,173],"a":"violet","d":-43,"c":{"e":144,"c":133,"a":"yellow","g":154,"b":"orange","d":127,"f":194},"h":{"e":52,"a":-43,"d":"orange","c":-45,"h":"orange","b":150,"g":-12,"f":91,"i":6},"b":{"e":"yellow","c":"blue","a":"violet","g":112,"b":174,"d":"violet","f":90},"g":177,"f":"blue"},"red","violet",96],"green","violet",[{"a":["red","red",46,"red"],"b":["green",193,54,"orange"]},["orange",8,1,["violet",84,"violet"],155,"yellow",151,"blue",196],"yellow","red",{"a":["green","orange","green",61,"blue",39,-2,46,"red",54]},"violet",128]]]},"a":{"e":[{"e":["yellow"],"c":93,"a":"violet","b":{"a":{"a":"yellow","b":"blue"},"b":-4},"d":"violet"},171,103,[13,"orange",[[51,"violet","yellow",{"c":85,"a":103,"b":"green"},97,{"e":"orange","a":-11,"d":62,"j":"yellow","c":"orange","h":47,"b":83,"g":119,"f":180,"i":136},{"a":177},80],{"e":{"c":"yellow","a":"orange","b":3,"d":197},"a":130,"d":"red","j":"red","c":-44,"h":-15,"b":64,"g":125,"f":82,"i":"green"}],{"e":["orange",42,["orange",197,"violet","yellow","blue",11,"yellow"],189,"yellow","blue","green","violet"],"a":{"a":149,"b":69},"d":128,"c":[["green",150,45,86,"red",-8,41,"orange","blue"]],"h":[[-4,127,"yellow","violet",124,112,196,"violet",161,40],37,0,"orange",-30,-43,[-24,"orange",142,"violet","red"],"blue",66],"b":{"c":"violet","a":["yellow",91,182,20,"orange",159,46,55,141],"b":{"c":173,"a":-40,"b":"green","d":"violet"},"d":[67,80,27,-15]},"g":"red","f":{"c":"orange","a":99,"b":"green"}},{"e":{"c":40,"a":"orange","b":"green"},"c":"green","a":-44,"b":{"e":"blue","c":56,"a":"yellow","g":62,"b":188,"d":141,"f":-21},"d":"yellow","f":{"e":"yellow","c":67,"a":33,"g":"yellow","b":"yellow","d":51,"f":195}}],["orange","violet",["red"],["green",35,[170,-30,"orange",140,"green","violet","violet",["orange","yellow","yellow",35,"blue","violet",-36,182,"yellow",141],146]],{"a":61,"b":"orange"},[31,"blue","green",65,"red","green"],"violet"],{"c":"blue","a":["blue"],"b":17},95],"c":[[48,"blue",[49],"orange",{"e":"violet","c":"green","a":"red","b":"red","d":-29,"f":["orange",20,190,97,["orange","blue",-30,"blue","green"],"blue","yellow",-47,[123,"yellow","green"],-41]},"green",{"a":170,"b":32},[{"c":"green","a":"violet","b":"red"},["yellow",36,"yellow","violet",149,{"e":"red","c":141,"a":-24,"b":"yellow","d":-13,"f":"red"},69,"orange",19,[87,"red",167,"red",77,110]],"orange","violet"],{"a":-16}],[["red"],"violet"],{"a":[["red",83,{"e":"red","c":"blue","a":"blue","b":"orange","d":"orange"},49,"green","violet"],{"e":"yellow","a":"violet","d":17,"j":"green","c":{"e":"orange","c":"green","a":"green","b":99,"d":"yellow","f":"orange"},"h":9,"b":159,"g":"yellow","f":167,"i":147},["blue","green","violet"],"yellow",["violet",197,"blue",[170,81,"yellow","orange",196],-24,99,193],-8,["red",81,-11,"green","red","blue","yellow","blue",["blue","violet",131,184,160,-1]],"green"]},"orange"],"a":[{"e":"blue","a":"violet","d":[{"a":"blue","b":46},"violet",72,35,61,161],"j":["green",78,144,[168,["red",77,38,"green","red"],"green","yellow",-8,"yellow"],190,40,"yellow",17,171],"c":{"e":"red","c":"violet","a":"violet","b":-14,"d":"red","f":167},"h":[[[83,"green",69,"red"],"green",155,133],106,1,"orange"],"b":-41,"g":{"a":27},"f":"red","i":{"e":"green","c":"green","a":182,"g":"orange","b":"orange","d":["orange"],"f":"orange"}},"yellow","green",-26],"b":{"e":[-32,-11,{"e":"red","c":"yellow","a":{"e":"green","a":"red","d":105,"c":-20,"h":85,"b":{"e":47,"a":89,"d":"green","c":"violet","h":"orange","b":"green","g":140,"f":"green"},"g":111,"f":"orange","i":"yellow"},"b":143,"d":{"e":{"e":"orange","c":129,"a":"blue","b":142,"d":"violet"},"c":"blue","a":122,"b":["violet","orange",84,"orange"],"d":"red","f":"blue"}},58,[147]],"a":{"e":"orange","c":[{"e":141,"c":114,"a":137,"g":"orange","b":61,"d":105,"f":33}],"a":["red","red",{"e":"green","c":4,"a":"violet","b":"red","d":"blue"},"yellow",["green",15,"green",-40,149,"orange",{"e":-7,"c":74,"a":"red","b":"green","d":32}],"blue","yellow",146,[191,"blue",["orange","blue",187,"blue","orange",127,"yellow",38],120,161,55,-30,"green",-10,"violet"],"orange"],"b":{"a":-32,"b":"blue"},"d":{"e":["green",27],"c":[94,"violet","red",18,166,"yellow"],"a":{"e":"green","a":95,"d":"green","j":176,"c":84,"h":"violet","b":"yellow","g":-25,"f":51,"i":119},"b":144,"d":{"c":"violet","a":"yellow","b":"red"}}},"d":{"e":{"e":140,"a":{"e":"green","c":"green","a":0,"b":68,"d":152,"f":"red"},"d":["blue",6],"c":-29,"h":"green","b":["violet",106,"violet","orange",-38,175],"g":54,"f":[177,31,"violet","yellow"],"i":185},"a":"green","d":[111,49,"yellow","blue","orange",{"e":"yellow","a":"orange","d":"violet","j":"blue","c":"red","h":88,"b":-1,"g":"red","f":"red","i":{"e":121,"a":112,"d":195,"j":103,"c":94,"h":"red","b":12,"g":8,"f":22,"i":"orange"}},64,["violet",["blue",76,"blue","red","red"],["violet","blue","orange","yellow",144],185,{"a":66,"b":"orange"},199,"green","green"],14],"c":{"e":"green","a":"orange","d":{"c":[-23,189,-11,"green","violet",178,-4,"blue",68,"violet"],"a":["orange","red"],"b":"yellow","d":"yellow"},"j":{"c":-33,"a":"blue","b":"violet"},"c":107,"h":{"e":-16,"a":174,"d":{"e":"orange","c":"green","a":-28,"b":-30,"d":73},"j":"yellow","c":"orange","h":"orange","b":["blue","violet",-4,76,"red","red"],"g":59,"f":12,"i":199},"b":{"a":"green","b":54},"g":"violet","f":174,"i":["orange",41,85,"yellow","green",25,"red",-20,156,143]},"h":"yellow","b":"red","g":90,"f":-37,"i":{"a":146,"b":"violet"}},"j":"blue","c":[1,["yellow",-11,"green",66,"red",90,"green","yellow",3,{"e":-34,"a":194,"d":"green","c":[-11,"yellow"],"h":59,"b":"yellow","g":"blue","f":162,"i":"violet"}],81,158,170],"h":"blue","b":"green","g":["violet",["blue","blue"]],"f":[-44,"yellow",[35,[122,"red","yellow",{"a":"red","b":"violet"},"blue","orange","violet"],"violet",{"e":-48,"a":6,"d":-6,"c":4,"h":"yellow","b":"blue","g":"red","f":"red"}],[{"e":-2,"a":156,"d":"red","j":69,"c":0,"h":"violet","b":"orange","g":61,"f":102,"i":["orange","blue","violet",-1,137]},{"a":183,"b":89}],{"a":167,"b":"orange"},193,95,[97,[66,154,-32,"orange",121,{"e":198,"a":"blue","d":102,"c":"red","h":"green","b":135,"g":"orange","f":-49,"i":151},97,7,"red"],195,"blue",49,"green",10]],"i":["violet",1,{"e":"orange","c":196,"a":"blue","g":"red","b":190,"d":87,"f":128},"blue",128,147]},"d":[[{"a":"green","b":43},169,-8,"orange",{"a":["violet",["red","violet","orange","yellow",-49,"violet",-25],"violet",60,33,"violet",["yellow","orange",31,144,"red","yellow",73,"orange","red","green"],["green",-31,"red"],"orange","blue"]},"violet","blue"],40,154,{"a":{"c":"violet","a":145,"b":166,"d":["blue",["blue",125,185,"yellow","red",152,89,-18,"blue",141],26,2,35,"orange",190]}},170,"violet",-31,[[151,"orange","green",["blue",114,-5,"yellow"],"blue","green","orange","yellow",62,{"c":22,"a":"green","b":"blue"}],17,[176],"violet",129,67,{"c":{"c":"red","a":140,"b":25},"a":["blue","green",163],"b":30,"d":[60,"green","red",126,[48,"green"],-26,["yellow","green",150,"red","violet","red","violet",59,-12],167,"yellow"]},"yellow","yellow"],"blue"]},"d":{"c":"green","a":52,"b":[136,{"c":{"a":[197,["orange","red",138,67,"orange",172,2,"orange"],"red"]},"a":"violet","b":{"a":{"e":172,"c":171,"a":"yellow","b":191,"d":{"e":171,"a":"red","d":"violet","c":"green","h":"yellow","b":"yellow","g":73,"f":"yellow"}}},"d":[86,-11,-5,["orange","green",64,["blue",15,"orange","yellow","violet",181,"green","blue"],"yellow","yellow",{"e":27,"c":156,"a":"blue","g":"violet","b":38,"d":51,"f":23},"orange","violet"],10]},[55,{"e":191,"c":"blue","a":"orange","b":"yellow","d":109},"blue",{"c":164,"a":[198,-9,183,{"e":14,"a":176,"d":117,"c":"violet","h":"violet","b":-44,"g":"violet","f":"red","i":"orange"},"yellow",0],"b":58,"d":33},"red",[125,23,"blue",149,[["blue",-44,22,133,"orange","yellow","yellow","violet","violet",131],"violet",-1,"red",66,"blue"],"green","red","red",[-31,"blue",["orange","orange","yellow",44,"green","yellow","green",160,"violet"],"yellow",["orange","violet","green","violet",194,"blue",-27],"green",{"e":"violet","a":"red","d":67,"c":68,"h":"blue","b":"orange","g":"orange","f":"violet","i":"violet"},"yellow"]],"violet",[59,158,{"e":"blue","c":"blue","a":"orange","g":73,"b":97,"d":"red","f":"orange"}],["red",[31,[95,72,"orange","yellow"],"blue",192,63],[197,"green",{"e":112,"a":"violet","d":"blue","c":-2,"h":"blue","b":"green","g":124,"f":"blue"},177,"green","blue",162,107]]],43,[{"e":"red","c":{"e":["green",-33,11,154,"yellow",-4],"c":"yellow","a":[7,"orange","orange","yellow",118,169,"red","blue"],"b":"green","d":114},"a":{"e":"green","a":"green","d":187,"j":{"e":106,"c":-41,"a":"violet","b":173,"d":12},"c":"red","h":"violet","b":-4,"g":{"c":"violet","a":-26,"b":87,"d":-33},"f":"green","i":-46},"b":"green","d":13,"f":"yellow"}],["blue","violet","orange","red",{"e":"green","a":["violet",140,[76,"green",94,33,"green",31,"orange",53],"violet","yellow","violet","blue",["blue",196,"orange","yellow","orange",-42,"orange",171,-47,"violet"],"green",110],"d":31,"c":"orange","h":{"e":-45,"a":"green","d":["violet"],"c":"red","h":105,"b":130,"g":-36,"f":"orange","i":{"e":"red","c":137,"a":54,"g":"blue","b":"violet","d":102,"f":178}},"b":-41,"g":{"e":6,"a":-25,"d":66,"j":"violet","c":39,"h":30,"b":63,"g":46,"f":56,"i":"blue"},"f":6,"i":"violet"},[84,175,"orange",{"a":"green"},"green",66,{"e":"red","a":{"a":178,"b":"yellow"},"d":"yellow","c":["red","red",38,"orange","blue",136,"red",137,"red"],"h":163,"b":["orange",84,"red",178],"g":65,"f":"blue"}],[98,"yellow",[46,"orange","yellow","yellow"],"blue",151,189,["yellow",{"e":"orange","a":27,"d":45,"c":48,"h":"green","b":90,"g":180,"f":-43},"yellow"],"blue"],{"a":"green"},"blue",{"c":37,"a":{"e":59,"c":["blue"],"a":"yellow","g":38,"b":"blue","d":"violet","f":"orange"},"b":"orange","d":"violet"}],{"c":75,"a":{"e":{"a":130},"a":5,"d":1,"c":72,"h":{"e":"red","a":11,"d":157,"c":97,"h":-24,"b":"red","g":111,"f":21},"b":{"e":145,"a":"red","d":"violet","j":[-11,191,-43,"blue","orange",105,158],"c":"red","h":143,"b":{"e":"orange","c":"yellow","a":-31,"g":177,"b":"violet","d":"blue","f":"green"},"g":"green","f":48,"i":{"e":18,"a":142,"d":"yellow","c":116,"h":"violet","b":135,"g":37,"f":36}},"g":-26,"f":[186,192,"orange",117,-9,"violet",-19,55,"green",167],"i":"green"},"b":"yellow","d":{"a":138}}]},"c":"blue","h":[[19],"orange",[{"e":["yellow",68,28,29,{"e":"red","a":"violet","d":"green","c":143,"h":"red","b":"orange","g":44,"f":123,"i":"orange"},38,28,65,{"e":-26,"c":["red",132,"red",124,"yellow",115],"a":170,"g":"yellow","b":"green","d":-18,"f":{"c":1,"a":"red","b":-1}}],"a":"orange","d":129,"c":33,"h":"violet","b":"orange","g":"green","f":-24},["violet",-22],[64,-20,{"e":46,"a":76,"d":97,"c":-21,"h":98,"b":"violet","g":{"e":-7,"c":"violet","a":190,"b":"violet","d":138,"f":"violet"},"f":[178,"blue","blue"],"i":"red"},{"e":"orange","c":"red","a":{"e":"orange","a":["green"],"d":[19,"red"],"c":-32,"h":-15,"b":"yellow","g":116,"f":"blue","i":"orange"},"b":96,"d":"green","f":176},[[104,99,"yellow",-13,"red",{"c":"blue","a":"red","b":46,"d":60},-13,9],-22,-26,133,["green",["red",188,"green","green"],166,"yellow",{"e":"yellow","c":197,"a":65,"b":83,"d":-19,"f":"yellow"},[157,"violet","blue","yellow",-30,"violet",-3],21,{"a":-15}],43,["orange","blue",88,"yellow",103,31],"orange",-24]],{"c":"violet","a":{"a":26,"b":"yellow"},"b":["violet","violet",{"e":102,"a":"red","d":178,"j":187,"c":"orange","h":"violet","b":72,"g":-37,"f":"violet","i":"orange"},44,114,"yellow",85]}],{"e":150,"c":"green","a":{"e":{"e":{"e":{"e":"orange","a":48,"d":41,"j":"orange","c":"orange","h":30,"b":"yellow","g":41,"f":-40,"i":8},"c":199,"a":32,"b":"yellow","d":-28},"a":46,"d":[50,"red","violet",63,"red",56,-18,"orange","violet","red"],"c":"blue","h":{"e":"green","c":172,"a":"green","b":-30,"d":22,"f":"yellow"},"b":"orange","g":65,"f":"yellow","i":174},"a":"green","d":[196,{"e":{"e":176,"a":"violet","d":"orange","j":-37,"c":19,"h":31,"b":155,"g":"red","f":106,"i":"green"},"c":"red","a":64,"b":"orange","d":179,"f":8},"yellow",103,"violet",{"e":142,"a":111,"d":"yellow","c":"violet","h":"red","b":148,"g":29,"f":179,"i":"green"},-26],"c":-19,"h":["red",134,"green","green",105],"b":"orange","g":126,"f":76,"i":158},"b":55,"d":"green"},[[[61],[["orange","red"],[151,"yellow",127,"yellow",185,"yellow",{"e":105,"c":"yellow","a":198,"b":"orange","d":"blue","f":89},140,{"e":"violet","a":-15,"d":169,"j":3,"c":"yellow","h":74,"b":-41,"g":29,"f":112,"i":18}]],101,{"e":[45,"green","yellow","blue","violet",["violet","yellow",159,0,"orange","yellow",100,"green","blue",49],[5,-37],"blue","orange"],"c":88,"a":"blue","b":-32,"d":23},77,{"e":["yellow",119,197,["orange",-28,"yellow",179,130,74,-10,115,"violet",79],"orange",63,-15,17,"blue","violet"],"c":{"e":164,"a":83,"d":"yellow","c":119,"h":"yellow","b":148,"g":-22,"f":[-17,17,"violet","green","red"],"i":67},"a":{"e":54,"a":147,"d":"yellow","c":86,"h":113,"b":"yellow","g":77,"f":101,"i":"blue"},"g":"orange","b":[193,"orange","orange","red",39,44,43,-29],"d":"violet","f":191}],"orange",["red","violet","yellow",["red",54,{"e":{"a":41,"b":"violet"},"c":"red","a":{"e":"red","a":"yellow","d":"green","j":-33,"c":96,"h":137,"b":"yellow","g":30,"f":"green","i":"blue"},"b":181,"d":"violet","f":"green"},49,"yellow"],"orange","yellow",{"e":"orange","c":[46,"orange",["blue","green","blue","yellow","yellow","violet","orange","orange",1],"yellow",155,194,"yellow",149],"a":"green","b":-3,"d":153,"f":[-21,-26,-25,"blue","red",108,169,["green",100,43],51,-9]}],71,[[[{"a":"violet","b":27},148,109,["blue",60,47,"violet","yellow",-47,"violet"],"red",{"e":97,"c":-21,"a":"yellow","b":"green","d":126},"yellow",85,89],{"a":["red","orange","violet","blue","blue","blue",128,"blue"]},{"e":-48,"c":{"c":90,"a":"orange","b":"yellow"},"a":"yellow","b":"red","d":172},"yellow",{"a":"orange"},[{"e":"yellow","a":40,"d":-9,"j":"violet","c":153,"h":79,"b":"violet","g":178,"f":2,"i":"yellow"},"green",-29],"red",-9,[9,{"a":39,"b":"green"},5,"violet",26,{"e":167,"c":"blue","a":"yellow","b":90,"d":33},"green",88,12,"blue"]],"red",{"c":{"e":"yellow","a":-44,"d":62,"j":-19,"c":96,"h":"green","b":-12,"g":"green","f":"red","i":134},"a":22,"b":24,"d":33},"red","violet",{"e":181,"c":64,"a":"violet","g":"green","b":"yellow","d":"violet","f":101},"green",[132,93,[-6,[-3,28,"red"],-21,"red","violet",{"a":180},"red","blue",-15],{"e":171,"a":{"e":"green","c":49,"a":"orange","g":22,"b":"violet","d":"orange","f":"orange"},"d":"red","c":113,"h":"green","b":[30,"blue"],"g":{"a":139,"b":47},"f":"red","i":"red"},"violet",158,"green",5,-1],19],"red"],{"e":{"c":["orange",93,162,"green","violet",["green",178],{"a":"green","b":{"e":-12,"a":-16,"d":144,"c":"red","h":"violet","b":43,"g":"green","f":-42}}],"a":"blue","b":"blue","d":{"e":["orange","red",{"c":-19,"a":"green","b":93},"yellow","green","orange","orange","red","green"],"a":"green","d":{"e":"yellow","a":2,"d":"violet","j":"green","c":"blue","h":19,"b":"violet","g":"blue","f":[157,"green",109,59,"red",74,"red","blue","green"],"i":"orange"},"j":"yellow","c":166,"h":"yellow","b":"yellow","g":["violet",138,["violet",141,"green"]],"f":28,"i":{"e":52,"c":"yellow","a":"green","b":5,"d":{"e":153,"a":"yellow","d":191,"j":"green","c":"green","h":124,"b":"green","g":181,"f":134,"i":"yellow"},"f":193}}},"c":"violet","a":{"a":{"a":"green"},"b":[132]},"b":[{"e":11,"a":"green","d":{"e":{"e":119,"a":"violet","d":"red","c":"red","h":"violet","b":-6,"g":"blue","f":"orange","i":"orange"},"a":183,"d":[-36,"yellow"],"c":"red","h":71,"b":"yellow","g":2,"f":"orange"},"c":"green","h":"yellow","b":29,"g":"green","f":"blue","i":{"e":"yellow","a":-24,"d":[55,125,193,70,60,190,199],"c":"green","h":[49,"yellow","yellow",74,"red",163],"b":198,"g":50,"f":"blue","i":70}},"orange"],"d":"blue"},{"c":{"e":-20,"a":8,"d":["orange",157,152,"green",46,"green",7,89,"violet",[-22,-49,81,127]],"c":35,"h":["blue","yellow","orange",94,"orange","yellow"],"b":"red","g":{"a":"green","b":["yellow","orange",198]},"f":"violet","i":17},"a":-48,"b":"blue"}],"b":[[149,[{"e":"blue","c":-30,"a":"violet","g":"violet","b":"yellow","d":178,"f":-4}],"orange",131,"yellow",{"a":"red","b":"violet"},"blue"],[11],{"e":[35,118,{"e":39,"a":"yellow","d":[119,"orange",120,-43],"j":"violet","c":"orange","h":"blue","b":-32,"g":[{"e":"green","c":106,"a":144,"b":147,"d":"green"},"violet","orange"],"f":116,"i":"orange"},112,"yellow"],"a":{"e":19,"a":"orange","d":61,"c":"red","h":"blue","b":164,"g":{"c":"red","a":-10,"b":{"e":{"e":"green","c":82,"a":103,"g":67,"b":153,"d":"violet","f":22},"c":-22,"a":101,"b":71,"d":{"a":152,"b":"green"},"f":"orange"}},"f":157,"i":{"e":"green","a":"orange","d":-8,"j":[159,73,182,"red","green"],"c":13,"h":"blue","b":"yellow","g":186,"f":"orange","i":81}},"d":13,"c":[186,["yellow",["violet","violet"],"green",-28],54,["blue",[119,"red",119,91,181],117],-15,190,{"c":"red","a":13,"b":[{"c":"green","a":70,"b":8,"d":175},"orange","green","yellow","green"]},"blue",-43],"h":{"e":[{"a":"green"},88,"red","violet",10],"a":{"a":"orange","b":[62,"yellow","green"]},"d":151,"c":"red","h":"orange","b":126,"g":{"a":"orange"},"f":"orange","i":46},"b":[[-2,"violet","violet","red",{"a":192},"green",122],["orange","red",{"c":62,"a":52,"b":-45},{"e":{"a":"violet","b":-45},"a":"red","d":"orange","c":"yellow","h":{"e":67,"c":-27,"a":116,"b":"violet","d":"green","f":-18},"b":"yellow","g":"blue","f":"blue"},27,{"c":37,"a":-39,"b":"blue"}],107,"yellow",["blue","red",143],"blue",{"e":"orange","a":["yellow",["blue",8,149,141,"red",-28,"red"],18],"d":29,"c":"violet","h":-21,"b":[{"e":66,"c":"green","a":"blue","b":-29,"d":"orange","f":"violet"},"blue",-21],"g":"green","f":112},73],"g":["red",{"a":{"e":93,"a":13,"d":"violet","c":175,"h":158,"b":9,"g":194,"f":-10},"b":"blue"}],"f":130}],"g":[["red","orange","orange",172,154,{"e":{"a":"blue","b":{"a":"yellow","b":53}},"c":-11,"a":"orange","g":"yellow","b":{"e":{"e":94,"a":123,"d":184,"j":-4,"c":193,"h":152,"b":"blue","g":"red","f":101,"i":178},"c":"blue","a":178,"b":154,"d":[103,109,190,"yellow",29,"red","orange","yellow",79,"green"],"f":"orange"},"d":{"e":25,"a":{"a":"blue"},"d":"green","c":"orange","h":{"e":144,"c":["red","blue","violet",15,"green",109,72],"a":"yellow","b":"orange","d":"yellow"},"b":151,"g":[141,"orange",134,"blue","blue",4,21,"blue","green"],"f":96},"f":"blue"},"blue"],80,186,[[194,"violet",70,"green"],{"a":"orange","b":"green"},[{"e":"orange","a":179,"d":{"e":164,"c":-14,"a":"blue","g":"yellow","b":"violet","d":76,"f":-33},"c":"green","h":"violet","b":"orange","g":"blue","f":"orange","i":"green"},"blue"]],"orange","yellow",66],"f":{"a":["violet"],"b":87},"i":{"e":{"c":[{"e":"red","a":19,"d":100,"j":"red","c":"red","h":"red","b":"yellow","g":-41,"f":10,"i":"blue"},42,92,"violet","red",[149,"green",91,"blue"],-33,["green",73,129],110,{"e":168,"c":153,"a":-30,"b":"yellow","d":[192,{"c":"blue","a":"blue","b":-16,"d":-18},{"e":"red","c":"yellow","a":"violet","b":31,"d":"green"},"blue"],"f":{"c":9,"a":"yellow","b":-16,"d":128}}],"a":[[["green","violet",136,59,"orange",173,116,113,"yellow"],"green",{"e":"blue","c":"green","a":"blue","g":"red","b":98,"d":-25,"f":21},"orange",184],4,"yellow","red",-24,{"c":"orange","a":15,"b":{"e":109,"c":179,"a":61,"b":"orange","d":190,"f":9}}],"b":[[92,148,{"e":"blue","a":0,"d":108,"c":197,"h":"red","b":"orange","g":-22,"f":105,"i":"blue"},"blue"],-7,149]},"a":{"e":{"a":{"e":"green","a":["violet",172],"d":-10,"c":42,"h":"blue","b":80,"g":{"e":"red","c":"orange","a":"yellow","g":87,"b":{"e":31,"c":129,"a":"orange","b":43,"d":"blue"},"d":"blue","f":81},"f":"violet"},"b":"orange"},"a":182,"d":{"c":{"a":154},"a":"blue","b":{"e":31,"a":["yellow","blue","red",{"a":"orange"},"red",62,39,"red",["green","orange","yellow",47,"orange",55,"blue"]],"d":[72,187,"red","orange",59,"yellow","violet","green"],"j":"orange","c":"yellow","h":185,"b":{"e":"blue","c":"violet","a":["orange",7,180,150,46,"yellow",176,"orange"],"b":148,"d":"blue"},"g":"blue","f":"yellow","i":102}},"c":"red","h":-9,"b":14,"g":{"a":"green","b":{"c":-18,"a":81,"b":104}},"f":[[{"e":-33,"c":"green","a":"orange","b":"blue","d":"blue"},"yellow",141,[42,197],[-12,61,{"e":"violet","a":"violet","d":"green","c":-21,"h":-5,"b":"orange","g":39,"f":"green"},"blue"],31,[[101,"blue",-14,"red",88],58,["red","blue","violet",34],-14,"yellow",98,106,91,131],"yellow",[151,"red","green",{"e":"violet","c":"green","a":49,"g":155,"b":96,"d":"blue","f":"orange"},-18,184,{"c":"blue","a":1,"b":162},{"e":115,"a":94,"d":97,"j":-34,"c":"blue","h":115,"b":"red","g":"orange","f":149,"i":105}],38],{"c":{"e":"blue","c":90,"a":"yellow","b":142,"d":"violet"},"a":-38,"b":"violet"}],"i":189},"d":"orange","c":[[103,8,"green",13,23,"violet",55],[{"e":79,"c":74,"a":{"e":"violet","a":{"c":"red","a":"violet","b":168},"d":142,"j":"blue","c":173,"h":"yellow","b":"green","g":"blue","f":"blue","i":"blue"},"g":[{"c":"violet","a":82,"b":90},-24,{"a":"orange"},"yellow",[126,53,153,6],52,137,"violet",181],"b":105,"d":166,"f":{"e":"blue","c":-35,"a":"blue","b":188,"d":-14,"f":63}},{"e":95,"a":"green","d":"yellow","j":"red","c":81,"h":107,"b":-46,"g":162,"f":"green","i":"red"},[{"e":"violet","a":150,"d":126,"c":10,"h":{"e":"green","a":"orange","d":19,"c":"green","h":"green","b":79,"g":"red","f":"yellow","i":"blue"},"b":{"a":25,"b":147},"g":180,"f":126},{"e":-48,"a":192,"d":-45,"c":25,"h":"green","b":{"c":165,"a":"orange","b":"red","d":"blue"},"g":"green","f":-24},95,{"e":"blue","a":"violet","d":"yellow","j":"blue","c":44,"h":["blue","green","red",142,"red"],"b":[-43,"violet","green",53],"g":33,"f":"orange","i":196},"orange","green",43,[113,"violet","orange",129,{"c":6,"a":"violet","b":"green","d":"green"},20]],"green"]],"h":{"a":-11},"b":{"e":"violet","c":174,"a":"violet","g":[{"e":105,"a":{"c":-5,"a":177,"b":63},"d":-41,"c":80,"h":[110,109,113,"blue"],"b":-28,"g":"red","f":129},["green",[108],{"a":4},[182,96,29,[181,14,"yellow","violet"],13,{"e":132,"a":115,"d":"red","c":"violet","h":"violet","b":"violet","g":"green","f":"green"},{"e":"orange","a":"yellow","d":"blue","j":"red","c":137,"h":"violet","b":"green","g":-22,"f":"yellow","i":-12},"green","yellow",57],-44,{"a":88,"b":-3},22,{"c":"red","a":"violet","b":-21}],[[14,"orange"]],-36,128,"yellow",[-47,[-7,36,177],"blue","blue",["yellow","violet",-23,"violet",-40,"orange",{"e":129,"a":21,"d":51,"j":"violet","c":"red","h":15,"b":174,"g":191,"f":101,"i":105}],23,[-47,[133,66,"violet"],177,"violet","yellow","green",159,"yellow"]],{"e":[{"a":"orange"},"green",69,"orange",43,"violet","violet",192,140,"green"],"a":62,"d":"violet","j":{"c":"violet","a":-25,"b":"violet"},"c":120,"h":"red","b":{"a":13},"g":"green","f":124,"i":33},[[19,176,174,"orange","violet","violet",105,128,"red"],{"a":10,"b":"red"},["orange",37,187,"green",176],"blue","red",[153,"yellow","violet",137,"orange","blue",[70,"red",174,"blue","green","yellow",99,"red"],"violet","violet","red"]]],"b":[{"c":133,"a":"orange","b":98,"d":{"c":"red","a":-9,"b":103}},"blue",[155,"yellow"],[["yellow",-8,{"e":"blue","c":59,"a":71,"g":"orange","b":88,"d":"orange","f":17},"blue",-37],{"e":82,"c":"violet","a":99,"b":81,"d":"yellow","f":161},"blue",{"c":-7,"a":154,"b":"violet"},-9,-13,53,{"e":"violet","a":"yellow","d":-26,"c":179,"h":"green","b":"red","g":-24,"f":133,"i":-36}]],"d":{"e":[9,[49],28,"red",{"c":23,"a":157,"b":{"c":"violet","a":"green","b":-11,"d":"green"},"d":139},"orange","green",93,44,[-19]],"a":-6,"d":7,"c":{"e":{"c":"violet","a":-21,"b":12},"c":["green",[-23,-40,157],"red",["orange","blue"],"violet","red",85,"violet","yellow",150],"a":162,"g":"yellow","b":"green","d":["green","yellow",181,"green",-2,{"e":"red","a":"yellow","d":129,"c":-34,"h":129,"b":152,"g":"yellow","f":80,"i":"red"},"green","red",-9,"red"],"f":6},"h":{"e":136,"a":"violet","d":["violet",-15,129,"green",5,"green",[-28,156,141,"blue",22,"green",34],"green"],"c":149,"h":["violet"],"b":149,"g":"green","f":149},"b":{"e":123,"a":"red","d":{"e":0,"c":"green","a":"violet","b":"yellow","d":"red","f":"green"},"c":{"e":{"e":"yellow","c":"red","a":"red","b":"violet","d":"yellow"},"a":"yellow","d":{"e":-39,"a":-11,"d":63,"c":179,"h":4,"b":44,"g":"orange","f":"violet","i":"yellow"},"c":-43,"h":"green","b":"violet","g":"blue","f":"yellow","i":124},"h":48,"b":129,"g":["orange",147,174,"blue","green",115],"f":172,"i":-36},"g":"red","f":30,"i":"violet"},"f":"red"},"g":{"e":{"e":[[126,"orange",196,"orange","red",{"e":23,"a":"yellow","d":128,"c":12,"h":-49,"b":"green","g":"yellow","f":41,"i":45},"red","violet"]],"c":[["red",103,{"e":69,"a":"violet","d":"yellow","c":"green","h":"red","b":133,"g":25,"f":"violet"}],88,"green","red",-29,"red"],"a":37,"b":"green","d":{"e":"orange","c":{"e":{"e":109,"c":144,"a":"yellow","b":70,"d":83},"c":-3,"a":"green","b":"yellow","d":146},"a":86,"b":-1,"d":{"a":68}}},"c":{"c":[155,18,"blue",-16,"orange",-36,49,"red",["yellow",136,140,-10,11,"violet","red",134,156,"violet"]],"a":64,"b":{"e":"violet","c":193,"a":101,"b":["green"],"d":182,"f":86},"d":[198]},"a":"yellow","g":"violet","b":1,"d":-27,"f":"orange"},"f":{"e":20,"c":{"e":155,"c":{"c":[181,{"e":-32,"a":"orange","d":"orange","j":"yellow","c":66,"h":-39,"b":"violet","g":"violet","f":"red","i":23},4,"blue",70,"violet","blue",141,{"a":"yellow","b":184},"violet"],"a":160,"b":158,"d":197},"a":138,"g":[48],"b":26,"d":11,"f":{"c":"yellow","a":179,"b":"red","d":90}},"a":148,"g":"yellow","b":[[{"a":["yellow"]},"yellow",19,"green",39],{"c":{"a":"blue"},"a":{"e":41,"c":191,"a":173,"b":"green","d":-14,"f":19},"b":{"a":["orange",4,48],"b":193},"d":"green"},["yellow",{"e":"orange","a":"orange","d":"blue","c":-39,"h":28,"b":"yellow","g":"red","f":"orange","i":[116,"red",173,76,24,-1,"green",101,-10]},70,{"c":"violet","a":44,"b":"violet","d":36},128,{"c":"yellow","a":"red","b":["yellow",-10]},-10,6]],"d":"violet","f":{"e":"violet","c":5,"a":"violet","g":173,"b":100,"d":["violet",194,{"e":["blue",181,"violet","yellow","blue",-7,137,43,112],"c":-19,"a":120,"b":"green","d":165},-1,195,"green",104],"f":128}}}} diff --git a/12/main.py b/12/main.py new file mode 100755 index 0000000..0887e88 --- /dev/null +++ b/12/main.py @@ -0,0 +1,41 @@ +#!/usr/bin/python + +import json + + + +def solve_partn(partn, data): + # Primitive data types + if isinstance(data, int) or isinstance(data, float): + return data + elif isinstance(data, str): + return 0 + + # Composite data types + result = 0 + if isinstance(data, list): + for d in data: + result += solve_partn(partn, d) + elif isinstance(data, dict): + for d in data.values(): + # Part 2: skip all objects containing "red" as value + if partn == 2 and isinstance(d, str) and d == "red": + return 0 + else: + result += solve_partn(partn, d) + return result + + + +def main(): + # Read the JSON data from the input text file + with open("input.txt", "r") as f: + data = json.loads(f.read()) + + print("Part 1 solution:", solve_partn(1, data)) # 119433 for me + print("Part 2 solution:", solve_partn(2, data)) # 68466 for me + + + +if __name__ == "__main__": + main() diff --git a/12/test.py b/12/test.py new file mode 100755 index 0000000..c4a2672 --- /dev/null +++ b/12/test.py @@ -0,0 +1,65 @@ +#!/usr/bin/python + +import json +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + data = json.loads('[1,2,3]') + self.assertEqual(main.solve_partn(1, data), 6) + + def test_example2(self): + data = json.loads('{"a":2,"b":4}') + self.assertEqual(main.solve_partn(1, data), 6) + + def test_example3(self): + data = json.loads('[[[3]]]') + self.assertEqual(main.solve_partn(1, data), 3) + + def test_example4(self): + data = json.loads('{"a":{"b":4},"c":-1}') + self.assertEqual(main.solve_partn(1, data), 3) + + def test_example5(self): + data = json.loads('{"a":[-1,1]}') + self.assertEqual(main.solve_partn(1, data), 0) + + def test_example6(self): + data = json.loads('[-1,{"a":1}]') + self.assertEqual(main.solve_partn(1, data), 0) + + def test_example7(self): + data = json.loads('[]') + self.assertEqual(main.solve_partn(1, data), 0) + + def test_example8(self): + data = json.loads('{}') + self.assertEqual(main.solve_partn(1, data), 0) + + + +class ExamplesPart2(unittest.TestCase): + def test_example1(self): + data = json.loads('[1,2,3]') + self.assertEqual(main.solve_partn(2, data), 6) + + def test_example2(self): + data = json.loads('[1,{"c":"red","b":2},3]') + self.assertEqual(main.solve_partn(2, data), 4) + + def test_example3(self): + data = json.loads('{"d":"red","e":[1,2,3,4],"f":5}') + self.assertEqual(main.solve_partn(2, data), 0) + + def test_example4(self): + data = json.loads('[1,"red",5]') + self.assertEqual(main.solve_partn(2, data), 6) + + + +if __name__ == "__main__": + unittest.main() diff --git a/13/input.txt b/13/input.txt new file mode 100644 index 0000000..35be357 --- /dev/null +++ b/13/input.txt @@ -0,0 +1,56 @@ +Alice would gain 54 happiness units by sitting next to Bob. +Alice would lose 81 happiness units by sitting next to Carol. +Alice would lose 42 happiness units by sitting next to David. +Alice would gain 89 happiness units by sitting next to Eric. +Alice would lose 89 happiness units by sitting next to Frank. +Alice would gain 97 happiness units by sitting next to George. +Alice would lose 94 happiness units by sitting next to Mallory. +Bob would gain 3 happiness units by sitting next to Alice. +Bob would lose 70 happiness units by sitting next to Carol. +Bob would lose 31 happiness units by sitting next to David. +Bob would gain 72 happiness units by sitting next to Eric. +Bob would lose 25 happiness units by sitting next to Frank. +Bob would lose 95 happiness units by sitting next to George. +Bob would gain 11 happiness units by sitting next to Mallory. +Carol would lose 83 happiness units by sitting next to Alice. +Carol would gain 8 happiness units by sitting next to Bob. +Carol would gain 35 happiness units by sitting next to David. +Carol would gain 10 happiness units by sitting next to Eric. +Carol would gain 61 happiness units by sitting next to Frank. +Carol would gain 10 happiness units by sitting next to George. +Carol would gain 29 happiness units by sitting next to Mallory. +David would gain 67 happiness units by sitting next to Alice. +David would gain 25 happiness units by sitting next to Bob. +David would gain 48 happiness units by sitting next to Carol. +David would lose 65 happiness units by sitting next to Eric. +David would gain 8 happiness units by sitting next to Frank. +David would gain 84 happiness units by sitting next to George. +David would gain 9 happiness units by sitting next to Mallory. +Eric would lose 51 happiness units by sitting next to Alice. +Eric would lose 39 happiness units by sitting next to Bob. +Eric would gain 84 happiness units by sitting next to Carol. +Eric would lose 98 happiness units by sitting next to David. +Eric would lose 20 happiness units by sitting next to Frank. +Eric would lose 6 happiness units by sitting next to George. +Eric would gain 60 happiness units by sitting next to Mallory. +Frank would gain 51 happiness units by sitting next to Alice. +Frank would gain 79 happiness units by sitting next to Bob. +Frank would gain 88 happiness units by sitting next to Carol. +Frank would gain 33 happiness units by sitting next to David. +Frank would gain 43 happiness units by sitting next to Eric. +Frank would gain 77 happiness units by sitting next to George. +Frank would lose 3 happiness units by sitting next to Mallory. +George would lose 14 happiness units by sitting next to Alice. +George would lose 12 happiness units by sitting next to Bob. +George would lose 52 happiness units by sitting next to Carol. +George would gain 14 happiness units by sitting next to David. +George would lose 62 happiness units by sitting next to Eric. +George would lose 18 happiness units by sitting next to Frank. +George would lose 17 happiness units by sitting next to Mallory. +Mallory would lose 36 happiness units by sitting next to Alice. +Mallory would gain 76 happiness units by sitting next to Bob. +Mallory would lose 34 happiness units by sitting next to Carol. +Mallory would gain 37 happiness units by sitting next to David. +Mallory would gain 40 happiness units by sitting next to Eric. +Mallory would gain 18 happiness units by sitting next to Frank. +Mallory would gain 7 happiness units by sitting next to George. diff --git a/13/main.py b/13/main.py new file mode 100755 index 0000000..31bd337 --- /dev/null +++ b/13/main.py @@ -0,0 +1,72 @@ +#!/usr/bin/python + +from itertools import permutations + + + +def parse_input(lines): + data = {} + + for l in lines: + words = l.split() + name1 = words[ 0] + name2 = words[10].rstrip(".") + if words[2] == "gain": + score = int(words[3]) + else: # words[2] == "lose" + score = -int(words[3]) + + if name1 not in data: + data[name1] = {} + data[name1][name2] = score + + return data + + + +def best_score(data): + names = list(data.keys()) + perms = permutations(names) + scores = [] + for p in perms: + score = 0 + for i in range(len(p)): + n1 = p[i] + n2 = p[(i + 1) % len(p)] + score += data[n1][n2] + data[n2][n1] + scores.append(score) + return max(scores) + + + +def solve_part1(lines): + data = parse_input(lines) + return best_score(data) + + + +def solve_part2(lines): + data = parse_input(lines) + + data["Myself"] = {} + names = list(data.keys()) + for n in names: + data["Myself"][n] = 0 + data[n]["Myself"] = 0 + + return best_score(data) + + + +def main(): + # Read happiness relations from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_part1(lines)) # 709 for me + print("Part 2 solution:", solve_part2(lines)) # 668 for me + + + +if __name__ == "__main__": + main() diff --git a/13/test.py b/13/test.py new file mode 100755 index 0000000..7600159 --- /dev/null +++ b/13/test.py @@ -0,0 +1,30 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + lines = [ + "Alice would gain 54 happiness units by sitting next to Bob.", + "Alice would lose 79 happiness units by sitting next to Carol.", + "Alice would lose 2 happiness units by sitting next to David.", + "Bob would gain 83 happiness units by sitting next to Alice.", + "Bob would lose 7 happiness units by sitting next to Carol.", + "Bob would lose 63 happiness units by sitting next to David.", + "Carol would lose 62 happiness units by sitting next to Alice.", + "Carol would gain 60 happiness units by sitting next to Bob.", + "Carol would gain 55 happiness units by sitting next to David.", + "David would gain 46 happiness units by sitting next to Alice.", + "David would lose 7 happiness units by sitting next to Bob.", + "David would gain 41 happiness units by sitting next to Carol." + ] + self.assertEqual(main.solve_part1(lines), 330) + + + +if __name__ == "__main__": + unittest.main() diff --git a/14/input.txt b/14/input.txt new file mode 100644 index 0000000..6cf5489 --- /dev/null +++ b/14/input.txt @@ -0,0 +1,9 @@ +Dancer can fly 27 km/s for 5 seconds, but then must rest for 132 seconds. +Cupid can fly 22 km/s for 2 seconds, but then must rest for 41 seconds. +Rudolph can fly 11 km/s for 5 seconds, but then must rest for 48 seconds. +Donner can fly 28 km/s for 5 seconds, but then must rest for 134 seconds. +Dasher can fly 4 km/s for 16 seconds, but then must rest for 55 seconds. +Blitzen can fly 14 km/s for 3 seconds, but then must rest for 38 seconds. +Prancer can fly 3 km/s for 21 seconds, but then must rest for 40 seconds. +Comet can fly 18 km/s for 6 seconds, but then must rest for 103 seconds. +Vixen can fly 18 km/s for 5 seconds, but then must rest for 84 seconds. diff --git a/14/main.py b/14/main.py new file mode 100755 index 0000000..4af4940 --- /dev/null +++ b/14/main.py @@ -0,0 +1,75 @@ +#!/usr/bin/python + + + +class Reindeer: + pass + + + +def parse_input(lines): + result = [] + for line in lines: + words = line.split() + + r = Reindeer() + r.name = words[0] + r.dist = 0 + r.score = 0 + r.state = "moving" + r.speed = int(words[ 3]) + r.tmove = int(words[ 6]) + r.trest = int(words[13]) + r.timer = 0 + + result.append(r) + + return result + + + +def solve_partn(partn, lines, tmax): + contestants = parse_input(lines) + + for t in range(tmax): + for r in contestants: + if r.state == "moving": + r.dist += r.speed + r.timer += 1 + if r.timer >= r.tmove: + r.state = "resting" + r.timer = 0 + else: # r.state == "resting" + r.timer += 1 + if r.timer >= r.trest: + r.state = "moving" + r.timer = 0 + + # Award 1 point to leader (and to others in case of a tie) + # Only for part 2, but doesn't hurt part 1, so not disabled. + leader = max(contestants, key = lambda r: r.dist) + for r in contestants: + if r.dist == leader.dist: + r.score += 1 + + if partn == 1: + winner = max(contestants, key = lambda r: r.dist) + return winner.dist + else: # partn == 2 + winner = max(contestants, key = lambda r: r.score) + return winner.score + + + +def main(): + # Read reindeer stats from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_partn(1, lines, 2503)) # 2640 for me + print("Part 2 solution:", solve_partn(2, lines, 2503)) # 1102 for me + + + +if __name__ == "__main__": + main() diff --git a/14/test.py b/14/test.py new file mode 100755 index 0000000..25012d4 --- /dev/null +++ b/14/test.py @@ -0,0 +1,21 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class Examples(unittest.TestCase): + def test_example1(self): + lines = [ + "Comet can fly 14 km/s for 10 seconds, but then must rest for 127 seconds.", + "Dancer can fly 16 km/s for 11 seconds, but then must rest for 162 seconds." + ] + self.assertEqual(main.solve_partn(1, lines, 1000), 1120) + self.assertEqual(main.solve_partn(2, lines, 1000), 689) + + + +if __name__ == "__main__": + unittest.main() diff --git a/15/input.txt b/15/input.txt new file mode 100644 index 0000000..d1af06e --- /dev/null +++ b/15/input.txt @@ -0,0 +1,4 @@ +Sugar: capacity 3, durability 0, flavor 0, texture -3, calories 2 +Sprinkles: capacity -3, durability 3, flavor 0, texture 0, calories 9 +Candy: capacity -1, durability 0, flavor 4, texture 0, calories 1 +Chocolate: capacity 0, durability 0, flavor -2, texture 2, calories 8 diff --git a/15/main.py b/15/main.py new file mode 100755 index 0000000..cb2077b --- /dev/null +++ b/15/main.py @@ -0,0 +1,78 @@ +#!/usr/bin/python + + + +def parse_input(lines): + ingredients = [] + + for l in lines: + words = l.split() + + # Rather than label the properties by name, we number them 0-4 + props = [] + for n in range(5): + props.append(int(words[2 + 2 * n].rstrip(","))) + + name = words[0].rstrip(":") + ingredients.append(props) + + return ingredients + + + +def all_recipes(ingredients): + recipes = {} + + for i1 in range(101): + for i2 in range(101 - i1): + for i3 in range(101 - i1 - i2): + i4 = 100 - i1 - i2 - i3 + amounts = [i1, i2, i3, i4] # amount of each ingredient + + props = [0, 0, 0, 0] # score for each property + for p in range(len(props)): + # Accumulate properties of ingredients + for i in range(len(amounts)): + prop = amounts[i] * ingredients[i][p] + props[p] += prop + # Clamp negative totals to zero + if props[p] < 0: + props[p] = 0 + + # `recipes' is a dictionary: key is recipe, value is total score + recipes[tuple(amounts)] = props[0] * props[1] * props[2] * props[3] + + return recipes + + + +def solve_partn(partn, lines): + ingredients = parse_input(lines) + recipes = all_recipes(ingredients) + + if partn == 2: + suitable = {} + for amounts, score in recipes.items(): + calories = 0 + for i in range(len(amounts)): + calories += amounts[i] * ingredients[i][4] + if calories == 500: + suitable[amounts] = score + recipes = suitable + + return max(recipes.values()) + + + +def main(): + # Read ingredient information from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_partn(1, lines)) # 222870 for me + print("Part 2 solution:", solve_partn(2, lines)) # 117936 for me + + + +if __name__ == "__main__": + main() diff --git a/15/test.py b/15/test.py new file mode 100755 index 0000000..fb71ad8 --- /dev/null +++ b/15/test.py @@ -0,0 +1,23 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class Examples(unittest.TestCase): + def test_example1(self): + lines = [ + "Butterscotch: capacity -1, durability -2, flavor 6, texture 3, calories 8", + "Cinnamon: capacity 2, durability 3, flavor -2, texture -1, calories 3", + "Dummy: capacity 0, durability 0, flavor 0, texture 0, calories 0", + "Dummy: capacity 0, durability 0, flavor 0, texture 0, calories 0" + ] + self.assertEqual(main.solve_partn(1, lines), 62842880) + self.assertEqual(main.solve_partn(2, lines), 57600000) + + + +if __name__ == "__main__": + unittest.main() diff --git a/16/input.txt b/16/input.txt new file mode 100644 index 0000000..b1bd498 --- /dev/null +++ b/16/input.txt @@ -0,0 +1,500 @@ +Sue 1: children: 1, cars: 8, vizslas: 7 +Sue 2: akitas: 10, perfumes: 10, children: 5 +Sue 3: cars: 5, pomeranians: 4, vizslas: 1 +Sue 4: goldfish: 5, children: 8, perfumes: 3 +Sue 5: vizslas: 2, akitas: 7, perfumes: 6 +Sue 6: vizslas: 0, akitas: 1, perfumes: 2 +Sue 7: perfumes: 8, cars: 4, goldfish: 10 +Sue 8: perfumes: 7, children: 2, cats: 1 +Sue 9: pomeranians: 3, goldfish: 10, trees: 10 +Sue 10: akitas: 7, trees: 8, pomeranians: 4 +Sue 11: goldfish: 1, perfumes: 4, cars: 6 +Sue 12: samoyeds: 6, trees: 6, perfumes: 2 +Sue 13: akitas: 10, pomeranians: 0, vizslas: 2 +Sue 14: cars: 2, perfumes: 3, children: 4 +Sue 15: goldfish: 2, children: 8, cars: 5 +Sue 16: goldfish: 9, cars: 0, vizslas: 5 +Sue 17: cats: 5, trees: 6, perfumes: 6 +Sue 18: cars: 0, perfumes: 8, pomeranians: 7 +Sue 19: trees: 2, goldfish: 5, perfumes: 4 +Sue 20: akitas: 4, vizslas: 4, trees: 0 +Sue 21: pomeranians: 7, trees: 0, goldfish: 10 +Sue 22: cars: 4, vizslas: 0, perfumes: 3 +Sue 23: vizslas: 8, trees: 1, akitas: 2 +Sue 24: children: 7, trees: 0, akitas: 1 +Sue 25: goldfish: 3, akitas: 2, trees: 2 +Sue 26: pomeranians: 4, vizslas: 4, samoyeds: 2 +Sue 27: cars: 0, trees: 8, akitas: 5 +Sue 28: perfumes: 6, cats: 0, cars: 2 +Sue 29: trees: 7, akitas: 1, vizslas: 1 +Sue 30: perfumes: 9, cars: 9, trees: 10 +Sue 31: pomeranians: 5, akitas: 9, samoyeds: 1 +Sue 32: pomeranians: 10, vizslas: 5, goldfish: 5 +Sue 33: vizslas: 2, akitas: 3, trees: 7 +Sue 34: goldfish: 10, perfumes: 0, samoyeds: 7 +Sue 35: akitas: 6, cats: 7, perfumes: 10 +Sue 36: pomeranians: 8, vizslas: 7, akitas: 6 +Sue 37: goldfish: 2, cars: 10, children: 7 +Sue 38: goldfish: 2, perfumes: 3, cars: 7 +Sue 39: trees: 9, vizslas: 10, cars: 5 +Sue 40: goldfish: 1, pomeranians: 0, trees: 2 +Sue 41: trees: 2, goldfish: 6, vizslas: 3 +Sue 42: akitas: 1, cars: 3, vizslas: 3 +Sue 43: akitas: 1, pomeranians: 1, vizslas: 3 +Sue 44: goldfish: 7, akitas: 3, vizslas: 10 +Sue 45: akitas: 8, samoyeds: 8, goldfish: 2 +Sue 46: trees: 0, vizslas: 4, cars: 9 +Sue 47: cars: 9, trees: 10, perfumes: 4 +Sue 48: akitas: 0, vizslas: 5, perfumes: 4 +Sue 49: goldfish: 9, trees: 1, cars: 4 +Sue 50: goldfish: 2, perfumes: 5, cars: 2 +Sue 51: samoyeds: 1, goldfish: 2, perfumes: 7 +Sue 52: cars: 0, perfumes: 4, goldfish: 8 +Sue 53: goldfish: 9, vizslas: 2, akitas: 9 +Sue 54: trees: 1, goldfish: 9, children: 5 +Sue 55: cars: 0, akitas: 5, trees: 4 +Sue 56: trees: 4, samoyeds: 5, children: 9 +Sue 57: children: 0, vizslas: 8, cars: 3 +Sue 58: trees: 4, pomeranians: 5, akitas: 5 +Sue 59: vizslas: 10, cats: 3, children: 2 +Sue 60: cats: 6, vizslas: 2, cars: 2 +Sue 61: akitas: 1, vizslas: 0, children: 4 +Sue 62: akitas: 4, trees: 9, children: 10 +Sue 63: pomeranians: 6, vizslas: 6, cars: 4 +Sue 64: perfumes: 8, pomeranians: 1, children: 8 +Sue 65: perfumes: 3, goldfish: 6, trees: 5 +Sue 66: goldfish: 10, akitas: 8, vizslas: 4 +Sue 67: vizslas: 10, samoyeds: 3, trees: 2 +Sue 68: samoyeds: 4, cars: 7, perfumes: 3 +Sue 69: perfumes: 2, goldfish: 0, trees: 2 +Sue 70: trees: 8, vizslas: 7, akitas: 6 +Sue 71: cars: 2, children: 7, perfumes: 3 +Sue 72: cars: 1, akitas: 9, perfumes: 0 +Sue 73: vizslas: 4, akitas: 7, cars: 5 +Sue 74: samoyeds: 3, cars: 3, akitas: 2 +Sue 75: trees: 2, cars: 1, vizslas: 7 +Sue 76: samoyeds: 9, perfumes: 1, trees: 6 +Sue 77: trees: 6, perfumes: 10, cars: 7 +Sue 78: trees: 0, children: 8, vizslas: 5 +Sue 79: vizslas: 0, trees: 0, samoyeds: 1 +Sue 80: trees: 6, goldfish: 8, perfumes: 0 +Sue 81: samoyeds: 8, pomeranians: 6, akitas: 5 +Sue 82: vizslas: 6, perfumes: 9, akitas: 4 +Sue 83: cats: 0, vizslas: 3, pomeranians: 10 +Sue 84: cars: 4, perfumes: 6, samoyeds: 5 +Sue 85: vizslas: 7, trees: 5, goldfish: 7 +Sue 86: goldfish: 2, trees: 2, vizslas: 1 +Sue 87: trees: 6, goldfish: 10, pomeranians: 4 +Sue 88: vizslas: 1, akitas: 0, perfumes: 8 +Sue 89: goldfish: 8, akitas: 3, vizslas: 7 +Sue 90: vizslas: 9, akitas: 7, perfumes: 9 +Sue 91: children: 7, cars: 7, trees: 9 +Sue 92: vizslas: 10, akitas: 8, goldfish: 1 +Sue 93: goldfish: 7, vizslas: 2, pomeranians: 0 +Sue 94: cats: 2, samoyeds: 6, pomeranians: 3 +Sue 95: samoyeds: 4, children: 4, pomeranians: 10 +Sue 96: pomeranians: 9, cats: 1, goldfish: 3 +Sue 97: trees: 1, akitas: 6, goldfish: 1 +Sue 98: vizslas: 7, akitas: 2, perfumes: 7 +Sue 99: pomeranians: 6, perfumes: 2, trees: 1 +Sue 100: cars: 3, children: 9, trees: 10 +Sue 101: children: 0, perfumes: 0, vizslas: 3 +Sue 102: cars: 4, goldfish: 5, children: 2 +Sue 103: pomeranians: 3, perfumes: 7, cats: 8 +Sue 104: akitas: 0, perfumes: 5, vizslas: 5 +Sue 105: akitas: 7, vizslas: 2, samoyeds: 8 +Sue 106: goldfish: 7, perfumes: 0, cats: 8 +Sue 107: cats: 6, pomeranians: 9, cars: 6 +Sue 108: akitas: 3, vizslas: 10, cats: 5 +Sue 109: akitas: 10, perfumes: 2, cars: 7 +Sue 110: goldfish: 7, pomeranians: 1, trees: 1 +Sue 111: akitas: 10, samoyeds: 6, vizslas: 6 +Sue 112: cats: 6, akitas: 7, trees: 9 +Sue 113: akitas: 1, trees: 9, vizslas: 8 +Sue 114: vizslas: 2, cats: 1, cars: 4 +Sue 115: akitas: 0, trees: 5, goldfish: 7 +Sue 116: goldfish: 2, trees: 10, akitas: 2 +Sue 117: cars: 4, goldfish: 10, perfumes: 5 +Sue 118: cars: 5, perfumes: 6, trees: 0 +Sue 119: perfumes: 5, vizslas: 1, cats: 0 +Sue 120: perfumes: 8, akitas: 9, vizslas: 4 +Sue 121: samoyeds: 2, vizslas: 7, perfumes: 6 +Sue 122: children: 6, trees: 9, perfumes: 2 +Sue 123: cars: 7, akitas: 0, pomeranians: 0 +Sue 124: akitas: 7, cats: 8, vizslas: 5 +Sue 125: goldfish: 3, trees: 1, cars: 4 +Sue 126: cars: 4, perfumes: 3, akitas: 0 +Sue 127: children: 10, vizslas: 5, akitas: 9 +Sue 128: akitas: 3, samoyeds: 2, cats: 8 +Sue 129: cats: 8, akitas: 1, vizslas: 8 +Sue 130: trees: 4, cars: 6, perfumes: 6 +Sue 131: akitas: 7, perfumes: 6, goldfish: 9 +Sue 132: akitas: 6, vizslas: 7, trees: 1 +Sue 133: akitas: 5, vizslas: 7, children: 9 +Sue 134: cars: 8, goldfish: 4, pomeranians: 4 +Sue 135: samoyeds: 1, pomeranians: 6, akitas: 4 +Sue 136: perfumes: 10, goldfish: 1, cars: 3 +Sue 137: cars: 3, samoyeds: 6, vizslas: 7 +Sue 138: samoyeds: 10, akitas: 3, perfumes: 4 +Sue 139: perfumes: 10, vizslas: 2, goldfish: 7 +Sue 140: samoyeds: 7, cars: 1, trees: 2 +Sue 141: children: 6, cats: 5, cars: 9 +Sue 142: cats: 0, trees: 1, akitas: 10 +Sue 143: samoyeds: 4, cars: 0, children: 7 +Sue 144: trees: 0, cars: 4, perfumes: 8 +Sue 145: goldfish: 7, cars: 5, trees: 1 +Sue 146: perfumes: 7, cars: 7, goldfish: 0 +Sue 147: trees: 2, goldfish: 7, vizslas: 5 +Sue 148: samoyeds: 8, perfumes: 1, trees: 0 +Sue 149: vizslas: 2, samoyeds: 5, trees: 0 +Sue 150: akitas: 4, perfumes: 4, pomeranians: 2 +Sue 151: trees: 2, cars: 0, goldfish: 10 +Sue 152: goldfish: 7, vizslas: 0, trees: 0 +Sue 153: children: 9, cats: 0, pomeranians: 10 +Sue 154: cars: 6, goldfish: 10, akitas: 5 +Sue 155: perfumes: 9, trees: 2, akitas: 3 +Sue 156: pomeranians: 9, perfumes: 5, cars: 9 +Sue 157: akitas: 0, trees: 2, cars: 7 +Sue 158: goldfish: 10, trees: 8, akitas: 7 +Sue 159: akitas: 5, trees: 10, cars: 10 +Sue 160: akitas: 3, trees: 5, cars: 8 +Sue 161: samoyeds: 2, cars: 7, perfumes: 4 +Sue 162: cars: 6, vizslas: 10, pomeranians: 5 +Sue 163: cars: 10, perfumes: 6, vizslas: 9 +Sue 164: pomeranians: 7, cars: 4, vizslas: 2 +Sue 165: goldfish: 9, vizslas: 3, trees: 1 +Sue 166: goldfish: 1, samoyeds: 3, trees: 1 +Sue 167: vizslas: 4, goldfish: 7, cats: 5 +Sue 168: children: 1, cars: 5, samoyeds: 7 +Sue 169: trees: 1, samoyeds: 3, goldfish: 6 +Sue 170: goldfish: 2, cars: 3, perfumes: 9 +Sue 171: cars: 4, goldfish: 0, trees: 6 +Sue 172: cats: 8, perfumes: 6, trees: 1 +Sue 173: akitas: 9, goldfish: 7, cars: 10 +Sue 174: vizslas: 2, trees: 0, akitas: 1 +Sue 175: perfumes: 3, vizslas: 8, akitas: 4 +Sue 176: perfumes: 0, akitas: 6, goldfish: 3 +Sue 177: perfumes: 6, children: 1, goldfish: 10 +Sue 178: cars: 5, vizslas: 3, children: 10 +Sue 179: perfumes: 3, trees: 8, cats: 9 +Sue 180: perfumes: 8, vizslas: 4, trees: 7 +Sue 181: perfumes: 7, vizslas: 9, samoyeds: 4 +Sue 182: vizslas: 9, trees: 4, pomeranians: 4 +Sue 183: trees: 9, cars: 3, goldfish: 5 +Sue 184: perfumes: 2, cars: 4, vizslas: 3 +Sue 185: children: 10, akitas: 10, cats: 9 +Sue 186: cars: 5, samoyeds: 0, trees: 0 +Sue 187: trees: 2, goldfish: 3, cars: 4 +Sue 188: goldfish: 3, vizslas: 1, cats: 6 +Sue 189: trees: 2, pomeranians: 10, cars: 7 +Sue 190: perfumes: 10, akitas: 3, samoyeds: 0 +Sue 191: cats: 5, vizslas: 6, akitas: 6 +Sue 192: samoyeds: 5, trees: 1, perfumes: 8 +Sue 193: pomeranians: 0, akitas: 9, cats: 0 +Sue 194: trees: 1, goldfish: 0, perfumes: 10 +Sue 195: perfumes: 2, akitas: 7, cars: 5 +Sue 196: perfumes: 5, samoyeds: 8, cars: 1 +Sue 197: vizslas: 2, pomeranians: 9, trees: 1 +Sue 198: trees: 8, vizslas: 6, children: 8 +Sue 199: pomeranians: 4, cars: 7, vizslas: 5 +Sue 200: trees: 0, perfumes: 10, akitas: 10 +Sue 201: cats: 9, akitas: 4, vizslas: 0 +Sue 202: goldfish: 9, pomeranians: 9, cats: 6 +Sue 203: cars: 5, perfumes: 5, trees: 2 +Sue 204: pomeranians: 7, children: 2, akitas: 6 +Sue 205: samoyeds: 7, pomeranians: 7, children: 6 +Sue 206: trees: 1, cars: 1, pomeranians: 4 +Sue 207: goldfish: 2, perfumes: 5, trees: 0 +Sue 208: perfumes: 2, samoyeds: 4, trees: 1 +Sue 209: cars: 8, perfumes: 6, goldfish: 9 +Sue 210: perfumes: 4, cars: 8, samoyeds: 3 +Sue 211: perfumes: 2, cars: 8, trees: 9 +Sue 212: trees: 7, perfumes: 2, akitas: 5 +Sue 213: children: 3, goldfish: 5, vizslas: 0 +Sue 214: akitas: 6, goldfish: 0, children: 0 +Sue 215: trees: 8, akitas: 3, goldfish: 1 +Sue 216: goldfish: 6, perfumes: 8, akitas: 3 +Sue 217: children: 7, trees: 2, vizslas: 6 +Sue 218: goldfish: 8, samoyeds: 4, pomeranians: 6 +Sue 219: goldfish: 8, samoyeds: 0, children: 9 +Sue 220: perfumes: 1, cars: 8, vizslas: 6 +Sue 221: perfumes: 9, cars: 10, children: 10 +Sue 222: perfumes: 9, vizslas: 1, trees: 0 +Sue 223: goldfish: 1, akitas: 2, vizslas: 8 +Sue 224: samoyeds: 8, akitas: 7, vizslas: 4 +Sue 225: goldfish: 1, cars: 4, perfumes: 10 +Sue 226: goldfish: 9, trees: 4, perfumes: 5 +Sue 227: vizslas: 5, trees: 4, goldfish: 7 +Sue 228: cars: 1, cats: 10, perfumes: 4 +Sue 229: vizslas: 8, cars: 10, akitas: 4 +Sue 230: cats: 1, children: 8, vizslas: 3 +Sue 231: perfumes: 7, cats: 6, samoyeds: 7 +Sue 232: cars: 3, children: 9, perfumes: 7 +Sue 233: vizslas: 1, samoyeds: 2, children: 2 +Sue 234: trees: 1, samoyeds: 8, children: 2 +Sue 235: trees: 6, akitas: 9, goldfish: 7 +Sue 236: children: 10, trees: 0, samoyeds: 8 +Sue 237: pomeranians: 4, trees: 1, goldfish: 2 +Sue 238: vizslas: 4, akitas: 2, cars: 0 +Sue 239: goldfish: 9, cars: 10, perfumes: 4 +Sue 240: perfumes: 3, vizslas: 6, trees: 6 +Sue 241: pomeranians: 6, akitas: 4, trees: 2 +Sue 242: cars: 8, perfumes: 5, children: 7 +Sue 243: trees: 4, perfumes: 7, cars: 3 +Sue 244: perfumes: 6, akitas: 1, vizslas: 7 +Sue 245: akitas: 3, perfumes: 9, samoyeds: 0 +Sue 246: pomeranians: 3, vizslas: 9, samoyeds: 1 +Sue 247: cars: 0, goldfish: 7, cats: 2 +Sue 248: trees: 5, goldfish: 6, perfumes: 3 +Sue 249: trees: 0, pomeranians: 7, perfumes: 9 +Sue 250: cars: 9, trees: 1, goldfish: 10 +Sue 251: perfumes: 3, cars: 8, trees: 7 +Sue 252: cars: 5, akitas: 7, trees: 8 +Sue 253: perfumes: 7, akitas: 3, trees: 8 +Sue 254: goldfish: 8, samoyeds: 1, vizslas: 7 +Sue 255: perfumes: 3, cars: 4, children: 6 +Sue 256: perfumes: 9, trees: 8, children: 7 +Sue 257: trees: 8, children: 6, cars: 4 +Sue 258: vizslas: 1, trees: 10, goldfish: 9 +Sue 259: vizslas: 5, trees: 6, goldfish: 9 +Sue 260: trees: 0, goldfish: 6, cars: 7 +Sue 261: cars: 1, perfumes: 4, goldfish: 9 +Sue 262: cars: 7, goldfish: 9, cats: 9 +Sue 263: cars: 0, children: 5, goldfish: 8 +Sue 264: cars: 2, akitas: 8, trees: 0 +Sue 265: perfumes: 9, children: 8, samoyeds: 7 +Sue 266: cats: 1, children: 1, vizslas: 10 +Sue 267: vizslas: 8, children: 2, trees: 6 +Sue 268: akitas: 10, vizslas: 3, cats: 2 +Sue 269: children: 4, goldfish: 1, cats: 6 +Sue 270: vizslas: 5, cars: 9, akitas: 9 +Sue 271: vizslas: 5, children: 4, akitas: 3 +Sue 272: cars: 1, goldfish: 0, vizslas: 0 +Sue 273: goldfish: 10, samoyeds: 1, akitas: 2 +Sue 274: goldfish: 10, children: 2, pomeranians: 0 +Sue 275: children: 0, vizslas: 1, samoyeds: 6 +Sue 276: children: 1, vizslas: 3, samoyeds: 1 +Sue 277: perfumes: 4, cats: 6, children: 10 +Sue 278: pomeranians: 7, goldfish: 3, cars: 4 +Sue 279: perfumes: 5, goldfish: 9, trees: 7 +Sue 280: goldfish: 6, trees: 5, perfumes: 8 +Sue 281: cars: 2, akitas: 1, vizslas: 7 +Sue 282: vizslas: 4, akitas: 3, children: 8 +Sue 283: pomeranians: 8, akitas: 9, vizslas: 4 +Sue 284: samoyeds: 10, trees: 10, pomeranians: 2 +Sue 285: akitas: 9, perfumes: 7, goldfish: 6 +Sue 286: akitas: 2, vizslas: 7, goldfish: 10 +Sue 287: pomeranians: 8, cars: 6, samoyeds: 5 +Sue 288: pomeranians: 1, trees: 0, goldfish: 0 +Sue 289: trees: 10, samoyeds: 1, children: 0 +Sue 290: cats: 10, samoyeds: 6, trees: 0 +Sue 291: vizslas: 9, trees: 6, goldfish: 5 +Sue 292: cats: 4, perfumes: 8, cars: 3 +Sue 293: goldfish: 10, perfumes: 10, cats: 0 +Sue 294: cats: 7, trees: 6, akitas: 4 +Sue 295: vizslas: 8, cars: 1, akitas: 6 +Sue 296: vizslas: 5, akitas: 10, trees: 1 +Sue 297: pomeranians: 8, samoyeds: 5, vizslas: 4 +Sue 298: perfumes: 10, children: 5, vizslas: 2 +Sue 299: cars: 10, akitas: 7, cats: 5 +Sue 300: trees: 1, perfumes: 7, cars: 7 +Sue 301: cars: 9, vizslas: 1, perfumes: 3 +Sue 302: perfumes: 9, vizslas: 1, akitas: 5 +Sue 303: akitas: 9, trees: 1, goldfish: 10 +Sue 304: children: 10, vizslas: 6, pomeranians: 8 +Sue 305: trees: 3, goldfish: 6, cats: 9 +Sue 306: cars: 5, perfumes: 9, vizslas: 5 +Sue 307: children: 0, goldfish: 7, trees: 2 +Sue 308: trees: 9, samoyeds: 4, cars: 0 +Sue 309: cats: 8, vizslas: 2, perfumes: 3 +Sue 310: cars: 6, pomeranians: 6, vizslas: 6 +Sue 311: vizslas: 6, akitas: 7, cats: 10 +Sue 312: trees: 0, goldfish: 7, cars: 0 +Sue 313: perfumes: 5, akitas: 5, cars: 2 +Sue 314: akitas: 10, vizslas: 3, samoyeds: 8 +Sue 315: cars: 3, perfumes: 1, goldfish: 8 +Sue 316: pomeranians: 6, goldfish: 9, perfumes: 1 +Sue 317: goldfish: 4, akitas: 6, cars: 2 +Sue 318: perfumes: 8, vizslas: 8, akitas: 0 +Sue 319: akitas: 10, cars: 5, vizslas: 6 +Sue 320: vizslas: 4, akitas: 3, cats: 4 +Sue 321: goldfish: 4, akitas: 8, cars: 8 +Sue 322: pomeranians: 5, vizslas: 7, cats: 1 +Sue 323: perfumes: 1, trees: 6, goldfish: 0 +Sue 324: goldfish: 6, trees: 10, cars: 10 +Sue 325: akitas: 2, samoyeds: 6, trees: 9 +Sue 326: vizslas: 4, akitas: 7, cars: 9 +Sue 327: children: 3, perfumes: 4, cars: 1 +Sue 328: akitas: 9, perfumes: 6, cars: 10 +Sue 329: perfumes: 2, goldfish: 0, trees: 1 +Sue 330: vizslas: 10, pomeranians: 7, goldfish: 6 +Sue 331: trees: 3, vizslas: 8, cars: 3 +Sue 332: akitas: 2, cats: 1, goldfish: 8 +Sue 333: cars: 6, trees: 2, vizslas: 0 +Sue 334: samoyeds: 7, cars: 7, trees: 3 +Sue 335: cats: 7, children: 1, perfumes: 8 +Sue 336: akitas: 5, goldfish: 10, vizslas: 5 +Sue 337: cats: 3, vizslas: 0, akitas: 10 +Sue 338: perfumes: 8, cars: 1, trees: 8 +Sue 339: cars: 4, samoyeds: 8, children: 2 +Sue 340: goldfish: 9, pomeranians: 1, samoyeds: 1 +Sue 341: akitas: 3, trees: 0, goldfish: 2 +Sue 342: perfumes: 4, vizslas: 8, pomeranians: 9 +Sue 343: akitas: 4, cars: 5, goldfish: 4 +Sue 344: samoyeds: 5, cats: 4, trees: 0 +Sue 345: samoyeds: 4, cars: 8, akitas: 2 +Sue 346: akitas: 3, vizslas: 10, perfumes: 10 +Sue 347: goldfish: 10, akitas: 4, cars: 1 +Sue 348: perfumes: 10, cats: 4, vizslas: 5 +Sue 349: akitas: 2, vizslas: 4, cars: 7 +Sue 350: akitas: 5, vizslas: 5, cars: 6 +Sue 351: vizslas: 8, perfumes: 6, cars: 3 +Sue 352: cars: 10, vizslas: 0, goldfish: 10 +Sue 353: cars: 10, perfumes: 5, children: 7 +Sue 354: vizslas: 6, akitas: 3, samoyeds: 9 +Sue 355: akitas: 2, perfumes: 7, cars: 10 +Sue 356: cars: 10, perfumes: 7, children: 6 +Sue 357: akitas: 4, cars: 8, trees: 1 +Sue 358: trees: 2, cars: 1, goldfish: 2 +Sue 359: vizslas: 5, cars: 9, trees: 4 +Sue 360: perfumes: 4, akitas: 3, cars: 3 +Sue 361: children: 3, akitas: 2, cats: 5 +Sue 362: cars: 8, cats: 4, akitas: 10 +Sue 363: cats: 2, trees: 1, vizslas: 4 +Sue 364: vizslas: 2, pomeranians: 5, samoyeds: 9 +Sue 365: samoyeds: 2, akitas: 7, goldfish: 9 +Sue 366: goldfish: 8, trees: 7, cats: 2 +Sue 367: perfumes: 2, vizslas: 6, trees: 5 +Sue 368: cars: 5, samoyeds: 0, perfumes: 6 +Sue 369: samoyeds: 10, trees: 10, vizslas: 1 +Sue 370: trees: 2, vizslas: 3, cars: 4 +Sue 371: akitas: 6, pomeranians: 2, cats: 4 +Sue 372: trees: 2, perfumes: 3, goldfish: 9 +Sue 373: vizslas: 5, children: 0, pomeranians: 6 +Sue 374: trees: 1, vizslas: 8, perfumes: 10 +Sue 375: cars: 0, akitas: 6, children: 0 +Sue 376: akitas: 1, vizslas: 0, trees: 0 +Sue 377: samoyeds: 10, cats: 5, pomeranians: 0 +Sue 378: goldfish: 3, pomeranians: 7, cats: 7 +Sue 379: perfumes: 0, cats: 0, trees: 8 +Sue 380: perfumes: 4, samoyeds: 1, akitas: 7 +Sue 381: akitas: 4, pomeranians: 2, children: 4 +Sue 382: vizslas: 9, akitas: 4, trees: 10 +Sue 383: trees: 1, vizslas: 10, akitas: 6 +Sue 384: trees: 3, akitas: 8, goldfish: 3 +Sue 385: goldfish: 6, perfumes: 2, children: 9 +Sue 386: children: 10, akitas: 7, goldfish: 7 +Sue 387: goldfish: 3, vizslas: 10, perfumes: 5 +Sue 388: children: 4, trees: 0, cars: 2 +Sue 389: trees: 0, cats: 3, goldfish: 10 +Sue 390: samoyeds: 9, pomeranians: 0, cats: 6 +Sue 391: samoyeds: 10, trees: 3, akitas: 4 +Sue 392: akitas: 9, goldfish: 10, perfumes: 7 +Sue 393: goldfish: 6, cars: 2, akitas: 9 +Sue 394: trees: 4, goldfish: 9, vizslas: 7 +Sue 395: vizslas: 4, samoyeds: 1, goldfish: 6 +Sue 396: vizslas: 5, cats: 0, samoyeds: 1 +Sue 397: goldfish: 7, cats: 0, trees: 7 +Sue 398: cars: 10, akitas: 1, vizslas: 7 +Sue 399: samoyeds: 10, cats: 6, goldfish: 6 +Sue 400: cats: 6, samoyeds: 0, trees: 2 +Sue 401: trees: 1, children: 4, goldfish: 2 +Sue 402: cats: 8, vizslas: 4, children: 3 +Sue 403: cars: 9, perfumes: 8, pomeranians: 2 +Sue 404: goldfish: 8, trees: 2, cars: 5 +Sue 405: perfumes: 1, pomeranians: 5, vizslas: 5 +Sue 406: perfumes: 6, trees: 2, pomeranians: 6 +Sue 407: trees: 0, goldfish: 6, cars: 6 +Sue 408: trees: 0, samoyeds: 7, goldfish: 9 +Sue 409: samoyeds: 10, goldfish: 6, pomeranians: 0 +Sue 410: perfumes: 5, vizslas: 6, trees: 0 +Sue 411: goldfish: 2, trees: 2, pomeranians: 0 +Sue 412: pomeranians: 4, perfumes: 8, cats: 8 +Sue 413: vizslas: 4, cars: 5, akitas: 1 +Sue 414: perfumes: 2, trees: 8, goldfish: 7 +Sue 415: akitas: 3, trees: 1, perfumes: 3 +Sue 416: cars: 7, trees: 1, perfumes: 8 +Sue 417: cars: 5, goldfish: 5, trees: 1 +Sue 418: cars: 9, goldfish: 4, samoyeds: 2 +Sue 419: pomeranians: 8, akitas: 1, goldfish: 6 +Sue 420: cars: 0, cats: 0, children: 8 +Sue 421: akitas: 10, goldfish: 1, vizslas: 8 +Sue 422: children: 8, vizslas: 6, samoyeds: 10 +Sue 423: samoyeds: 3, goldfish: 10, vizslas: 8 +Sue 424: cars: 3, children: 7, goldfish: 4 +Sue 425: cars: 9, perfumes: 9, goldfish: 8 +Sue 426: akitas: 5, trees: 10, vizslas: 10 +Sue 427: vizslas: 10, cars: 3, akitas: 7 +Sue 428: cats: 6, perfumes: 5, goldfish: 10 +Sue 429: goldfish: 7, trees: 5, vizslas: 10 +Sue 430: perfumes: 3, trees: 7, cars: 3 +Sue 431: cars: 2, vizslas: 1, akitas: 6 +Sue 432: pomeranians: 8, perfumes: 5, cars: 3 +Sue 433: children: 8, cars: 0, perfumes: 7 +Sue 434: samoyeds: 0, vizslas: 9, akitas: 10 +Sue 435: akitas: 3, vizslas: 8, cats: 4 +Sue 436: goldfish: 5, trees: 8, samoyeds: 8 +Sue 437: cars: 10, samoyeds: 9, goldfish: 7 +Sue 438: samoyeds: 5, akitas: 7, perfumes: 9 +Sue 439: goldfish: 10, perfumes: 5, cars: 0 +Sue 440: pomeranians: 1, samoyeds: 9, children: 4 +Sue 441: vizslas: 4, perfumes: 2, cats: 5 +Sue 442: trees: 0, pomeranians: 3, cars: 7 +Sue 443: akitas: 0, cars: 2, vizslas: 10 +Sue 444: children: 1, akitas: 9, trees: 0 +Sue 445: cars: 5, perfumes: 7, goldfish: 9 +Sue 446: akitas: 0, perfumes: 1, vizslas: 2 +Sue 447: vizslas: 7, perfumes: 0, cars: 5 +Sue 448: vizslas: 6, goldfish: 10, trees: 0 +Sue 449: cars: 7, vizslas: 7, trees: 3 +Sue 450: pomeranians: 4, akitas: 4, vizslas: 8 +Sue 451: cats: 4, perfumes: 8, children: 3 +Sue 452: samoyeds: 8, akitas: 9, cars: 1 +Sue 453: cars: 8, akitas: 5, vizslas: 2 +Sue 454: vizslas: 9, perfumes: 4, akitas: 4 +Sue 455: akitas: 3, goldfish: 2, vizslas: 6 +Sue 456: cars: 4, perfumes: 5, goldfish: 10 +Sue 457: trees: 9, pomeranians: 4, goldfish: 10 +Sue 458: pomeranians: 1, perfumes: 9, children: 6 +Sue 459: samoyeds: 0, goldfish: 8, vizslas: 6 +Sue 460: cars: 10, goldfish: 8, samoyeds: 8 +Sue 461: akitas: 8, goldfish: 9, vizslas: 2 +Sue 462: cars: 1, vizslas: 2, akitas: 8 +Sue 463: goldfish: 2, akitas: 4, samoyeds: 10 +Sue 464: children: 5, perfumes: 5, cars: 5 +Sue 465: perfumes: 9, trees: 0, samoyeds: 6 +Sue 466: akitas: 5, goldfish: 3, cats: 6 +Sue 467: perfumes: 3, goldfish: 0, trees: 4 +Sue 468: goldfish: 2, children: 4, trees: 1 +Sue 469: cars: 0, perfumes: 8, children: 7 +Sue 470: vizslas: 8, cats: 5, samoyeds: 9 +Sue 471: pomeranians: 7, trees: 2, goldfish: 3 +Sue 472: goldfish: 8, akitas: 4, perfumes: 5 +Sue 473: perfumes: 2, pomeranians: 3, cars: 8 +Sue 474: samoyeds: 0, akitas: 7, pomeranians: 6 +Sue 475: vizslas: 7, perfumes: 1, trees: 6 +Sue 476: vizslas: 3, samoyeds: 1, perfumes: 10 +Sue 477: cars: 6, perfumes: 5, vizslas: 2 +Sue 478: pomeranians: 1, goldfish: 3, akitas: 7 +Sue 479: goldfish: 10, trees: 0, cars: 3 +Sue 480: cats: 3, akitas: 5, vizslas: 8 +Sue 481: pomeranians: 5, vizslas: 2, trees: 3 +Sue 482: cars: 8, samoyeds: 10, goldfish: 10 +Sue 483: pomeranians: 3, vizslas: 6, goldfish: 5 +Sue 484: perfumes: 7, vizslas: 4, akitas: 7 +Sue 485: goldfish: 1, trees: 0, perfumes: 10 +Sue 486: goldfish: 6, perfumes: 0, akitas: 10 +Sue 487: cats: 2, akitas: 10, trees: 1 +Sue 488: akitas: 1, goldfish: 3, cars: 7 +Sue 489: goldfish: 3, akitas: 6, vizslas: 6 +Sue 490: goldfish: 8, perfumes: 2, akitas: 2 +Sue 491: trees: 4, vizslas: 8, perfumes: 6 +Sue 492: cars: 9, perfumes: 3, cats: 0 +Sue 493: trees: 3, vizslas: 6, goldfish: 7 +Sue 494: trees: 8, samoyeds: 1, perfumes: 5 +Sue 495: children: 9, akitas: 8, vizslas: 4 +Sue 496: vizslas: 2, pomeranians: 1, perfumes: 7 +Sue 497: trees: 2, akitas: 4, vizslas: 6 +Sue 498: akitas: 8, pomeranians: 7, trees: 0 +Sue 499: perfumes: 6, goldfish: 3, vizslas: 7 +Sue 500: cars: 1, perfumes: 6, vizslas: 1 diff --git a/16/main.py b/16/main.py new file mode 100755 index 0000000..ce630a2 --- /dev/null +++ b/16/main.py @@ -0,0 +1,66 @@ +#!/usr/bin/python + + + +# Machine's readings given in puzzle text +readings = { + "children" : 3, + "cats" : 7, + "samoyeds" : 2, + "pomeranians" : 3, + "akitas" : 0, + "vizslas" : 0, + "goldfish" : 5, + "trees" : 3, + "cars" : 2, + "perfumes" : 1 +} + + + +def solve_partn(partn, lines): + # Parse input file into a list of dictionaries + aunts = [] + for line in lines: + words = line.split(" ") + + data = {} + for i in range(3): + key = words[2 + 2 * i].rstrip(":") + val = words[3 + 2 * i].rstrip(",") + data[key] = int(val) + + aunts.append(data) + + # Find the aunt who gave us the present + for i, a in enumerate(aunts): + is_target = True + for k in a.keys(): + if partn == 1: + is_target &= a[k] == readings[k] + else: # partn == 2 + if k == "cats" or k == "trees": + is_target &= a[k] > readings[k] + elif k == "pomeranians" or k == "goldfish": + is_target &= a[k] < readings[k] + else: + is_target &= a[k] == readings[k] + if is_target: + return i + 1 + + return -1 # Shouldn't happen + + + +def main(): + # Read properties of all Aunts Sue from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_partn(1, lines)) # 213 for me + print("Part 2 solution:", solve_partn(2, lines)) # 323 for me + + + +if __name__ == "__main__": + main() diff --git a/17/input.txt b/17/input.txt new file mode 100644 index 0000000..6b25a72 --- /dev/null +++ b/17/input.txt @@ -0,0 +1,20 @@ +33 +14 +18 +20 +45 +35 +16 +35 +1 +13 +18 +13 +50 +44 +48 +6 +24 +41 +30 +42 diff --git a/17/main.py b/17/main.py new file mode 100755 index 0000000..d301334 --- /dev/null +++ b/17/main.py @@ -0,0 +1,52 @@ +#!/usr/bin/python + + + +def find_combos(sizes, taken, avail, remaining): + result = set() + + # For each container we haven't used yet + for i in avail: + # If its capacity is less than what we need, recurse to find + # containers for the remaining liquid, which might not succeed. + if sizes[i] < remaining: + _taken = taken | {i} + _avail = avail - {i} + _remaining = remaining - sizes[i] + for c in find_combos(sizes, _taken, _avail, _remaining): + result |= {frozenset([i]) | c} + # If its capacity is exactly what we need, we've found an option + elif sizes[i] == remaining: + result |= {frozenset([i])} + # If its capacity is too large, this isn't an option; continue + + return result + + + +def solve_partn(partn, combos): + if partn == 1: + options = combos + else: # partn == 2 + lengths = map(len, combos) + min_len = min(lengths) + options = {c for c in combos if len(c) == min_len} + return len(options) + + + +def main(): + # Read container volumes from the input text file + with open("input.txt", "r") as f: + sizes = list(map(int, f.read().splitlines())) + + # Extremely expensive (takes several minutes), so do it once up front + combos = find_combos(sizes, set(), set(range(len(sizes))), 150) + + print("Part 1 solution:", solve_partn(1, combos)) # 1304 for me + print("Part 2 solution:", solve_partn(2, combos)) # 18 for me + + + +if __name__ == "__main__": + main() diff --git a/17/test.py b/17/test.py new file mode 100755 index 0000000..74943db --- /dev/null +++ b/17/test.py @@ -0,0 +1,19 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class Examples(unittest.TestCase): + def test_example1(self): + sizes = [20, 15, 10, 5, 5] + combos = main.find_combos(sizes, set(), set(range(len(sizes))), 25) + self.assertEqual(main.solve_partn(1, combos), 4) + self.assertEqual(main.solve_partn(2, combos), 3) + + + +if __name__ == "__main__": + unittest.main() diff --git a/18/input.txt b/18/input.txt new file mode 100644 index 0000000..e91a2a7 --- /dev/null +++ b/18/input.txt @@ -0,0 +1,100 @@ +###.##..##.#..#.##...#..#.####..#.##.##.##..###...#....#...###..#..###..###.#.#.#..#.##..#...##.#..# +.#...##.#####..##.......#..####.###.##.#..###.###.....#.#.####.##.###..##...###....#.##.....#.#.#.## +.....#.#.....#..###..####..#.....##.#..###.####.#.######..##......#####.#.##.#########.###..#.##.#.# +...###......#.#..###..#.#.....#.##..#.##..###...#.##.#..#..#.##.#..##......##.##.##.######...#....## +.###.....#...#.#...####.#.###..#..####.#..#.##..####...##.#...#..###...###...####..##....####.##..#. +..#....#...#.......#..###.###....#.##..#.....###.#.##.#....#.#....##.##..#.##.#..###.###.##.##..##.# +##..#####.#.#....#.#...#.#.####..#....#..#....#.#..#.#####...#..##.#.....#.##..##.####......#.#.##.. +.#..##..#.#.###..##..##...#....##...#..#.#..##.##..###.####.....#.####.#.....##.#.##...#..####..#... +#.#####.......#####...#...####.#.#.#....#.###.#.##.#####..#.###.#..##.##.#.##....#.##..#....####.#.# +#.##...#####....##.#.#.....##......##.##...#.##.##...##...###.###.##.#.####.####.##..#.##.#.#.####.. +#.##.##....###.###.#..#..##.##.#..#.#..##..#.#...#.##........###..#...##.#.#.##.......##.....#...### +###..#.#..##.##.#.#.#...#..#...##.##.#.########.......#.#...#....########..#.#.###..#.#..#.##..##### +####.#.#...#.##.##..#.#...#....#..###..#.#.#.####.#.##.##.#..##..##..#..#####.####.##..########..##. +.#.#...#..##.#..#..###.#..####.......##.#.#.#.##.#####..#..##...#.##...#..#....#..#..###..####.#.... +..#.#...#....##...#####..#..#...###.###.....#.###.#....#.#..##...#.##.##.####.#.#.#..#.##.#....#.#.. +#....###.####.##..#.#.###..###.##.##..#.#...###..#.##.#####.##.#######..#.#...##.#..........####.### +#.#####.#......#.#......#.....##...##.#.#########.#......##..##..##.#..##.##..#....##...###...#.#... +#..#..##..###.#.#.#.#.....###.#.####.##.##....#.#..##....#.#..#.####..###.##...#######.#####.##.#.#. +..###.#........##.#...###..#.##..#.#....##.#......#..#.##..#.#..#.#..#.####.#####..###.##..#.##.#... +##.###....#..##...#..#.#......##..#...#..#.####..#.##...##.####.#...#..###...#.#.#....###.##..#.#... +..##.##.#.##..##.#..#.###...##..##..#....##..##...####.#..####.###...#.....#..#.##..##..###..#.#...# +#.#....#.....#...##.#...####..#..##..##.####..##..##...####...#....##.#.#######..##.#......######.#. +#.#...###.######.######..##..##....#.#......#......#.#.##.#.##.#.#.#...#...#....#.#.#.#..#.##..#...# +####.###.#.#.##..#.##.#...#.##...#.##.##...#.....#.#..#.####.##..######.#..#.#..##....#.#.#..#.#.#.# +..##......#.#...#.##.##..##..##..#..##..#########.#..###..###.##...#..##.#..#.#.#.######..#....#.#.. +..##.##.#...###.#...##..######.##.#..####..#..#.#.##.####.##.##.#...##....#...###.##.####..#....#.#. +####...###..#.#.##.#.#....###..##.#.#..########..#...#.#...#.##....##.##...#.....#.#.....#.....#.... +.#.###############....#.##..###..#.####.#.##.##..#..#.#...###...##..##.##.#.....##...###.###.....#.. +.###..#..##.##..####.#.###.##.##..#..##....#.#......#......##.#...#.#...#..##.#.#...#...#.##..#.##.. +###.#.#.########.#.#..####.#..##.#.##.##.###.##..######...#..##.##.#..#.#...#.##..#####.....#.#.#..# +.##.##..#.#...#####.#.#.###...##...####...#......#...#..####..#.##..........#..#.#..###....######.## +..#####...#.#.#.#..#.##..#...#.#..#.##...##..##.##.#.##.#..#.#...#.......##.#...###.....#...#.#.#.## +##.##.#..######.##...#.....#.###.#..##.#.#.#..####.#....##.#....####...##....#.#.##.#..###.##.##..## +.###.##.#..#.###.####..#.##..####.#.#.##..###.#######.###.###...####........##....###.#...#.#.####.# +........#..#.#..##..########..........#.##.#..##.#...#.....####....##..#..#.#####.###...#...#.##.### +.....#..##.####...##.#####..######.##.#.###.####.##.##.#..##.##.######.##......#..#.####..##....#.## +##...####....#.##.##.###....#.#...#.####..##.#.##.#.#...####.#.#.#.#...##.###...##...###...######.## +.#....#.#.####...#.##.....##...###.#.#.##...##.#####....#.######.#.#....##..##...##....##.#.##.#.#.# +.###..###.#.......#.#######..#.#.#.######....#.#####.#.....#.#########...#....##...##.####.#..#..... +##.#..##..##.....#..##...#..##.##.#..#.#####.##.##.#.##.##...##.######.####..#.##..#####.##...##..#. +#.###...##.#.#.#.##....#.#.##.##..#....#...#.#.........#..#..####..####.####..#.##.##.#....####..##. +.#..######..#####.####.##.#.....#.#.#####..##..###.#.#.#..#.#...#.#######..##....##.##...#######..#. +#...#....#.#.##..#####..#########..#.....#...##.#.#.###...#####..##...##...####.......#######.#..### +.#......#...##.###..#....#...#.#.....#.#...##.#.#..#..###.##.###.#.##..##...#.##......#.###..#.#..## +.#....####...###..#.....##..#...#.#.###.#.#.##...#.##.##.#.#.#..####..###.#.#.#.##.#.#...#..#...#### +......##.##.#...#####.##..#.###..#.#####..##.#..##.###......#...#...#..#......###.######...#.#.##..# +###..#...#.##..###.#....##...#..#####.#.#..#.###...#####.#....##..####.#.##...#.#...##..#.#.#.#..#.# +...##.#.##.##..#.#.#.###.#.#...#.....###.###.##...#.###.##...##..#..###.#..##.##..###.#....###..##.. +.##.#..###..###.##.##...#..#####...#.....#####.##..####...#.##.#.#..##.#.#.#....###.....#....##..... +######.#..#.#..#....#.###...####.####.#.........#..##.#..##..##.....#..#.##.##...#...#####.#.##..#.# +.##.###...####....#.####...#####..#..#...#..#.....###.#..#.###..#.###.#.......##.####..#.##.#...##.. +........#.#.##.#.....#####.###......##..#.##.#..#...####.#...#..###.#.#...##..#.#...#.####...#.#.### +.#..#.##..##...######.###.##.#.#...#.#.#.#.##..##..##.#.##..#....#.##...#.##.##...##....##.###.##.#. +##...#...#...###.#.#...#...#..###......##.#.#....##..##.#..##.#.######...#..##.#.##.#.#....#.##.##.. +...#..###.#....#...#.##..##.#.##.#..###.##..#.##..####.#########....#.....##.#.##.##..##.##.######.# +#.##.#..##.......###...#.###....###.#..####..##.#####.##.###....##....#.###...####..#.#.#.##.....### +.......#...#...##.#...##.#.#..#.##..##.#....###...##.#####...#.........#.......###.##.#.#.###....##. +###.#.##.##.....#.#..#.#..####.####..#..###..........####.#.##...#######.###..#####..#.....#..###..# +#...##.##..####.##.###.#.#######..###.#..#######..#.##.####...#..#.##.####..####.#.#.......####.#... +...#.##..#..#..##........#.#..#..#.#....#.###.#.###..#.......###..#.....#....#..##.#...#.###...##.#. +###.##..#.##.#.#####..#.##.####....#####..###.#.#..#...#...###.#.##..#.#.#.....#.####.#.#.#.#.#.#... +..##..##..#..##.##.#...#..#....####....#...#..####..#.....######.###.####.#....##....##.#.#.###....# +.#.#.#.##..####..#.....#.####.#....#.....#....#.##..#.#..#.#...#.#.#.#..#..#..##.#....####.......#.. +..##.##..###......#...#..##...#.###.####.#...#.####..#.#.#.....#.#...####...#.########.##.#.#.#..### +#....#.##.....##.###.##.###..#.####.....####.##...#..##.###...###..###.#....####.#..#..#..#.#..##.#. +.#.#.##....#.##......#.#..###.#....###....#......#.#.##.##.#########..##..#...#.####..#...####..#..# +.#.#.......##.#.##.#...#...#.##.#..#.#.#.##....#..###.###.##.#.#...##.#..#..##....#..###.#...#.#.##. +#.##.#....####...#..##..#.#.#.#.##.#...#####.#...#..#..#.####.####.#.#....#......##..##..###...#..## +..##.###..##.####..#..#..##...###.#.#.#######.####...####......##.##..#...#.##...##....#..#..#.....# +....#..#..#.#.####.#...##..#....####.#..####...#.#...###...#..#..##...#....##...#.....#.#..#.#.#...# +...#.#.#.##..##.###..#.######....####.###...##...###.#...##.####..#.#..#.#..#.##.....#.#.#..##...... +.#.##.##.....##.#..###.###.##....#...###.#......#...##.###.#.##.##...###...###...#.######..#......#. +###..#...#......#..##...#....##.#..###.##.####..##..##....####.#...#.#....##..#.#######..#.#.#####.. +##...#####..####..##....#.#.###.##.#..#.#..#.....###...###.#####.....#..##.#......#...#.###.##.##... +...#.#.#..#.###..#.#.#....##.#.#..####.##.#.####.#.#.#...#....##....#.##.####..###.#.#...##.#..#..## +#.#.#..#.##..##.##.#...##.#....#...###..##..#.#######.#.###..##......##.#..###.########.#.##..#.#.## +######.###....##..#..#...####....#.#.#..#...#..######.#.#.##..##....##....##.##.##...#..#.####.#.#.. +#####.###..#..###......##...##.####.#.#.#.###.......##..##.####..##.####.#..#..####..#.####.#####... +##.#.#.###..##.#.##.#.#.#.##.#...##........###.#.##..####....###.#.####.####.#.......##.##.##...##.. +#.#..###...#..##.....##.#..#.#..##..######.#####...###.#.......###...#..##..#..#..##.#.#....#..#..#. +#.#..####.###..#...#...#...#.###..#.#.#.#.#.#.#..#....#.##.##.##..###..####.#..##..##.###.###....##. +#..#.##.#####........#..#.##.#..##.#...#....#..#.##..###..##..##.##..#..##.#.#...#.#.##.#.##....#.#. +.......##..#.....#..#.#.....#.##...####.###..####..#.#.#.#..#.....#....##...#..#.##..###.#.#....#... +#...###########.##.....##...###.#.##.##..####.##...#.####.#####.#####.####...###.##...##..#.#.###..# +....#.#.###.####.###...#...#.#..###.#.#.##...#..#.#.#..#.####..#..###.######.#.####.###...###.#.##.# +.....#..#..########...#.#.#.#.#.#.#.#..###.##..####...##.#.#.#...##..#####.##.#...#.####.#######.##. +.......#...#.#..#..#...#..#..##.....#.##....##.##...##..##.##...##...#.#..#.##.#.###.#.####.#.#..##. +.####...#...#.#.#....##..........##.##.###.##.#.#..#.#.#......########.#...#.####.##.###..##...####. +#.#.#...##.###..##..#..#.....####.#.....##.##.#..#.#.###.#..#######...##..#.#..#.#..############.### +.##..####.#..#.....###..#..#.#.....#.#.#...##.##.#....#..#..###.#...#....#.#...####..#.....###.####. +..#...#.###.###....##.#..#.##..####.##.#.##.##.##...###.####..#.#.#.##.#.#.#..###..##.##.##.##.#..## +#...............##.....######.#.#####.##.#....#.#..#.##...#.##....#........##.##...#.##.##.#..#.##.# +#..##..#.#.#.##.#..#.#.##.##...#...#..#.#.##..#.#...###...##...###..#####.#.#..#..#.#..#.#.##...##.# +.#######.#.....##...#.#.####.######.#..#......#....##.#.#..#..###.#...###...#....#.#..#.##.#...#.#.. +#.###......##.#.##..#.###.###..####..##....#..###......##..##..#####.####....#...###.....###.#..#... +###...#....###.#..#.###.##...###.##.......##.##.#.#.#....####....###..##.###...#..##....#.#.##..##.. +.##.......##.######.#.#..#..##....#####.###.#.##.....####....#......####....#.##.#.##..#.##...##.#.# +.#.###...#.#.#.##.###..###...##..#.##.##..##..#.....###.#..#.##.##.####........##.#####.#.#....#...# +##...##..#.##.#######.###.#.##.#####....##.....##.#.....#.#.##.#....#.##.#....##.#..#.###..#..#.#... +.#..#.#.#.#...#.##...###.##.#.#...###.##...#.#..###....###.#.###...##..###..#..##.##....###...###.## diff --git a/18/main.py b/18/main.py new file mode 100755 index 0000000..e6bdf65 --- /dev/null +++ b/18/main.py @@ -0,0 +1,59 @@ +#!/usr/bin/python + +import numpy as np + + + +def init_grid(lines): + dim = len(lines[0]) + grid = np.zeros((dim + 2, dim + 2), dtype="bool") + + for r, line in enumerate(lines): + for c, char in enumerate(line): + if char == "#": + grid[r + 1, c + 1] = True + + return grid + + + +def solve_partn(partn, init, steps): + grid = init_grid(init) + + # Part 2: some lights are stuck in the "on" state + if partn == 2: + grid[([1, 1, -2, -2], [1, -2, 1, -2])] = True + + for i in range(steps): + new_grid = grid.copy() + for x in range(1, grid.shape[0] - 1): + for y in range(1, grid.shape[1] - 1): + neigh = np.sum(grid[x - 1 : x + 2, y - 1 : y + 2]) - grid[x, y] + if grid[x, y]: + if neigh < 2 or neigh > 3: + new_grid[x, y] = False + else: # not grid[x, y] + if neigh == 3: + new_grid[x, y] = True + + if partn == 2: + new_grid[([1, 1, -2, -2], [1, -2, 1, -2])] = True + + grid = new_grid + + return np.count_nonzero(grid) + + + +def main(): + # Read initial state from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_partn(1, lines, 100)) # 821 for me + print("Part 2 solution:", solve_partn(2, lines, 100)) # 886 for me + + + +if __name__ == "__main__": + main() diff --git a/18/test.py b/18/test.py new file mode 100755 index 0000000..954e2b3 --- /dev/null +++ b/18/test.py @@ -0,0 +1,25 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class Examples(unittest.TestCase): + def test_example1(self): + lines = [ + ".#.#.#", + "...##.", + "#....#", + "..#...", + "#.#..#", + "####.." + ] + self.assertEqual(main.solve_partn(1, lines, 4), 4) + self.assertEqual(main.solve_partn(2, lines, 5), 17) + + + +if __name__ == "__main__": + unittest.main() diff --git a/19/input.txt b/19/input.txt new file mode 100644 index 0000000..806774f --- /dev/null +++ b/19/input.txt @@ -0,0 +1,45 @@ +Al => ThF +Al => ThRnFAr +B => BCa +B => TiB +B => TiRnFAr +Ca => CaCa +Ca => PB +Ca => PRnFAr +Ca => SiRnFYFAr +Ca => SiRnMgAr +Ca => SiTh +F => CaF +F => PMg +F => SiAl +H => CRnAlAr +H => CRnFYFYFAr +H => CRnFYMgAr +H => CRnMgYFAr +H => HCa +H => NRnFYFAr +H => NRnMgAr +H => NTh +H => OB +H => ORnFAr +Mg => BF +Mg => TiMg +N => CRnFAr +N => HSi +O => CRnFYFAr +O => CRnMgAr +O => HP +O => NRnFAr +O => OTi +P => CaP +P => PTi +P => SiRnFAr +Si => CaSi +Th => ThCa +Ti => BP +Ti => TiTi +e => HF +e => NAl +e => OMg + +CRnCaSiRnBSiRnFArTiBPTiTiBFArPBCaSiThSiRnTiBPBPMgArCaSiRnTiMgArCaSiThCaSiRnFArRnSiRnFArTiTiBFArCaCaSiRnSiThCaCaSiRnMgArFYSiRnFYCaFArSiThCaSiThPBPTiMgArCaPRnSiAlArPBCaCaSiRnFYSiThCaRnFArArCaCaSiRnPBSiRnFArMgYCaCaCaCaSiThCaCaSiAlArCaCaSiRnPBSiAlArBCaCaCaCaSiThCaPBSiThPBPBCaSiRnFYFArSiThCaSiRnFArBCaCaSiRnFYFArSiThCaPBSiThCaSiRnPMgArRnFArPTiBCaPRnFArCaCaCaCaSiRnCaCaSiRnFYFArFArBCaSiThFArThSiThSiRnTiRnPMgArFArCaSiThCaPBCaSiRnBFArCaCaPRnCaCaPMgArSiRnFYFArCaSiThRnPBPMgAr diff --git a/19/main.py b/19/main.py new file mode 100755 index 0000000..120a44a --- /dev/null +++ b/19/main.py @@ -0,0 +1,128 @@ +#!/usr/bin/python + +from random import shuffle + + + +def parse_input(lines): + rules = {} + for line in lines[0:-2]: + words = line.split() + k = words[0] + if k not in rules: + rules[k] = [] + rules[k].append(words[2]) + + molecule = lines[-1] + return rules, molecule + + + +# Given a "parent" molecule, find all "child" molecules +# that can be made from it with exactly one replacement. +def find_children(rules, parent): + result = [] + # For each replaceable string + for k in rules.keys(): + # For each occurrence in the given molecule + p = 0 + while p < len(parent): + i = parent.find(k, p) + if i != -1: + # For each replacement of the replaceable string + for r in rules[k]: + m = parent[0 : i] + r + parent[i + len(k) : ] + if m not in result: + result.append(m) + p = i + 1 + else: # ran out of occurrences + break + return result + + + +# Given a "child" molecule, find all "parent" molecules +# that can be produce it using exactly one replacement. +def find_parents(rules, child): + result = [] + # For each replaceable string + for k in rules.keys(): + # For each replacement of the replaceable string + for r in rules[k]: + # For each occurrence in the given molecule + p = 0 + while p < len(child): + i = child.find(r, p) + if i != -1: + m = child[0 : i] + k + child[i + len(r) : ] + if m not in result: + result.append(m) + p = i + 1 + else: # ran out of occurrences + break + return result + + + +def solve_part1(lines): + rules, start = parse_input(lines) + result = find_children(rules, start) + return len(result) + + + +def solve_part2(lines): + rules, target = parse_input(lines) + molecules = [target] + + # Compared to part 1, we do part 2 in reverse: from the target molecule, + # we work backwards through its history until we encounter "e"; because + # we go back one generation at a time, the first "e" must be the answer. + depth = 0 + while "e" not in molecules: + + # Find all ancestors of this generation; there could be HUGELY many + ancestors = [] + for m in molecules: + parents = find_parents(rules, m) + for p in parents: + if p not in ancestors: + ancestors.append(p) + + # Extremely greedy algorithm: only keep shortest candidates, + # because they're more likely to lie on the shortest path. + # However, this may give the wrong answer: the optimal path + # may involve some strategic locally non-optimal steps. + min_len = min(map(len, ancestors)) + shortest = [] + for p in ancestors: + if len(p) == min_len: + shortest.append(p) + ancestors = shortest + + # Sledgehammer solution to keep the runtime under control, + # since it turns out the above greedy approach isn't enough. + # Fortunately, the puzzle input is well-chosen to allow this. + if len(ancestors) > 42: + shuffle(ancestors) + ancestors = ancestors[0 : 42] + + molecules = ancestors + depth += 1 + + return depth + + + +def main(): + # Read replacement rules and medicine molecules from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_part1(lines)) # 509 for me + print("Part 2 solution:", solve_part2(lines)) # 195 for me + + + +if __name__ == "__main__": + main() diff --git a/19/test.py b/19/test.py new file mode 100755 index 0000000..f2fab39 --- /dev/null +++ b/19/test.py @@ -0,0 +1,39 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class Examples(unittest.TestCase): + def test_example1(self): + lines = [ + "e => H", + "e => O", + "H => HO", + "H => OH", + "O => HH", + "", + "HOH" + ] + self.assertEqual(main.solve_part1(lines), 4) + self.assertEqual(main.solve_part2(lines), 3) + + def test_example2(self): + lines = [ + "e => H", + "e => O", + "H => HO", + "H => OH", + "O => HH", + "", + "HOHOHO" + ] + self.assertEqual(main.solve_part1(lines), 7) + self.assertEqual(main.solve_part2(lines), 6) + + + +if __name__ == "__main__": + unittest.main() diff --git a/20/main.py b/20/main.py new file mode 100755 index 0000000..c20cc5c --- /dev/null +++ b/20/main.py @@ -0,0 +1,45 @@ +#!/usr/bin/python + +from math import sqrt + + + +def solve_partn(partn, target): + house = 1 + while True: + # Find all divisors of the house number, because those + # determine which elves brings presents to which house. + # If I were smart, I'd cache the results and use them in + # both parts 1 and 2, but I can't be bothered to do that. + divs = [1, house] + for n in range(2, int(sqrt(house)) + 1): + if house % n == 0: + divs += [n, house / n] + + # Give gifts to each house as described in the puzzle text + gifts = 0 + for d in divs: + if partn == 1: + gifts += 10 * d + else: # partn == 2 + if house / d <= 50: + gifts += 11 * d + + if gifts >= target: + return house + + house += 1 + + + +def main(): + # My personalized puzzle input + target = 34000000 + + print("Part 1 solution:", solve_partn(1, target)) # 786240 for me + print("Part 2 solution:", solve_partn(2, target)) # 831600 for me + + + +if __name__ == "__main__": + main() diff --git a/20/test.py b/20/test.py new file mode 100755 index 0000000..15ac2f9 --- /dev/null +++ b/20/test.py @@ -0,0 +1,16 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + self.assertEqual(main.solve_partn(1, 150), 8) + + + +if __name__ == "__main__": + unittest.main() diff --git a/21/input.txt b/21/input.txt new file mode 100644 index 0000000..e749051 --- /dev/null +++ b/21/input.txt @@ -0,0 +1,3 @@ +Hit Points: 103 +Damage: 9 +Armor: 2 diff --git a/21/main.py b/21/main.py new file mode 100755 index 0000000..2c75798 --- /dev/null +++ b/21/main.py @@ -0,0 +1,155 @@ +#!/usr/bin/python + +from copy import copy + + + +class Entity: + pass + +class Item: + pass + +class Shop: + pass + + + +# Annoying boilerplate to initialize the shop with the items +# given in the text. This is as compact as I could make it. +def init_shop(): + table_weapons = [ + "Dagger 8 4 0", + "Shortsword 10 5 0", + "Warhammer 25 6 0", + "Longsword 40 7 0", + "Greataxe 74 8 0" + ] + table_armour = [ + "Leather 13 0 1", + "Chainmail 31 0 2", + "Splintmail 53 0 3", + "Bandedmail 75 0 4", + "Platemail 102 0 5", + "NONE 0 0 0" # Because it's optional + ] + table_rings = [ + "Damage+1 25 1 0", + "Damage+2 50 2 0", + "Damage+3 100 3 0", + "Defense+1 20 0 1", + "Defense+2 40 0 2", + "Defense+3 80 0 3", + "NONE 0 0 0" # Because it's optional + ] + tables = [ + (table_weapons, "weapons"), + (table_armour, "armour"), + (table_rings, "rings") + ] + + shop = Shop() + shop.weapons = [] + shop.armour = [] + shop.rings = [] + + for table, attr in tables: + for row in table: + fields = row.split() + + item = Item() + item.name = fields[0] + item.cost = int(fields[1]) + item.damage = int(fields[2]) + item.armour = int(fields[3]) + + # Sometimes I love you, Python. But usually I don't. + shop.__dict__[attr].append(item) + + return shop + + + +def will_win(player, boss): + turn = 0 + while boss.health > 0 and player.health > 0: + # Player's turn to attack + if turn % 2 == 0: + boss.health -= max(1, player.damage - boss.armour) + # Boss' turn to attack + else: # turn % 2 == 1 + player.health -= max(1, boss.damage - player.armour) + turn += 1 + + # Did the player win? + return boss.health <= 0 + + + +def solve_partn(partn, player_stats, boss_stats): + shop = init_shop() + + min_cost = 666 + max_cost = 0 + for w in shop.weapons: + for a in shop.armour: + for r1 in shop.rings: + for r2 in shop.rings: + # No more than one of each item + if r1 == r2: + continue + + boss = copy( boss_stats) + player = copy(player_stats) + + cost = w.cost + a.cost + r1.cost + r2.cost + player.damage += w.damage + player.damage += r1.damage + player.damage += r2.damage + player.armour += a.armour + player.armour += r1.armour + player.armour += r2.armour + + # Part 1: find lowest cost where player wins + if will_win(player, boss): + if cost < min_cost: + min_cost = cost + # Part 2: find highest cost where player loses + else: + if cost > max_cost: + max_cost = cost + + if partn == 1: + return min_cost + else: # partn == 2 + return max_cost + + + +def main(): + # Set up player's stats given in puzzle text + player = Entity() + player.health = 100 + player.damage = 0 + player.armour = 0 + + # Read boss' stats from input text file + boss = Entity() + with open("input.txt", "r") as f: + lines = f.read().splitlines() + for i in range(len(lines)): # len(lines) = 3 + words = lines[i].split() + if i == 0: + boss.health = int(words[-1]) + if i == 1: + boss.damage = int(words[-1]) + if i == 2: + boss.armour = int(words[-1]) + + print("Part 1 solution:", solve_partn(1, player, boss)) # 121 for me + print("Part 2 solution:", solve_partn(2, player, boss)) # 201 for me + + + +if __name__ == "__main__": + main() diff --git a/21/test.py b/21/test.py new file mode 100755 index 0000000..4527f49 --- /dev/null +++ b/21/test.py @@ -0,0 +1,27 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + player = main.Entity() + player.health = 8 + player.damage = 0 + player.armour = 0 + + boss = main.Entity() + boss.health = 12 + boss.damage = 7 + boss.armour = 2 + + result = main.solve_partn(1, player, boss) + self.assertEqual(result, 40 + 25) + + + +if __name__ == "__main__": + unittest.main() diff --git a/22/input.txt b/22/input.txt new file mode 100644 index 0000000..7f98dd7 --- /dev/null +++ b/22/input.txt @@ -0,0 +1,2 @@ +Hit Points: 58 +Damage: 9 diff --git a/22/main.py b/22/main.py new file mode 100755 index 0000000..9b7bb0b --- /dev/null +++ b/22/main.py @@ -0,0 +1,137 @@ +#!/usr/bin/python + +from copy import copy +from random import randrange + + + +class Entity: + pass + + + +def solve_partn(partn, player_stats, boss_stats): + # We assign numbers 0-4 to the spells + mana_costs = [53, 73, 113, 173, 229] + + least_mana = 666666 + # 100K attempts turns out to be enough to reliably find the solution + for i in range(100000): + boss = copy( boss_stats) + player = copy(player_stats) + + spent_mana = 0 + # Timers for "Shield", "Poison" and "Recharge", respectively + timers = [0, 0, 0] + + turn = 0 + while boss.health > 0 and player.health > 0: + # Already spent too much; this can't be the solution, abort + if spent_mana > least_mana: + break + + # Part 2: hard mode: player loses 1 HP at start of their turn + if partn == 2 and turn % 2 == 0: + player.health -= 1 + if player.health <= 0: + break + + # Apply status effects from past spells + # "Shield" + if timers[0] > 0: + timers[0] -= 1 + if timers[0] == 0: + player.armour -= 7 + # "Poison" + if timers[1] > 0: + boss.health -= 3 + # Did the boss die before any actions were taken? + if boss.health <= 0: + break + timers[1] -= 1 + # "Recharge" + if timers[2] > 0: + player.mana += 101 + timers[2] -= 1 + + # Player's turn to cast a spell + if turn % 2 == 0: + # Can we afford to cast any spell? If not, we've lost; abort + if player.mana < min(mana_costs): + break + + # Randomly select which spell to cast. Sounds inefficient, but + # works fine: we want to minimize the total mana spent, so we're + # looking for short sequences, which we're very unlikely to miss. + s = -1 + while s == -1: + s = randrange(0, 5) + # Can we afford this spell? + if mana_costs[s] > player.mana: + s = -1 + # Isn't this spell already active? + if s in [2, 3, 4] and timers[s - 2] > 0: + s = -1 + + player.mana -= mana_costs[s] + spent_mana += mana_costs[s] + + # Apply effect of the spell we've selected + # "Magic Missile" + if s == 0: + boss.health -= 4 + # "Drain" + if s == 1: + boss.health -= 2 + player.health += 2 + # "Shield" + if s == 2: + timers[0] = 6 + player.armour += 7 + # "Poison" + if s == 3: + timers[1] = 6 + # "Recharge" + if s == 4: + timers[2] = 5 + + # Boss' turn to attack + else: # turn % 2 == 1 + player.health -= max(1, boss.damage - player.armour) + + turn += 1 + + # Did we stop because the player won? + if boss.health <= 0: + if spent_mana < least_mana: + least_mana = spent_mana + + return least_mana + + + +def main(): + # Set up player's stats given in puzzle text + player = Entity() + player.health = 50 + player.armour = 0 + player.mana = 500 + + # Read boss' stats from input text file + boss = Entity() + with open("input.txt", "r") as f: + lines = f.read().splitlines() + for i in range(len(lines)): # len(lines) = 2 + words = lines[i].split() + if i == 0: + boss.health = int(words[-1]) + if i == 1: + boss.damage = int(words[-1]) + + print("Part 1 solution:", solve_partn(1, player, boss)) # 1269 for me + print("Part 2 solution:", solve_partn(2, player, boss)) # 1309 for me + + + +if __name__ == "__main__": + main() diff --git a/22/test.py b/22/test.py new file mode 100755 index 0000000..8410d32 --- /dev/null +++ b/22/test.py @@ -0,0 +1,39 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + player = main.Entity() + player.health = 10 + player.armour = 0 + player.mana = 250 + + boss = main.Entity() + boss.health = 13 + boss.damage = 8 + + result = main.solve_partn(1, player, boss) + self.assertEqual(result, 173 + 53) + + def test_example2(self): + player = main.Entity() + player.health = 10 + player.armour = 0 + player.mana = 250 + + boss = main.Entity() + boss.health = 14 + boss.damage = 8 + + result = main.solve_partn(1, player, boss) + self.assertEqual(result, 229 + 113 + 73 + 173 + 53) + + + +if __name__ == "__main__": + unittest.main() diff --git a/23/input.txt b/23/input.txt new file mode 100644 index 0000000..a2b735a --- /dev/null +++ b/23/input.txt @@ -0,0 +1,47 @@ +jio a, +18 +inc a +tpl a +inc a +tpl a +tpl a +tpl a +inc a +tpl a +inc a +tpl a +inc a +inc a +tpl a +tpl a +tpl a +inc a +jmp +22 +tpl a +inc a +tpl a +inc a +inc a +tpl a +inc a +tpl a +inc a +inc a +tpl a +tpl a +inc a +inc a +tpl a +inc a +inc a +tpl a +inc a +inc a +tpl a +jio a, +8 +inc b +jie a, +4 +tpl a +inc a +jmp +2 +hlf a +jmp -7 diff --git a/23/main.py b/23/main.py new file mode 100755 index 0000000..bf84465 --- /dev/null +++ b/23/main.py @@ -0,0 +1,65 @@ +#!/usr/bin/python + + + +def solve_partn(partn, program): + if partn == 1: + regs = { "a" : 0, "b" : 0 } + else: # partn == 2 + regs = { "a" : 1, "b" : 0 } + + # "Parse" the input once up front, so we don't waste time + # doing this each iteration of a loop in the given program. + tokens = [] + for line in program: + words = line.split() + words[1] = words[1].rstrip(",") + tokens.append(words) + + # Main program execution loop + i = 0 # instruction pointer + while i < len(tokens): + op = tokens[i][0] + d1 = tokens[i][1] + + # The "i += 1" is repeated for consistency and clarity + if op == "hlf": + regs[d1] = int(regs[d1] / 2) + i += 1 + elif op == "tpl": + regs[d1] = regs[d1] * 3 + i += 1 + elif op == "inc": + regs[d1] = regs[d1] + 1 + i += 1 + elif op == "jmp": + i += int(d1) + elif op == "jie": + if regs[d1] % 2 == 0: + d2 = tokens[i][2] + i += int(d2) + else: + i += 1 + elif op == "jio": + if regs[d1] == 1: + d2 = tokens[i][2] + i += int(d2) + else: + i += 1 + + return regs["b"] + + + +def main(): + # Read program's assembly code from input text file + with open("input.txt", "r") as f: + lines = f.read().splitlines() + + print("Part 1 solution:", solve_partn(1, lines)) # 307 for me + print("Part 2 solution:", solve_partn(2, lines)) # 160 for me + + + +if __name__ == "__main__": + main() diff --git a/23/test.py b/23/test.py new file mode 100755 index 0000000..19dad35 --- /dev/null +++ b/23/test.py @@ -0,0 +1,22 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + prog = [ + "inc b", + "jio b, +2", + "tpl b", + "inc b" + ] + self.assertEqual(main.solve_partn(1, prog), 2) + + + +if __name__ == "__main__": + unittest.main() diff --git a/24/input.txt b/24/input.txt new file mode 100644 index 0000000..e204f7d --- /dev/null +++ b/24/input.txt @@ -0,0 +1,28 @@ +1 +3 +5 +11 +13 +17 +19 +23 +29 +31 +37 +41 +43 +47 +53 +59 +67 +71 +73 +79 +83 +89 +97 +101 +103 +107 +109 +113 diff --git a/24/main.py b/24/main.py new file mode 100755 index 0000000..61c97a6 --- /dev/null +++ b/24/main.py @@ -0,0 +1,86 @@ +#!/usr/bin/python + +from itertools import combinations + + + +def solve_partn(partn, masses): + if partn == 1: + num_groups = 3 + else: # partn == 2 + num_groups = 4 + + m_total = sum(masses) + m_group = int(m_total / num_groups) + + # At first, it seems the easiest way is to generate all possible + # grouping of packages, and then just keep the ones that are valid, + # and find the best among the remaining configurations. However, + # the input file has 28 packages, so there are 3^28 = 23 trillion + # possible groupings, which is obviously too much to brute-force. + + # Instead, we find the candidates for group 1: subsets of the packages + # whose masses add up to `m_group', with the smallest number of items. + + # Step 1: Find all combinations of packages in a certain range + k_min = int((m_group - 1) / max(masses)) + 1 + k_max = int(len(masses) / num_groups) + combos = [] + for k in range(k_min, k_max + 1): + combos += combinations(masses, k) + # Step 2: Keep only combinations whose masses add up to `m_group' + group1 = [] + for c in combos: + if sum(c) == m_group: + group1.append(c) + # Step 3: Keep only candidates with the smallest package count + min_len = min(map(len, group1)) + smallest = {} + for g1 in group1: + if len(g1) == min_len: + smallest[g1] = [] + + # Verify for each group 1 candidate that the remaining packages can be + # divided into 2 more groups of mass `m_group'. This takes time and it + # turns out that no candidates get rejected, hence it's commented out. + #for i, g1 in enumerate(smallest): + # remaining = [] + # for m in masses: + # if m not in g1: + # remaining.append(m) + # k_max = int(len(remaining) / (num_groups - 1)) + # combos = [] + # for k in range(k_min, k_max + 1): + # combos += combinations(remaining, k) + # for c in combos: + # if sum(c) == m_group: + # smallest[g1].append(c) + #valid = {} + #for g1 in smallest.keys(): + # if len(smallest[g1]) > 0: + # valid[g1] = smallest[g1] + + # Calculate quantum entanglement of each group 1 candidate + qentangs = [] + for g1 in smallest.keys(): + qe = 1 + for m in g1: + qe *= m + qentangs.append(qe) + + return min(qentangs) + + + +def main(): + # Read package weights from input text file + with open("input.txt", "r") as f: + masses = list(map(int, f.read().splitlines())) + + print("Part 1 solution:", solve_partn(1, masses)) # 10439961859 for me + print("Part 2 solution:", solve_partn(2, masses)) # 72050269 for me + + + +if __name__ == "__main__": + main() diff --git a/24/test.py b/24/test.py new file mode 100755 index 0000000..2c2655c --- /dev/null +++ b/24/test.py @@ -0,0 +1,18 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class Examples(unittest.TestCase): + def test_example1(self): + masses = [1, 2, 3, 4, 5, 7, 8, 9, 10, 11] + self.assertEqual(main.solve_partn(1, masses), 99) + self.assertEqual(main.solve_partn(2, masses), 44) + + + +if __name__ == "__main__": + unittest.main() diff --git a/25/input.txt b/25/input.txt new file mode 100644 index 0000000..c5c38e6 --- /dev/null +++ b/25/input.txt @@ -0,0 +1 @@ +To continue, please consult the code grid in the manual. Enter the code at row 2947, column 3029. diff --git a/25/main.py b/25/main.py new file mode 100755 index 0000000..48ca1f7 --- /dev/null +++ b/25/main.py @@ -0,0 +1,47 @@ +#!/usr/bin/python + + + +def coord_list(until): + return result + + + +def solve_part1(until): + # Generate a list of table (row, col) coordinates in the order + # that are filled by the algorithm described in the puzzle text. + coords = [] + r = 1 + c = 0 + while (r, c) != until: + if r == 1: + r = c + 1 + c = 1 + else: + r -= 1 + c += 1 + coords.append((r, c)) + + code = 20151125 # first code is given + for i in range(1, len(coords)): + code *= 252533 + code %= 33554393 + + return code + + + +def main(): + # Read target coordinate from input text file + with open("input.txt", "r") as f: + words = f.read().split() + row = int(words[-3].rstrip(",")) + col = int(words[-1].rstrip(".")) + coord = (row, col) + + print("Part 1 solution:", solve_part1(coord)) # 19980801 for me + + + +if __name__ == "__main__": + main() diff --git a/25/test.py b/25/test.py new file mode 100755 index 0000000..5b34e3e --- /dev/null +++ b/25/test.py @@ -0,0 +1,17 @@ +#!/usr/bin/python + +import unittest + +import main + + + +class ExamplesPart1(unittest.TestCase): + def test_example1(self): + until = (1, 6) + self.assertEqual(main.solve_part1(until), 33511524) + + + +if __name__ == "__main__": + unittest.main() -- cgit v1.3