advent of code 2025 in ts and nix
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add vis for day 10

dunkirk.sh 93a01046 b9ac8f35

verified
+1828
+10
scripts/generate-vis.ts
··· 62 62 description: 63 63 "3D visualization of junction boxes being connected by their shortest distances. Watch circuits form as connections merge isolated boxes into larger groups.", 64 64 }, 65 + "09": { 66 + title: "Movie Theater Floor", 67 + description: 68 + "Find the largest rectangle using red tiles as opposite corners. Part 1 allows any rectangle, Part 2 requires rectangles to only contain red/green tiles.", 69 + }, 70 + "10": { 71 + title: "Factory Machines", 72 + description: 73 + "Configure indicator lights by pressing buttons that toggle specific lights. Find the minimum number of button presses to match the target configuration.", 74 + }, 65 75 }; 66 76 67 77 const dayCards = days
+197
shared/10/input.txt
··· 1 + [...###.#.#] (1,8) (0,4,5,6) (2,3,4,5,6,7,8) (5) (0,3,5) (0,1,5,6,7,9) (0,7,9) (0,1,2,3,5,6,8,9) (0,1,2,3,4,5,7,8,9) (0,2,4,6,7,8,9) (1,2,3,4,6,7,8,9) (0,9) {65,41,48,35,50,67,76,68,55,61} 2 + [##.#..] (0,2,3,5) (0,2,3,4) (0,1,2,4) (1,4) (2,3,4,5) (1,4,5) (0,3,4) (3) {56,191,62,82,236,212} 3 + [...#.] (2,3,4) (1,2) (1,2,3,4) (0,2,3) (3) (0,3,4) {194,25,212,218,39} 4 + [###..] (1,2) (1,2,3) (3,4) (0,1,2) (1,3,4) {12,52,35,43,28} 5 + [#..####] (0,3,4,5,6) (0,1,3,5,6) (0,1,2,6) (0,3) (0,1,2,3) (4,5) (3,4) {47,46,31,136,104,19,27} 6 + [#.#.#] (0,1,2) (1,2,3) (0,2,3) (1,2) (0,4) (1,3) {35,44,50,27,10} 7 + [.#...###.] (4,5,6) (3,5,6) (0,2,4,6) (0,2,6,8) (0,1,8) (1,3) (0,1,2,4,5,7,8) (2,5,7) {39,33,32,11,41,35,37,15,29} 8 + [.#.####] (0,1) (0,4,5,6) (1,3,4,5) (1,5) (1,2,3) (1,2,3,6) (0,1,3,4,6) {43,87,30,61,37,26,44} 9 + [.######.] (0,3,4,5,7) (1,2,4,5,6,7) (1,2,3,4,6,7) (0,1,2) (5,7) (0,1,2,3,4,6) (0,4,5) (2,3) (0,2,3,4,5,7) (0,1,5,7) {34,43,49,20,33,47,21,47} 10 + [.#####] (0,3) (0,1,3,5) (1,2,3,4,5) (2) (0,1,2) {34,170,162,185,153,168} 11 + [.#.#] (1,3) (0,2,3) {154,10,154,164} 12 + [..#.##] (0,3,4) (2,4,5) (0,1,3,4,5) (0,1,3,5) {28,12,2,28,23,14} 13 + [...#.] (1,2,3,4) (3) (1,2,4) (0,3) (1,4) {168,22,12,188,22} 14 + [##...] (1,2,4) (2,3) (2,3,4) (1,2) (1,2,3) (0,2) (4) {3,30,36,15,11} 15 + [..##] (1) (1,2) (2,3) (2) (0,1,3) (0,3) {11,11,143,25} 16 + [.###..#..] (1,2,4,5,7,8) (0,3,4,5,7,8) (1,3,7,8) (5,7) (6) (0,1,3,4,6) (0,1,2,4,5,6,7,8) (1,3,4,6,7) (0,2,3,4,7,8) (1,5,6) (3,4,5,6,7,8) {49,151,36,57,71,160,141,79,63} 17 + [.#.#] (1,3) (2,3) (1,2) (0,1) (0,1,3) {23,48,18,47} 18 + [.#......#] (0,2,4,6) (1,4,5) (0,2,3) (0,2,4,7,8) (1,3,5,6,7,8) (3,7) (2,3,4,7,8) (1,8) (0,2) {42,20,228,213,224,19,14,205,201} 19 + [#..#.] (4) (0,1,3) (2,3,4) (1) (0,3) (3,4) (1,2,4) {14,29,10,18,29} 20 + [.#####.#] (0,1,5,7) (0,4,5,6,7) (2,6) (2,3,5) (1,4,5) (3,5,7) (1,2,3,4,5,6,7) {13,42,24,35,37,68,25,45} 21 + [###.###.#] (4,6,7) (2,4,6,7) (0,1,4,5) (2,3,4,5,6,7,8) (1,8) (1,2,3,4,6,8) (2,5,6) (0,2,3,5,6,8) (0,5,6,7,8) (1,2,4,6,8) {27,15,61,25,57,58,94,57,47} 22 + [##.##....] (0,1,2,5,6,7,8) (0,1,2,3,6,7) (0,1,2,6,7) (2,3,6) (0,3,4,7,8) (0,1,2,4,6) (5,7,8) (4,6,7) {47,45,61,37,32,209,77,249,211} 23 + [.##.##.#.#] (2,4,7,9) (1,4,5,8) (0,1,3,5) (1,4,5) (7) (1,2,8,9) (2,3,7,8) (0,1,2,3,4,7,8) (0,5) (0,2,3) (1,2,5,6,7,8,9) (0,1,2,3,5,9) (4,6,7,9) {69,76,81,72,49,58,6,51,46,40} 24 + [##..] (0,2) (0,1,3) (0,1) {26,6,20,2} 25 + [.#.#.#.] (0,1,6) (0,3,4) (1,2,3,6) (1,2,3,4,5) (1,2,3,5,6) (0,1,2,3) {21,33,28,34,7,7,22} 26 + [#..##.####] (8) (3,5) (1,3,4,6) (4,5,7,8) (2,3,4,6,9) (0,1,4,6,7,9) (1,2,3,4,5,6) (1,4,5,6,7) (1,5,6,7) (6,9) (3,6) (0,1,2,3,4,5,8,9) {25,161,35,166,175,74,190,42,29,50} 27 + [#..#.] (0,2,4) (1,4) (0,3) {22,5,20,2,25} 28 + [.......#..] (0,3,4,5) (2,3,5,6,8,9) (1,2,3,5,7,8) (0,1,3,4,7) (0,2,3,4,5,6,7) (1,2,5,6,7) (0,1,3,6,8,9) (0,2,6) (0,2) (0,1,3,4,5,7,8) {79,31,88,74,43,75,58,49,44,20} 29 + [.##..###.] (0,2) (1,6) (7,8) (1,3,7) (2,3) (3,4,7,8) (0,2,3,4,5,7) (4,7) (1,2,5,6,7) (0,2,3,4,5,8) {19,38,37,33,26,30,21,65,31} 30 + [###..#..] (5,6) (0,4) (0,1,2,4,5,7) (0,3,5) (1,2,3,5,6) (0,2) (0,1,2,4,7) (0,3,6) {55,49,51,38,32,53,23,32} 31 + [..##.#] (1,5) (0,1,2,3,4) (0,1,3) (2,4) (0,3,4) (0,2,4,5) {122,133,27,118,28,20} 32 + [#...#.#] (0,1,2,6) (1,3,6) (0,3,4,5,6) (1) (0,1,4,5,6) (0,4,5) (2,3,4,5,6) (2,3,4) {47,37,38,37,55,37,47} 33 + [##.###] (0,1,3,4,5) (1,4) (0,5) (1,3,4,5) (1,2,3,5) (0,2,3,4,5) {36,43,22,54,47,57} 34 + [.##...#..] (0,1,3,4,5,7) (0,1,2,3,4,6,8) (0,4,8) (1,5,6,7) (0,1,5,6,7,8) (0,2,4,5,7,8) (0,1,3,5,6) {78,68,23,32,40,77,62,58,53} 35 + [..##.....] (0,4,6,7,8) (1,2,3,5,7) (3,6) (1,3,4) (0,1,2,4,5,6,7,8) (0,1,2,3,4,5) (0,5,6) (2,5,6) {34,44,55,49,35,59,55,33,18} 36 + [.##.#.#..#] (1,2,3,6,8,9) (1,2,5,7,8) (3,7,9) (1,2,4,6,9) (1,2,4,6,8,9) (1,2,5,6,7,8,9) (0,2,5,6,7,8) (0,3,4,6,7,9) (0,2,5,6,7,8,9) {20,44,61,26,25,34,59,55,44,62} 37 + [#.#.] (0,1,3) (0,2) {213,18,195,18} 38 + [#..##.] (3,4) (0,1,2,5) (2,5) (0,2,3,4) (0,1,3,4,5) (0,5) {27,12,27,15,15,41} 39 + [.##..] (0) (1,2,3) (0,4) (1,2) (0,1,2,3) (3,4) (1,3) {42,207,201,207,36} 40 + [.##.#..] (1,2,3,4,5) (0,3) (2,3,4) (1,3,6) (1,2,4,5,6) (0,1,3,4) (0) {34,123,34,153,35,14,114} 41 + [#.#.#.#] (1,3,5,6) (0,5) (3,6) (1,2,3,4) (0,2) {33,22,29,26,16,26,10} 42 + [#...##...] (0,1,2,4,5,6,7) (0,1,2,8) (0,2,3,4,6,7,8) (0,2,3) (1,2,3,4,6,7,8) (0,1,2,3,5,6,8) (1,3,5,6) (1,2,4,5,6) (0,5,6,8) {53,48,74,47,55,29,61,48,42} 43 + [##.#.] (1,3,4) (0,4) (1,4) (0,1,2,3) (1,2,4) {177,213,173,193,44} 44 + [.#.#.##.#] (1,3,7) (8) (0,1) (4,5) (4,5,8) (0,3,4,5,6,7,8) (2,7) (2,4,6) (0,2,3) {22,15,30,9,21,9,15,17,24} 45 + [#......#.#] (0,1,2,4,6,7,8) (1,3,7,9) (5,7) (0,2,4,6) (2,4,5,7,9) (3,5,7) (0,1,2,5,6,9) (0,7,8) {54,27,50,24,36,58,34,77,28,35} 46 + [#.#..##] (0,1,3) (0,2) (1,2,4,6) (3,5) (5,6) (0,4,6) (0,1,3,5,6) (2,6) {33,28,31,20,26,14,44} 47 + [#..##] (0,1) (2,3) (1,3,4) (0,1,4) {175,177,0,2,168} 48 + [.###...##.] (8) (0,3,4,5,6,7,8,9) (0,4,5,9) (0,1,2,3,5,7,8) (2,3,4,5,6,7,9) (1,2,3,6,7,9) (0,1,2,3,4,5,7,8) (2,3,5,8,9) (6,8,9) (1,2,3,4,5,6,7,9) (1,4,6,8,9) (0,3,6,9) (0,2,3,7) {65,50,69,97,72,86,95,82,68,117} 49 + [#..#.#....] (0,2,4,7) (1,8,9) (0,1,3,4,6,7,8,9) (8) (0,1,3,4,5,6,9) (1,3,5,6,7) (0,3,5,6,7) (1,3) (0,3,5) (0,1,4,8) (0,1,2,4,5,7,8,9) {80,81,27,53,70,31,38,56,62,53} 50 + [#...] (0,1,2) (1,3) (1,2) (0,2) (2,3) {19,41,38,23} 51 + [.##..] (1,2) (1,3,4) (0,3) {20,29,9,40,20} 52 + [..#.#.] (3,4,5) (2,3,5) (0,1,2,5) (3,5) (0,1,2) (2,3,4,5) (2,3) {27,27,76,67,25,72} 53 + [##.##...#] (7,8) (0,2,4,5,7,8) (1,4,6,7) (2,4,5,6) (2,3,4,5,6) (0,1,3,5,6,8) (1,5,7,8) (0,2,5,8) (0,1,3,6) (2,3,4,5,6,7,8) (0,2,3) {56,44,44,48,44,68,60,44,61} 54 + [#..#.] (0,2,3,4) (0,1,2,3) (1,2,3) (2,4) {12,13,132,25,119} 55 + [..#...#] (1,2,4) (2,3,4) (2) (0,1,4,5,6) (2,4) (0,1,2,4) (0,2,3,4,5) (0,2,4,5,6) (0,1,2,3,6) {58,42,71,22,64,34,49} 56 + [..##.] (0,2,4) (0,1,2,3) (0,1,4) (1,4) (2,3,4) (1,2,4) {22,44,18,11,41} 57 + [#.#.] (0,1,3) (0,2) {21,1,20,1} 58 + [#...] (0,3) (0,1,3) (0,2,3) (1) (1,2,3) (2,3) {120,35,134,153} 59 + [.#.##.#] (1,3,4,6) (0,1,2,4,5,6) (0,1,2,4,5) (0,2,6) (2,3,5) (4) {54,48,67,27,55,47,50} 60 + [##.#] (0,2,3) (0,1,3) {18,17,1,18} 61 + [#.##.....#] (0,2,3,9) (6,8) (1,6,7) (4,5,6) (0,1,3,4,8,9) (3,4,5,6,8) (0,3,7,8) (0,2,3) {22,19,19,28,16,15,36,20,12,1} 62 + [##.#.] (0,2,3) (0,1,4) (1,3,4) (1,4) (0,1,3) (1,3) {19,62,1,36,42} 63 + [#.###] (1,3,4) (0,2,3,4) (2,3) {12,19,30,49,31} 64 + [...##] (0,1,4) (1,2,3,4) (0,2) (0,3) (3,4) (1,2) (0) {18,19,18,18,18} 65 + [#..#..#.#] (0,1,4) (5,7,8) (2,5,6,7,8) (0,4,5,6) (0,2,3,4,6,8) (1,3,4,5,6,7) (0,2,3,5,6,7,8) (0,1,2,3,4,6,7) (1,2,3,6,7,8) (2,4,5,7) {209,187,45,48,215,71,78,64,43} 66 + [##....#.] (2,3,4,7) (1,4,5) (0,3,4,5) (0,1,2,5,7) (1,4) (0,1,4,6) (0,3,4) (0,6,7) {30,38,108,107,138,10,17,108} 67 + [..###.###.] (0,9) (1,7) (0,1,2,3,5,6) (2,5,7,8) (0,2,3,4,5,7,9) (1,2,3,4,5,7,8,9) (1,2,3,4,5,6) (0,1,2,5,6,8) (0,1,2,4,5,6,7,8) (0,1,2,5) (0,1,2,4,6,7,8,9) {82,105,103,33,55,85,74,77,79,37} 68 + [#.#.#.##.] (1,2,3,4,5,6,7) (1,6,8) (2,3,5) (5,6) (1,2,4,6,7) (0,1,2,7,8) (0,2,3,4,5,7,8) (0,1,3,4,5,6,8) {37,45,79,49,42,52,30,59,40} 69 + [#...##.] (0,2,3,4,5) (0,3,6) (0,4,5) (1,3,5,6) (1,2,4,5) (4,6) (0,2,3,4,5,6) {27,18,22,34,33,29,45} 70 + [#..##.#.] (0,1,4) (0,5,7) (1,2,4,5,6) (2) (0,5) (3,4,6,7) (0,2,3,4,6) {24,171,185,10,181,178,176,7} 71 + [#..#.##.] (0,3,4,6) (4,6) (0,4,5) (1,2,3,4,5,7) (0,1,2,3,6) (0,1,2,4,6,7) (1,2,3) (1,2,3,4) {62,61,61,57,84,21,65,22} 72 + [#.#.##.] (0,1,2,4,5) (3,6) (1,2,4,5,6) (1,3,5,6) (0,1,6) (1,2) {16,149,136,27,17,25,38} 73 + [#.#.#..#.#] (0,3,6,7,9) (0,2,3,5,6,7,8,9) (3,6,8) (0,2,5,6,9) (2,3,4,7) (0,1,2,4,5,6,7,8) (0,1,3,4,5,6,7,9) (0,1,2,3,7,9) (5,8,9) (2,5,8,9) (3) {54,41,64,92,37,43,52,67,47,59} 74 + [##..#.] (3,4,5) (1,5) (1,2,4) (1,4) (1,2) (0,3,5) (0) {23,47,31,10,33,12} 75 + [#..##.#] (2,4) (1,3,4,5) (0,1,5,6) (0,2,4,5,6) (0,1,4,5,6) {47,41,24,12,55,59,47} 76 + [#.#.##.#] (0,1,2,4,5,7) (0,2,3,6,7) (0,3,4,5) (3,4,5,6) (0,1,3,5,6,7) (1,2,4,5,6,7) (0,2,3) (2,4,5,6,7) (1,7) {32,34,35,34,44,47,32,42} 77 + [..#.#....#] (0,2,3,5,6,7,8,9) (1,3,4,5,6,7,8,9) (0,2,7,8,9) (5,6,9) (3) (0,1,4,5,9) (1,5,9) (0,1,2,3,4,5,8) (2,5) (4,8) {26,38,191,38,31,233,23,8,24,46} 78 + [.#....#.#.] (2,3,4,8) (0,1,2,5,6,7,9) (0,2,3,4,7,8,9) (0,2,3,5,6,7,8,9) (1,3) (4,5,6,9) (0,3,4,5,6,7,8) (0,8,9) (3,4,5,7,8,9) (0,1,2,3,4,6,8,9) (1,2,5,6,7,8,9) (3,4,5) {70,55,62,73,59,77,79,59,69,100} 79 + [#...###...] (0,3,6,9) (5,8,9) (1,2,3,4,6,8,9) (1,2,5,7) (0,1,2,3,4,6,7,8) (1,2,3,4,6,7,8,9) (3,5) (1,5,6,7,8,9) (4,5,6) (1,2,3,4,5,6,7,9) {33,65,60,67,57,30,75,48,63,62} 80 + [#.##] (1,2) (0,1) (0,2,3) {8,22,16,1} 81 + [##..##] (1,2,5) (0,1,2,3,5) (0,3,4) (0,2,4) {20,11,21,10,17,11} 82 + [.#.#] (1,3) (0,2) (0,3) {21,10,9,22} 83 + [#..##.##] (0,1,2,3,4,6,7) (3,4,7) (2,3,7) (2,3,4,5,7) (2,3,5,6) (2,3,6,7) (3,4) (1,3,7) (0,4,5,6) (2,3) {3,14,61,108,49,34,27,62} 84 + [########..] (0,2,3,4,9) (0,3,6,7,8,9) (0,1,2,3,4,5,6,7) (4,5,7,9) (0,1,2,3,4,7,8,9) (0,2,3,4,6,7,8,9) (1,3,5,6,8,9) (0,1,4,5,8,9) (0,2,3) (1,8) (0,5,8) {58,39,41,60,41,33,38,48,46,47} 85 + [#..#.#..#] (0,3,6,7) (3,4,6,7) (0,2,5) (0,5,8) (0,6) (0,1,2,3,4,5,7,8) (1,3,4,6,7,8) (0,3,5,8) (4,7) (0,1,3,4,7,8) {49,22,13,36,43,26,47,47,35} 86 + [.#.....] (1,2,3,4,5) (1,2,3,4) (1,2,3,4,6) (0,2,4,6) (0,1,2,4,5) {6,29,33,27,33,18,8} 87 + [##.###.#.#] (0,2,5,6,8) (1,2,3,4,5) (0,2,3,5,7,8,9) (0,1,2,4,5,6,9) (2,3,6,7,9) (0,1,2,3,4,5,7,9) (0,2,9) (2,3,4,7,9) {38,39,69,47,42,56,30,28,17,39} 88 + [..##.#.] (0,1,3,4,5) (2,5) (0,1,4,5) (1,4,6) (0,3,4) {128,128,12,21,142,126,14} 89 + [###.] (1,3) (0,2,3) (3) (0,1) (2) (1) {24,41,14,44} 90 + [##.##...] (0,1,4,6,7) (0,1,3,4) (4,6) (0,2,3,4) (6,7) (3,5,6) (0,2,3,5,7) {38,20,18,31,42,23,54,42} 91 + [#.#..] (0,2,3) (3,4) (0,3) (4) (1,2) (0,1) {42,175,174,42,14} 92 + [.#######] (0,2,6) (0,1,2,3,5,6) (1,7) (2,4,5,6,7) (1,2,4,5) (2,3,4,5,6) {2,8,22,7,20,20,22,21} 93 + [.#.###.###] (3,7,8) (0,8,9) (1,2,3,4,5,7,8,9) (0,1,2,3,5,6,9) (0,1,2,3,4,6,7) (0,1,2,3,5,6,8,9) (0,4,6,8) (0,1,2,4,8,9) (0,1,5,8) {191,63,54,46,150,41,166,15,177,48} 94 + [#.#.] (1,2,3) (0,2) {11,14,25,14} 95 + [#...] (0,3) (1,2,3) (3) (0,1,2) (2) (0,2) {7,7,14,22} 96 + [....##..] (5,7) (0,6) (2,7) (1,2,3,5,6,7) (0,3,4,5,6,7) (0,1,3,5,7) (1,4) (0,1,2,3,5,7) (0,1,2,3,4,5,7) {37,30,22,26,13,31,14,31} 97 + [#...##....] (0,2,7) (2,5) (0,1,4,5,6,9) (0,1,6,7,8,9) (0,2,3,4,5,7,8) (0,2,3,4,5) (1,2,3,5,6,7,8) (0,1,2,6) (1,2,4,6) (3,8,9) {76,83,91,53,48,56,83,51,57,48} 98 + [#.##.####] (0,1,3,4,6,7,8) (0,2,3,5,6,7,8) (2,4) (2,3,4,5,6,7,8) (0,1,3,4,5,7,8) (5,6) (2,3,6,7,8) {31,27,50,68,55,45,60,68,68} 99 + [..#....##] (0,1,4,5,6,7,8) (0,4,6,7,8) (1,3,4,5,7,8) (1,2,6,7,8) (0,2,3,4,8) (1,2,4,5) (0,4,5,6,7) (0,1,3,4,6,7,8) {52,52,40,41,71,35,43,53,68} 100 + [.#.#] (1,3) (0,2) {19,106,19,106} 101 + [.#.#] (0,3) (1,2,3) (1,2) (2) (0,1,3) {20,44,28,31} 102 + [####.] (0,2,4) (1,2) (0,1,2,3) (0,2,3,4) (1) {134,128,137,125,10} 103 + [###...##] (0,4,5,6,7) (0,1,2,5) (1,4,5,7) (0,1,5) (2,3,4,7) (0,2,5,6,7) (0,2,3,6) (1,3,5) (0,1,2,3,6,7) (1,2,4,5,6) {201,193,197,35,42,211,32,55} 104 + [..#.##] (2,3,4,5) (0,1,2,3,5) (1,4) (0,1) (0,3,4) (0,3,5) {29,31,12,23,24,17} 105 + [#..#] (2) (0,1) (0,1,2) (1,2) (3) (0,1,3) {23,25,25,20} 106 + [.##.##..#.] (2,4,9) (0,1,3,4,5,6,8,9) (2,4,5,6,7) (1,2,3,4,6,7,8,9) (0,4,5,7,8) (0,3,4,6,7,8,9) (1,2,4,5,6,7,9) (0,3,4,5,6,7,8) {17,16,30,28,47,16,41,41,28,36} 107 + [#..#.#] (0,3,5) (1,3,4) (1,3,5) (0,2,3,5) (4,5) {24,173,9,197,12,209} 108 + [..#.#] (0,1,3,4) (1,2,3) (0,1,2,4) (0,2,3) {160,25,158,146,22} 109 + [###..###] (1,2,4,5,7) (0,2,3,5,7) (0,3,4,5,6,7) (1,2,6,7) (0,1) (1,2,4,7) (3,4,5,7) (0,2,3,5,6,7) {46,41,57,45,49,65,42,79} 110 + [#.##] (1,2,3) (2,3) (0,2,3) {14,1,18,18} 111 + [.##.######] (1,2,3,4,5) (0,2,7) (0,2,4,5,6,7,8,9) (6,8,9) (0,1,3,4,6,8,9) (5) (5,6,9) (0,1,4,5,7,8,9) (0,2,3) (0,1,2,6,7,8,9) (1,2,5,6,7,8,9) {58,38,41,16,30,38,65,43,58,72} 112 + [.#...##.#] (0,1,2,3,4,6,7,8) (0,2,3,4,5,7) (0,1,5,6) (0,2,3,4,5,6,7) (0,1,2,6,7,8) (2,3,4,5,7) (0,2,4,7) (3,5,8) {220,14,230,224,217,223,32,230,32} 113 + [####..#..] (0,2,5) (3,4) (0,2,4,5) (0,4,5,7) (0,2,4,5,6,8) (0,1,5,8) (0,1,2,6,7) (0,1,3,4,5,7,8) (0,1,4,5,6) (0,2,3,4,5,6,8) (0,4,5,7,8) {302,229,63,40,99,283,47,64,243} 114 + [...#.#.] (0,2,3,4,5) (3,4,5,6) (0,1,3,4,6) (3,4,5) (1,2,3,4,6) (0,3,6) (0,2,5) (0,1,5) (0,2,4,5,6) {87,25,61,70,76,80,58} 115 + [###......] (0,1,3,6,7,8) (3,6) (2,3,4,5,6,7) (0,4,8) (1,5,6,8) (0,1,3,4,6,7) (0,1,2,4,6,7,8) (1,2) (1,2,6) {145,188,47,160,29,35,188,157,156} 116 + [...##.#] (3,4,6) (0,1,3,4,6) (0,2,3,6) (3) (0,6) (4,5,6) (0,1,2,4,5) (0,3,5) (1,4,5,6) {38,26,19,40,39,21,35} 117 + [####..##] (0,1,2,4,7) (1,6) (0,1,3,6) (0,7) (2,6) (0,1,3) (1,2,4,7) (3,5,6,7) {28,38,208,23,24,12,210,43} 118 + [.#.....] (0,1) (0,3,4,6) (2,3,4,6) (4,5,6) (1,2,4,5,6) (0,1,3,4,5) (3,4,6) {44,44,23,55,83,47,64} 119 + [#.#.##....] (0,1,2,3,7,8) (2,4,5,7,8) (0,1,3,4,8,9) (0,5,7,9) (3,4) (0,1,2,3,4,5,8,9) (0,1,2,3,4,5,6,7,9) (0,2,3,4,6,8,9) {48,26,154,61,184,135,23,130,167,47} 120 + [##.#######] (2,3,5,6,8,9) (0,5,9) (1,2,9) (0,2,3,4,5,6,7,8) (2,6,8) (0,3,5,6) (0,1,2,3,4,5,7,9) (3,4,9) (0,2,5,6,8) (3,7) {35,17,158,154,7,167,147,13,141,171} 121 + [#.##.#..] (0,3) (0,2,4) (1,2,3,5,6) (0,1,2,3,6) (1,2,3,4,5,7) (2,3) (3,4) (2,3,4,7) (0,1,2,7) (0,1,6,7) {72,60,68,67,41,16,39,45} 122 + [###..] (3) (1,2,3) (0,1,2,3) (3,4) (0,1,4) (0,3,4) (0,2) {37,26,24,34,18} 123 + [...#...###] (2,3,5) (0,3,4,5,6,9) (3,6) (2,8) (0,1,4,5,6,7,9) (1,3) (0,1,3,4,5,6,7,8,9) (5,7,9) (0,2,4,8) {50,36,32,66,50,63,46,33,22,48} 124 + [#..#] (0,1,3) (0,2,3) (1) (1,2) {16,181,165,16} 125 + [#.#.] (0,2) (0,1,3) {19,15,4,15} 126 + [##.####] (0,1,3) (0,4,5,6) (0,1,3,4,5,6) (0,2,4,5,6) (0,1,2,4,5,6) (2,3,4) {28,18,38,24,43,24,24} 127 + [#..#..] (0,3) (1,2,3,4) (1,2,4,5) (0,1,2,3,4,5) {19,227,227,33,227,213} 128 + [#.##] (1,2,3) (0,1) (1,2) (2,3) {17,49,32,12} 129 + [.#.##] (0,1,3) (3,4) (2) (0,2,4) {16,13,20,28,18} 130 + [##..] (2) (0) (3) (0,2) (1,3) (0,2,3) {15,15,33,31} 131 + [.##.#.###.] (1,6,8) (6,7) (0,1,2) (1,5,6,7,9) (2,3,4,5,6,8,9) (7,8) (2,4,5,6,7,8) (3,6,7,9) (0,1,3,5,6,7,8,9) (1,2,3,5,6,7) (0,2,5,6,8,9) (0,2,3,4,5,8,9) {19,59,26,37,9,46,82,69,41,50} 132 + [#.#...#] (0,1,4,6) (0,3) (3,6) (1,2,4,5,6) (0,1,5) (1,4,5,6) (0,1,2,3,5) (0,1,4,5,6) (1,3,4,6) {51,67,24,33,42,59,42} 133 + [####] (1,3) (0,1,2,3) {12,16,12,16} 134 + [.#.#.] (0,2,3) (0,3,4) (0,1) (0,2) (0,3) (3) (0,1,2) {58,8,27,181,16} 135 + [..#....] (2,3) (2,6) (2,3,5) (0,1,3,4,5) (4,6) (0,3,5,6) (0,6) (1,2,4,5,6) {19,26,59,29,26,44,49} 136 + [##..] (0,1,3) (3) (0) (0,1,2) {35,28,10,25} 137 + [#..##.#] (0,2,3) (1,4) (1,2,3,5,6) (0,4) (2,3) (0,3,4) (4,6) (0,2,4,5,6) (0,3,4,6) {62,8,36,54,72,20,49} 138 + [##..##...] (0,2,3,4,8) (0,1,8) (0,1,3,4,5,6,7,8) (0,3,4,5,6,7,8) (2,5,7,8) (0,1,2,3,6,8) (0,6,7) (3,5,8) (2,7) {57,32,170,62,35,43,37,178,72} 139 + [.##...#] (0,2,3,5) (1,2,3,4,5) (0,1,2,5) (0,1,4,6) (0,5,6) {52,33,32,15,16,38,21} 140 + [....#.] (0,2,3) (0,2) (3,5) (0,1,2,3,5) (1) (3,4) {12,17,12,24,5,17} 141 + [....#..#..] (2,6) (0,2,3,4,5,6,7,8) (0,1,3,7,8,9) (3,4,9) (0,1,2,3,4,5,6,9) (1,3,5,7,8,9) (0,2,3,4,6,7,9) (0,1,8) (1,3,4,8) (0,1,3,4,6,7,8,9) {41,47,28,70,62,27,43,32,44,52} 142 + [#.##.#.] (1,2,4,6) (1,2,3,4) (0,2,3,5,6) (0,2) (0,1,3,4,6) {28,18,46,29,18,20,29} 143 + [##..#.] (1,2,4,5) (5) (0,2) (0,1,2,4) (0) (4,5) (1,3,4,5) (3,4,5) {33,34,37,192,225,221} 144 + [##...##.] (0,3,4) (2,5) (1,4) (2,4,6) (0,1,3,7) (0,2,4,6,7) {164,10,193,10,185,20,173,158} 145 + [.......#] (4,5) (1,2,4,7) (0,5,7) (1,4) (1,2,3,4,5,6,7) (1,2,3,4,5,7) (0,3,5,6,7) (0,1,2,5,6,7) {44,63,52,44,62,80,38,85} 146 + [####..#.##] (0,3,5,8,9) (0,2,9) (1,3,5,6,7,8,9) (7,8) (0,2,3,4,5,8,9) (4,8,9) (0,1,3,4,5,6,7,9) (0,1) (0,1,2,3,4,5,7,9) (0,2,4,5,6,7) (1,3,6,8) (0,1,4,9) (4,6) {178,69,47,175,63,177,53,67,149,185} 147 + [.##..####] (3,4,6) (0,3,4,5,6,7,8) (4,5,8) (0,1,2,3,5,6,7,8) (4,5) (1,2,4,7) (6) (1,3,7,8) {29,40,24,62,75,62,54,55,61} 148 + [##.###.] (0,1,2,3,4) (0,3,6) (0,3,5,6) (3,5) (0,4) (0,1,3,4,5) {249,205,200,242,214,25,35} 149 + [##....##] (1,3,4,6) (1,2,4,5,6,7) (0,1,3,4,5,7) (0,1,2,3,5,6) (2,3,4,5,6,7) (0,3,4,6,7) (0,4,5) {43,37,32,45,52,55,46,22} 150 + [##....###.] (2,6,8,9) (3,9) (2,4,6) (5,6,7) (4,7) (0,1,2,3,7) (2) (1,5,6,9) (0,1,3,6,8,9) (3,4,5,6) (1,2,3,4,5,6,8) (0,1,3,4,6,8) (9) {37,51,76,53,52,23,82,42,55,55} 151 + [..##.] (2,3) (0,2,3,4) (1,3,4) (1,2,3,4) {8,18,34,37,26} 152 + [##.#....#] (2,5) (0,1,2,5,8) (3,4,5,6,8) (1,2,3,4,6,7,8) (0,1,3,4,5,6,8) (1,4,7) (2,3,5,7,8) (1,2,3,5,7) {29,65,46,36,47,40,32,38,54} 153 + [###.#.#] (2,5) (0,4) (2,3) (1,2) (2) (0,3,6) (0,2,6) (0,3) (0,1,4,5,6) {88,25,56,42,38,32,51} 154 + [#..###.##] (0,1,4,5,6) (0,1,3,4,5,6,7,8) (0,1,2,7,8) (1,2,3,4,5) (0,3,8) (1,3,4,5,6,7) (4,6) (0,1,3,5,6,7) (8) (0,2,3,4,5,6,7) (1,7) {175,196,12,182,43,176,171,187,52} 155 + [.#.###..] (2,4,5) (2,6,7) (2,4,5,6,7) (3,4) (0,3,4,5,7) (1,2,3,4,5,7) (5) (2,5,6) (1,3,4,5,6,7) (0,2,4,6,7) {14,25,37,189,194,64,34,47} 156 + [.##.] (0,1) (0,2,3) (0,1,2) (1,2) {35,31,38,20} 157 + [#.#...#] (0,1,4,5) (1,2,4) (0,1,4,6) (1,2,4,5,6) (0,2,6) (1,2,3) (3,4) {42,60,34,19,63,35,39} 158 + [.###...] (4) (0,2,3,4,6) (0,1,2,3,4,5) (0,2,4,5,6) (0,1,3,4,5) (1,2,3) {37,35,20,36,44,36,3} 159 + [#.#..] (0,3) (2,3) (3,4) (0,3,4) (2,4) (0,1,3) {200,3,39,227,212} 160 + [#.#.#...] (2) (1,7) (0,3,4,6) (3) (1,4,5,6,7) (0,2,3,5,6) {33,211,25,52,29,30,46,211} 161 + [....##] (0,1,4,5) (0,1,5) (2,3,4) (1,3) (0,1,3) (1,2,5) (0) (1,2,3,4) {36,41,20,34,21,16} 162 + [.##.###.#.] (0,2,3,4,9) (1,7) (1,2,3,5,6,7,8,9) (0,1,2,4,5,7,9) (3,4,5,6,7) (4,6) (2) (0,1,2,3,6,7,9) (0,6,7,8,9) {138,163,164,156,25,29,162,172,22,157} 163 + [..#.#.] (0,1,2,4,5) (0,2,3) (0,2,5) (0,4,5) {53,2,34,19,21,34} 164 + [#...##] (1,2,3,4) (0,3,5) (1,5) (0,1,4,5) (0,2,3,4,5) (0,2,3) (0,1,2,3) {32,41,28,39,15,30} 165 + [##.###..] (0,2,5,6) (0,5,6,7) (4,5,7) (1,3,6,7) (0,2,5,7) (1) (3,4,6,7) (0,6) (1,2,3,5) {30,45,38,45,35,55,43,64} 166 + [.#.#..#...] (3,7) (0,4,5,9) (3,4,6,8) (0,1,2,3,5,6,8,9) (2,3,4,5,6,7,8,9) (8,9) (0,1,2,3,4,6,8) (0,1,2) (0,1,2,4,5,7,8,9) (0,1,3,4,6) (0,1,3,7,9) (0,1,6,7,8,9) {263,243,67,237,236,61,224,76,91,99} 167 + [.##.##] (0,2,3,5) (1) (0,1,2,4,5) (4,5) (1,3) (0) (0,2,3) {44,31,42,42,15,35} 168 + [###.] (1,3) (1,2) (0,2) (2) (2,3) {9,155,45,146} 169 + [#.#...#.#.] (0,1,2,5,6) (0,1,2,5,7) (1,2,4,5,6) (0,1,3,5,7,8,9) (2,3,4,5,6,8) (4,6) (0,1,2,3,4,5,6,8) (0,3,4,5,9) (5,6,7,8) (1,4,6,7,8) (2,3,8,9) (2,3,4,9) (0,1,2,4,5,7,8) {76,79,96,73,82,86,58,63,80,61} 170 + [...###] (0,3,4) (3,4,5) (0,1,4,5) (0,2,3,4) {34,10,10,32,42,18} 171 + [..##.] (1,2,4) (0,2,3) (2,3) {17,7,28,21,7} 172 + [.###] (1,2,3) (0,2) {4,19,23,19} 173 + [###.] (2,3) (0,1,3) (0,1) (1,2) {15,32,30,26} 174 + [..#.#.] (0,2,4) (3,4) (0,1,2,4,5) (0,1,3) (1,2,3,5) {37,29,33,31,48,21} 175 + [###..###] (1,3,6) (0,1,2,3,4,5,7) (0,2,4,5,6,7) (1,2,6) (0,3,6) (1,5,7) {27,26,20,16,20,37,36,37} 176 + [.##.] (2,3) (1,2) (0,3) {14,1,1,14} 177 + [.#.##...#] (3,4,5,6,8) (1,2,3,6,7,8) (1,2,3,5,6,7) (3,7) (2,3,4,5,6,7,8) (0,1,2,8) (0,3,4,5,7,8) {153,46,47,212,158,173,51,196,189} 178 + [#.###.] (0,1,4,5) (0,1,2,5) (1,2,3) (1,2,3,4,5) (0,2,3,5) (0,3,4) (1,2) (2,3,4,5) {220,54,54,223,212,30} 179 + [#.####] (1,2,3,5) (0,1,5) (1,2,3,4) (0,2,3,4) (2,3) {21,25,36,36,20,14} 180 + [...#....##] (0,9) (4,5,6) (0,2,4,6,7,9) (0,2,3,4,7,8,9) (0,1,4,7) (0,3,7,8) (8,9) (0,7,8) (0,1,2,5,6,7) {65,26,36,8,49,35,47,46,18,49} 181 + [.####.##] (1,2,3,5,6,7) (0,1,3,4,6,7) (1,2,3,4,5,6) (0,2,4,7) (1,3,5) (3,4,5,6,7) (4,7) (0,1,4,6,7) (0,7) {19,35,12,42,55,27,40,46} 182 + [.#.###] (0,2,3,5) (1,3,4,5) (0,1,2,4) (1,5) (1,2,3,5) {29,50,39,38,35,43} 183 + [..#..##.#] (2,3,8) (1,5) (1,4,5,6,7,8) (1,3,4,5,7,8) (2,3,4,5,7) (0,1,3,4) (0,1,3,4,6) (0,2,3,4,5,7,8) {28,173,36,70,64,171,30,46,60} 184 + [.##.] (1) (0,2,3) (1,2) {3,11,10,3} 185 + [#.#....##] (1,2,3,8) (1,2,3,4,5) (0,1,3,7) (0,1,2,3,6,7) (0,1,2,3,7,8) (4) (1,2,3,4,5,7,8) {27,49,45,49,31,19,6,42,35} 186 + [##..] (1) (0,1,2) (2,3) (0) {22,19,28,9} 187 + [##..###] (1,2,3,4,5) (2,3,4,5) (0,2,4,5) (1,4) (0,2,4) (3) (0,1,3,6) (1,3,6) {37,171,27,179,33,24,158} 188 + [.####.] (1,2,3,4) (0,4) (0,1,3) (1,2,3) (2,3,4,5) (1,2,3,4,5) (0,2) {44,38,47,45,44,21} 189 + [.##.#...#] (1,6,8) (2,3,4,5,8) (0,1,2,3,6,8) (0,2,3,4,7,8) (5,7) (0,1,2,3,4,5,8) (1,3,4,5) (0,1,4) (1,2,3,6,7,8) (4,5,6,7) (0,1,2,4,5,6,8) {59,172,61,70,85,56,141,54,164} 190 + [.##......] (7,8) (3,5) (1,2) (1,3,5,6,8) (2,3,4,5,6) (0,4,7,8) (2,4) (1,2,3,4,5,6,7) {4,35,43,56,44,56,47,41,33} 191 + [#....#....] (0,1,2,3,4,5,7,8,9) (2,4,5,9) (3,5,6) (3,9) (0,3,5,9) (0,1,4) (0,1,3,5,6,8) (0,1,2,4,5,6,7,8) (0,2,5,6,7,8,9) (0,1,3,6,8,9) (4,6,8) {217,50,191,56,54,220,203,176,191,209} 192 + [.#..#.] (0,2,4) (1,3) (1,3,5) (1,2,3,5) (0,1,2,3) (3) (0,3,4,5) {145,21,28,151,139,132} 193 + [#..###] (3,4) (2) (1,3,5) (1,2,3,5) (0,1,2) (0,2,4,5) (0,2,3,4) (0,2,3) {42,19,63,44,38,13} 194 + [#.#......] (0,2,4,6,7) (0,3,4,6,8) (0,3,4,5,8) (0,1,4,6) (2,4,5) (2,3,5) (1,3,5,7) (3,8) {32,17,39,53,46,56,18,25,25} 195 + [###......#] (0,1,2,5) (5,6,9) (0,2,8,9) (0,2,3,5) (2) (0,1,2,3,4,5,6,7) (0,1,2,3,5,6,7,9) (7) (0,3,4) {73,56,84,44,19,78,52,49,9,44} 196 + [#.##] (1,2) (2) (0,1,3) (0,1,2) {21,27,190,4} 197 + [...#..#.##] (0,2,3,4,6,7,8,9) (0,2,3,4,8,9) (0,1,2,5,6,8,9) (2,3) (0,1,2,5,6,7,8) (1,2,5,8) (0,1,2,3,5,7,8,9) (2,7) (0,3,8,9) (2,4,9) {36,32,70,37,11,32,14,33,37,42}
+934
vis/10/generate.ts
··· 1 + const scriptDir = import.meta.dir; 2 + const file = await Bun.file(`${scriptDir}/../../shared/10/input.txt`).text(); 3 + 4 + interface Machine { 5 + target: boolean[]; 6 + buttons: number[][]; 7 + joltages: number[]; 8 + } 9 + 10 + // Parse input 11 + const machines: Machine[] = file 12 + .trim() 13 + .split("\n") 14 + .map((line) => { 15 + const lightsMatch = line.match(/\[([.#]+)\]/); 16 + const target = lightsMatch![1].split("").map((c) => c === "#"); 17 + 18 + const buttonsMatch = line.matchAll(/\(([0-9,]+)\)/g); 19 + const buttons: number[][] = []; 20 + for (const match of buttonsMatch) { 21 + const indices = match[1].split(",").map(Number); 22 + buttons.push(indices); 23 + } 24 + 25 + const joltagesMatch = line.match(/\{([0-9,]+)\}/); 26 + const joltages = joltagesMatch ? joltagesMatch[1].split(",").map(Number) : []; 27 + 28 + return { target, buttons, joltages }; 29 + }); 30 + 31 + // Solve one machine 32 + function solveMachine(machine: Machine): { solution: number[]; steps: any[] } { 33 + const n = machine.target.length; 34 + const m = machine.buttons.length; 35 + 36 + const matrix: number[][] = []; 37 + for (let i = 0; i < n; i++) { 38 + const row: number[] = []; 39 + for (let j = 0; j < m; j++) { 40 + row.push(machine.buttons[j].includes(i) ? 1 : 0); 41 + } 42 + row.push(machine.target[i] ? 1 : 0); 43 + matrix.push(row); 44 + } 45 + 46 + const steps = [JSON.parse(JSON.stringify(matrix))]; 47 + const pivotCols: number[] = []; 48 + 49 + for (let col = 0; col < m; col++) { 50 + let pivotRow = -1; 51 + for (let row = pivotCols.length; row < n; row++) { 52 + if (matrix[row][col] === 1) { 53 + pivotRow = row; 54 + break; 55 + } 56 + } 57 + 58 + if (pivotRow === -1) continue; 59 + 60 + const targetRow = pivotCols.length; 61 + if (pivotRow !== targetRow) { 62 + [matrix[pivotRow], matrix[targetRow]] = [ 63 + matrix[targetRow], 64 + matrix[pivotRow], 65 + ]; 66 + steps.push(JSON.parse(JSON.stringify(matrix))); 67 + } 68 + 69 + pivotCols.push(col); 70 + 71 + for (let row = 0; row < n; row++) { 72 + if (row !== targetRow && matrix[row][col] === 1) { 73 + for (let c = 0; c <= m; c++) { 74 + matrix[row][c] ^= matrix[targetRow][c]; 75 + } 76 + steps.push(JSON.parse(JSON.stringify(matrix))); 77 + } 78 + } 79 + } 80 + 81 + // Identify free variables 82 + const isPivot = new Array(m).fill(false); 83 + pivotCols.forEach((col) => (isPivot[col] = true)); 84 + const freeVars: number[] = []; 85 + for (let j = 0; j < m; j++) { 86 + if (!isPivot[j]) freeVars.push(j); 87 + } 88 + 89 + // Try all combinations of free variables to find minimum 90 + let minPresses = Infinity; 91 + let bestSolution: number[] = []; 92 + 93 + const numCombinations = 1 << freeVars.length; 94 + for (let combo = 0; combo < numCombinations; combo++) { 95 + const solution: number[] = new Array(m).fill(0); 96 + 97 + // Set free variables according to combo 98 + for (let i = 0; i < freeVars.length; i++) { 99 + solution[freeVars[i]] = (combo >> i) & 1; 100 + } 101 + 102 + // Back-substitution for pivot variables 103 + for (let i = pivotCols.length - 1; i >= 0; i--) { 104 + const col = pivotCols[i]; 105 + solution[col] = matrix[i][m]; 106 + 107 + for (let j = col + 1; j < m; j++) { 108 + if (matrix[i][j] === 1) { 109 + solution[col] ^= solution[j]; 110 + } 111 + } 112 + } 113 + 114 + const presses = solution.reduce((sum, x) => sum + x, 0); 115 + if (presses < minPresses) { 116 + minPresses = presses; 117 + bestSolution = solution; 118 + } 119 + } 120 + 121 + return { solution: bestSolution, steps }; 122 + } 123 + 124 + // Solve Part 2: joltage configuration 125 + function solveMachinePart2(machine: Machine): number[] { 126 + const n = machine.joltages.length; 127 + const m = machine.buttons.length; 128 + const target = machine.joltages; 129 + 130 + // Build coefficient matrix A 131 + const A: number[][] = []; 132 + for (let i = 0; i < n; i++) { 133 + const row: number[] = []; 134 + for (let j = 0; j < m; j++) { 135 + row.push(machine.buttons[j].includes(i) ? 1 : 0); 136 + } 137 + A.push(row); 138 + } 139 + 140 + // Build augmented matrix [A | b] 141 + const matrix: number[][] = []; 142 + for (let i = 0; i < n; i++) { 143 + matrix.push([...A[i], target[i]]); 144 + } 145 + 146 + // Gaussian elimination 147 + const pivotCols: number[] = []; 148 + for (let col = 0; col < m; col++) { 149 + let pivotRow = -1; 150 + for (let row = pivotCols.length; row < n; row++) { 151 + if (matrix[row][col] !== 0) { 152 + pivotRow = row; 153 + break; 154 + } 155 + } 156 + 157 + if (pivotRow === -1) continue; 158 + 159 + const targetRow = pivotCols.length; 160 + if (pivotRow !== targetRow) { 161 + [matrix[pivotRow], matrix[targetRow]] = [ 162 + matrix[targetRow], 163 + matrix[pivotRow], 164 + ]; 165 + } 166 + 167 + pivotCols.push(col); 168 + 169 + // Scale row so pivot is 1 170 + const pivot = matrix[targetRow][col]; 171 + for (let c = 0; c <= m; c++) { 172 + matrix[targetRow][c] /= pivot; 173 + } 174 + 175 + // Eliminate column in other rows 176 + for (let row = 0; row < n; row++) { 177 + if (row !== targetRow && matrix[row][col] !== 0) { 178 + const factor = matrix[row][col]; 179 + for (let c = 0; c <= m; c++) { 180 + matrix[row][c] -= factor * matrix[targetRow][c]; 181 + } 182 + } 183 + } 184 + } 185 + 186 + // Identify free variables 187 + const isPivot = new Array(m).fill(false); 188 + pivotCols.forEach((col) => (isPivot[col] = true)); 189 + const freeVars: number[] = []; 190 + for (let j = 0; j < m; j++) { 191 + if (!isPivot[j]) freeVars.push(j); 192 + } 193 + 194 + if (freeVars.length > 15) { 195 + return new Array(m).fill(0); 196 + } 197 + 198 + let minPresses = Infinity; 199 + let bestSolution: number[] = []; 200 + 201 + const maxTarget = Math.max(...target); 202 + const maxFreeValue = Math.min(maxTarget * 2, 200); 203 + 204 + function searchFreeVars(idx: number, currentSol: number[]) { 205 + if (idx === freeVars.length) { 206 + const sol = [...currentSol]; 207 + let valid = true; 208 + for (let i = pivotCols.length - 1; i >= 0; i--) { 209 + const col = pivotCols[i]; 210 + let val = matrix[i][m]; 211 + for (let j = col + 1; j < m; j++) { 212 + val -= matrix[i][j] * sol[j]; 213 + } 214 + sol[col] = val; 215 + 216 + if (val < -1e-9 || Math.abs(val - Math.round(val)) > 1e-9) { 217 + valid = false; 218 + break; 219 + } 220 + } 221 + 222 + if (valid) { 223 + const intSol = sol.map((x) => Math.round(Math.max(0, x))); 224 + const presses = intSol.reduce((sum, x) => sum + x, 0); 225 + if (presses < minPresses) { 226 + minPresses = presses; 227 + bestSolution = intSol; 228 + } 229 + } 230 + return; 231 + } 232 + 233 + for (let val = 0; val <= maxFreeValue; val++) { 234 + currentSol[freeVars[idx]] = val; 235 + searchFreeVars(idx + 1, currentSol); 236 + } 237 + } 238 + 239 + searchFreeVars(0, new Array(m).fill(0)); 240 + 241 + return bestSolution; 242 + } 243 + 244 + const machinesData = JSON.stringify(machines); 245 + 246 + const html = `<!DOCTYPE html> 247 + <html lang="en"> 248 + <head> 249 + <meta charset="UTF-8"> 250 + <meta name="viewport" content="width=device-width, initial-scale=1.0"> 251 + <title>AoC 2025 Day 10 - Factory</title> 252 + <style> 253 + * { 254 + box-sizing: border-box; 255 + } 256 + body { 257 + background: #1e1e2e; 258 + color: #cdd6f4; 259 + font-family: "Source Code Pro", monospace; 260 + font-size: 14pt; 261 + font-weight: 300; 262 + padding: 20px; 263 + display: flex; 264 + flex-direction: column; 265 + align-items: center; 266 + min-height: 100vh; 267 + margin: 0; 268 + } 269 + h1 { 270 + color: #a6e3a1; 271 + text-shadow: 0 0 2px #a6e3a1, 0 0 5px #a6e3a1; 272 + margin-bottom: 10px; 273 + font-size: 1em; 274 + font-weight: normal; 275 + } 276 + .controls { 277 + background: #11111b; 278 + border: 1px solid #313244; 279 + padding: 15px; 280 + margin: 15px 0; 281 + max-width: 1200px; 282 + border-radius: 4px; 283 + width: 100%; 284 + } 285 + .control-row { 286 + display: flex; 287 + gap: 15px; 288 + align-items: center; 289 + margin-bottom: 15px; 290 + flex-wrap: wrap; 291 + justify-content: center; 292 + } 293 + .control-row:last-child { 294 + margin-bottom: 0; 295 + } 296 + button { 297 + background: #11111b; 298 + color: #a6e3a1; 299 + border: 1px solid #313244; 300 + padding: 8px 16px; 301 + cursor: pointer; 302 + font-family: inherit; 303 + font-size: 14px; 304 + border-radius: 3px; 305 + } 306 + button:hover { 307 + background: #181825; 308 + } 309 + button:disabled { 310 + opacity: 0.5; 311 + cursor: not-allowed; 312 + } 313 + .speed-control { 314 + display: flex; 315 + align-items: center; 316 + gap: 8px; 317 + font-size: 13px; 318 + color: #a6adc8; 319 + } 320 + .speed-control input[type="range"] { 321 + width: 120px; 322 + height: 6px; 323 + background: #313244; 324 + outline: none; 325 + -webkit-appearance: none; 326 + border-radius: 3px; 327 + } 328 + .speed-control input[type="range"]::-webkit-slider-thumb { 329 + -webkit-appearance: none; 330 + appearance: none; 331 + width: 14px; 332 + height: 14px; 333 + background: #a6e3a1; 334 + cursor: pointer; 335 + border-radius: 50%; 336 + border: 1px solid #313244; 337 + } 338 + .speed-control input[type="range"]::-moz-range-thumb { 339 + width: 14px; 340 + height: 14px; 341 + background: #a6e3a1; 342 + cursor: pointer; 343 + border-radius: 50%; 344 + border: 1px solid #313244; 345 + } 346 + .machine-display { 347 + background: #11111b; 348 + border: 1px solid #313244; 349 + padding: 20px; 350 + margin: 20px 0; 351 + max-width: 1200px; 352 + border-radius: 4px; 353 + width: 100%; 354 + } 355 + .lights { 356 + display: flex; 357 + gap: 10px; 358 + justify-content: center; 359 + margin: 20px 0; 360 + flex-wrap: wrap; 361 + } 362 + .light { 363 + width: 50px; 364 + height: 50px; 365 + border-radius: 50%; 366 + border: 2px solid #313244; 367 + display: flex; 368 + flex-direction: column; 369 + align-items: center; 370 + justify-content: center; 371 + font-size: 9px; 372 + transition: all 0.3s ease; 373 + overflow: hidden; 374 + text-align: center; 375 + padding: 3px; 376 + line-height: 1.1; 377 + } 378 + .light.off { 379 + background: #1e1e2e; 380 + color: #6c7086; 381 + } 382 + .light.on { 383 + background: #a6e3a1; 384 + color: #1e1e2e; 385 + box-shadow: 0 0 10px #a6e3a1; 386 + } 387 + .light.target { 388 + border-color: #f9e2af; 389 + border-width: 3px; 390 + } 391 + .buttons-grid { 392 + display: grid; 393 + grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); 394 + gap: 10px; 395 + margin: 20px 0; 396 + } 397 + .button-display { 398 + background: #181825; 399 + border: 1px solid #313244; 400 + padding: 10px; 401 + border-radius: 4px; 402 + text-align: center; 403 + cursor: pointer; 404 + transition: all 0.2s ease; 405 + } 406 + .button-display:hover { 407 + background: #313244; 408 + } 409 + .button-display.pressed { 410 + background: #a6e3a1; 411 + color: #1e1e2e; 412 + border-color: #a6e3a1; 413 + } 414 + .button-label { 415 + font-size: 12px; 416 + margin-bottom: 5px; 417 + color: #a6adc8; 418 + } 419 + .button-toggles { 420 + font-size: 11px; 421 + color: #6c7086; 422 + } 423 + .stats { 424 + background: #11111b; 425 + border: 1px solid #313244; 426 + padding: 10px 15px; 427 + margin: 10px 0; 428 + max-width: 1200px; 429 + border-radius: 4px; 430 + text-align: center; 431 + font-size: 13px; 432 + color: #a6adc8; 433 + width: 100%; 434 + margin-top: auto; 435 + } 436 + .info { 437 + margin: 10px 0; 438 + text-align: center; 439 + color: #f9e2af; 440 + } 441 + a { 442 + text-decoration: none; 443 + color: #a6e3a1; 444 + outline: 0; 445 + } 446 + a:hover, a:focus { 447 + text-decoration: underline; 448 + } 449 + </style> 450 + </head> 451 + <body> 452 + <h1>AoC 2025 Day 10 - Factory Machines</h1> 453 + 454 + <div class="controls"> 455 + <div class="control-row"> 456 + <button id="togglePart" style="color: #f9e2af; font-weight: bold;">Part 1</button> 457 + <button id="prev">← Previous Machine</button> 458 + <button id="play">▶ Play</button> 459 + <button id="next">Next Machine →</button> 460 + <button id="reset">↺ Reset</button> 461 + <div class="speed-control"> 462 + <label for="speed">Speed:</label> 463 + <input type="range" id="speed" min="1" max="25" value="5" step="1"> 464 + <span id="speedValue">5x</span> 465 + </div> 466 + </div> 467 + </div> 468 + 469 + <div class="info" id="machineInfo">Machine 1 / ${machines.length}</div> 470 + 471 + <div class="machine-display"> 472 + <h2 id="displayTitle" style="text-align: center; color: #89b4fa; font-size: 18px; margin-bottom: 20px;">Indicator Lights</h2> 473 + <div class="lights" id="lights"></div> 474 + 475 + <h2 style="text-align: center; color: #89b4fa; font-size: 18px; margin: 30px 0 20px 0;">Buttons</h2> 476 + <div class="buttons-grid" id="buttons"></div> 477 + </div> 478 + 479 + <div class="stats"> 480 + <div id="statsInfo">Buttons Pressed: 0 | Target: ? | Accumulated Total: 0</div> 481 + <div style="margin-top: 5px; font-size: 11px;"><a href="../index.html">[Return to Index]</a></div> 482 + </div> 483 + 484 + <script type="module"> 485 + const machines = ${machinesData}; 486 + 487 + let currentMode = 1; // 1 or 2 488 + let currentMachineIndex = 0; 489 + let currentState = []; 490 + let buttonStates = []; // Track which buttons are "on" (pressed odd number of times) 491 + let isPlaying = false; 492 + let showingSolution = false; 493 + let solutionSteps = []; 494 + let currentStep = 0; 495 + let solvedMachines = new Set(); // Track which machines have been solved 496 + let animationSpeed = 200; // ms between button presses (default 5x) 497 + 498 + 499 + function renderMachine() { 500 + const machine = machines[currentMachineIndex]; 501 + 502 + // Update title based on mode 503 + const titleEl = document.getElementById('displayTitle'); 504 + if (currentMode === 1) { 505 + titleEl.textContent = 'Indicator Lights'; 506 + titleEl.style.color = '#89b4fa'; 507 + } else { 508 + titleEl.textContent = 'Joltage Counters'; 509 + titleEl.style.color = '#f9e2af'; 510 + } 511 + 512 + // Render lights or counters 513 + const lightsDiv = document.getElementById('lights'); 514 + lightsDiv.innerHTML = ''; 515 + 516 + if (currentMode === 1) { 517 + // Part 1: Indicator lights 518 + machine.target.forEach((target, i) => { 519 + const light = document.createElement('div'); 520 + light.className = \`light \${currentState[i] ? 'on' : 'off'} \${target ? 'target' : ''}\`; 521 + light.textContent = i; 522 + lightsDiv.appendChild(light); 523 + }); 524 + } else { 525 + // Part 2: Joltage counters 526 + machine.joltages.forEach((target, i) => { 527 + const counter = document.createElement('div'); 528 + const current = currentState[i] || 0; 529 + const isTarget = current === target; 530 + counter.className = \`light \${isTarget ? 'on' : 'off'} \${true ? 'target' : ''}\`; 531 + counter.innerHTML = \`<div style="font-size: 7px; opacity: 0.7;">[\${i}]</div><div style="font-size: 10px; font-weight: bold;">\${current}/<span style="color: #f9e2af;">\${target}</span></div>\`; 532 + lightsDiv.appendChild(counter); 533 + }); 534 + } 535 + 536 + // Render buttons 537 + const buttonsDiv = document.getElementById('buttons'); 538 + buttonsDiv.innerHTML = ''; 539 + machine.buttons.forEach((toggles, i) => { 540 + const btn = document.createElement('div'); 541 + const pressCount = buttonStates[i] || 0; 542 + const isPressed = currentMode === 1 ? (pressCount % 2 === 1) : (pressCount > 0); 543 + btn.className = \`button-display \${isPressed ? 'pressed' : ''}\`; 544 + btn.innerHTML = \` 545 + <div class="button-label">Button \${i}\${currentMode === 2 ? \` (\${pressCount})\` : ''}</div> 546 + <div class="button-toggles">Affects: \${toggles.join(', ')}</div> 547 + \`; 548 + btn.addEventListener('click', () => toggleButton(i)); 549 + buttonsDiv.appendChild(btn); 550 + }); 551 + } 552 + 553 + function toggleButton(buttonIndex) { 554 + const machine = machines[currentMachineIndex]; 555 + 556 + if (currentMode === 1) { 557 + // Part 1: Toggle lights (XOR) 558 + buttonStates[buttonIndex] = buttonStates[buttonIndex] ? 0 : 1; 559 + machine.buttons[buttonIndex].forEach(lightIndex => { 560 + currentState[lightIndex] = !currentState[lightIndex]; 561 + }); 562 + } else { 563 + // Part 2: Increment counters 564 + buttonStates[buttonIndex] = (buttonStates[buttonIndex] || 0) + 1; 565 + machine.buttons[buttonIndex].forEach(counterIndex => { 566 + currentState[counterIndex] = (currentState[counterIndex] || 0) + 1; 567 + }); 568 + } 569 + 570 + renderMachine(); 571 + updateStats(); 572 + } 573 + 574 + function solveMachine(machine) { 575 + const n = machine.target.length; 576 + const m = machine.buttons.length; 577 + 578 + const matrix = []; 579 + for (let i = 0; i < n; i++) { 580 + const row = []; 581 + for (let j = 0; j < m; j++) { 582 + row.push(machine.buttons[j].includes(i) ? 1 : 0); 583 + } 584 + row.push(machine.target[i] ? 1 : 0); 585 + matrix.push(row); 586 + } 587 + 588 + const pivotCols = []; 589 + for (let col = 0; col < m; col++) { 590 + let pivotRow = -1; 591 + for (let row = pivotCols.length; row < n; row++) { 592 + if (matrix[row][col] === 1) { 593 + pivotRow = row; 594 + break; 595 + } 596 + } 597 + 598 + if (pivotRow === -1) continue; 599 + 600 + const targetRow = pivotCols.length; 601 + if (pivotRow !== targetRow) { 602 + [matrix[pivotRow], matrix[targetRow]] = [matrix[targetRow], matrix[pivotRow]]; 603 + } 604 + 605 + pivotCols.push(col); 606 + 607 + for (let row = 0; row < n; row++) { 608 + if (row !== targetRow && matrix[row][col] === 1) { 609 + for (let c = 0; c <= m; c++) { 610 + matrix[row][c] ^= matrix[targetRow][c]; 611 + } 612 + } 613 + } 614 + } 615 + 616 + const solution = new Array(m).fill(0); 617 + for (let i = pivotCols.length - 1; i >= 0; i--) { 618 + const col = pivotCols[i]; 619 + solution[col] = matrix[i][m]; 620 + for (let j = col + 1; j < m; j++) { 621 + if (matrix[i][j] === 1) { 622 + solution[col] ^= solution[j]; 623 + } 624 + } 625 + } 626 + 627 + return solution; 628 + } 629 + 630 + // Part 2 solver (copy of server-side logic) 631 + function solveMachinePart2(machine) { 632 + const n = machine.joltages.length; 633 + const m = machine.buttons.length; 634 + const target = machine.joltages; 635 + 636 + const A = []; 637 + for (let i = 0; i < n; i++) { 638 + const row = []; 639 + for (let j = 0; j < m; j++) { 640 + row.push(machine.buttons[j].includes(i) ? 1 : 0); 641 + } 642 + A.push(row); 643 + } 644 + 645 + const matrix = []; 646 + for (let i = 0; i < n; i++) { 647 + matrix.push([...A[i], target[i]]); 648 + } 649 + 650 + const pivotCols = []; 651 + for (let col = 0; col < m; col++) { 652 + let pivotRow = -1; 653 + for (let row = pivotCols.length; row < n; row++) { 654 + if (matrix[row][col] !== 0) { 655 + pivotRow = row; 656 + break; 657 + } 658 + } 659 + 660 + if (pivotRow === -1) continue; 661 + 662 + const targetRow = pivotCols.length; 663 + if (pivotRow !== targetRow) { 664 + [matrix[pivotRow], matrix[targetRow]] = [matrix[targetRow], matrix[pivotRow]]; 665 + } 666 + 667 + pivotCols.push(col); 668 + 669 + const pivot = matrix[targetRow][col]; 670 + for (let c = 0; c <= m; c++) { 671 + matrix[targetRow][c] /= pivot; 672 + } 673 + 674 + for (let row = 0; row < n; row++) { 675 + if (row !== targetRow && matrix[row][col] !== 0) { 676 + const factor = matrix[row][col]; 677 + for (let c = 0; c <= m; c++) { 678 + matrix[row][c] -= factor * matrix[targetRow][c]; 679 + } 680 + } 681 + } 682 + } 683 + 684 + const isPivot = new Array(m).fill(false); 685 + pivotCols.forEach(col => isPivot[col] = true); 686 + const freeVars = []; 687 + for (let j = 0; j < m; j++) { 688 + if (!isPivot[j]) freeVars.push(j); 689 + } 690 + 691 + if (freeVars.length > 8) { // Reduced limit for browser 692 + return new Array(m).fill(0); 693 + } 694 + 695 + let minPresses = Infinity; 696 + let bestSolution = []; 697 + 698 + const maxTarget = Math.max(...target); 699 + const maxFreeValue = Math.min(maxTarget * 2, 100); 700 + 701 + function searchFreeVars(idx, currentSol) { 702 + if (idx === freeVars.length) { 703 + const sol = [...currentSol]; 704 + let valid = true; 705 + for (let i = pivotCols.length - 1; i >= 0; i--) { 706 + const col = pivotCols[i]; 707 + let val = matrix[i][m]; 708 + for (let j = col + 1; j < m; j++) { 709 + val -= matrix[i][j] * sol[j]; 710 + } 711 + sol[col] = val; 712 + 713 + if (val < -1e-9 || Math.abs(val - Math.round(val)) > 1e-9) { 714 + valid = false; 715 + break; 716 + } 717 + } 718 + 719 + if (valid) { 720 + const intSol = sol.map(x => Math.round(Math.max(0, x))); 721 + const presses = intSol.reduce((sum, x) => sum + x, 0); 722 + if (presses < minPresses) { 723 + minPresses = presses; 724 + bestSolution = intSol; 725 + } 726 + } 727 + return; 728 + } 729 + 730 + for (let val = 0; val <= maxFreeValue; val++) { 731 + currentSol[freeVars[idx]] = val; 732 + searchFreeVars(idx + 1, currentSol); 733 + } 734 + } 735 + 736 + searchFreeVars(0, new Array(m).fill(0)); 737 + return bestSolution; 738 + } 739 + 740 + function getCurrentSolution() { 741 + const machine = machines[currentMachineIndex]; 742 + return currentMode === 1 ? solveMachine(machine) : solveMachinePart2(machine); 743 + } 744 + 745 + function showSolution() { 746 + const machine = machines[currentMachineIndex]; 747 + const solution = getCurrentSolution(); 748 + 749 + if (currentMode === 1) { 750 + currentState = new Array(machine.target.length).fill(false); 751 + buttonStates = [...solution].map(v => v === 1); 752 + 753 + solution.forEach((shouldPress, buttonIndex) => { 754 + if (shouldPress === 1) { 755 + machine.buttons[buttonIndex].forEach(lightIndex => { 756 + currentState[lightIndex] = !currentState[lightIndex]; 757 + }); 758 + } 759 + }); 760 + } else { 761 + currentState = new Array(machine.joltages.length).fill(0); 762 + buttonStates = [...solution]; 763 + 764 + solution.forEach((pressCount, buttonIndex) => { 765 + for (let p = 0; p < pressCount; p++) { 766 + machine.buttons[buttonIndex].forEach(counterIndex => { 767 + currentState[counterIndex]++; 768 + }); 769 + } 770 + }); 771 + } 772 + 773 + showingSolution = true; 774 + renderMachine(); 775 + updateStats(); 776 + } 777 + 778 + function updateStats() { 779 + const machine = machines[currentMachineIndex]; 780 + const solution = getCurrentSolution(); 781 + const minPresses = solution.reduce((a, b) => a + b, 0); 782 + 783 + let totalPressed; 784 + if (currentMode === 1) { 785 + totalPressed = buttonStates.filter(b => b).length; 786 + } else { 787 + totalPressed = buttonStates.reduce((sum, count) => sum + (count || 0), 0); 788 + } 789 + 790 + // Calculate accumulated total for solved machines 791 + let accumulatedTotal = 0; 792 + solvedMachines.forEach(idx => { 793 + const m = machines[idx]; 794 + const sol = currentMode === 1 ? solveMachine(m) : solveMachinePart2(m); 795 + accumulatedTotal += sol.reduce((a, b) => a + b, 0); 796 + }); 797 + 798 + document.getElementById('statsInfo').textContent = \`Buttons Pressed: \${totalPressed} | Target: \${minPresses} | Accumulated Total: \${accumulatedTotal}\`; 799 + document.getElementById('machineInfo').textContent = \`Machine \${currentMachineIndex + 1} / \${machines.length}\`; 800 + } 801 + 802 + document.getElementById('prev').addEventListener('click', () => { 803 + if (currentMachineIndex > 0) { 804 + isPlaying = false; 805 + document.getElementById('play').textContent = '▶ Play'; 806 + currentMachineIndex--; 807 + initMachine(); 808 + } 809 + }); 810 + 811 + document.getElementById('next').addEventListener('click', () => { 812 + if (currentMachineIndex < machines.length - 1) { 813 + isPlaying = false; 814 + document.getElementById('play').textContent = '▶ Play'; 815 + currentMachineIndex++; 816 + initMachine(); 817 + } 818 + }); 819 + 820 + document.getElementById('reset').addEventListener('click', initMachine); 821 + 822 + document.getElementById('togglePart').addEventListener('click', () => { 823 + currentMode = currentMode === 1 ? 2 : 1; 824 + document.getElementById('togglePart').textContent = \`Part \${currentMode}\`; 825 + solvedMachines.clear(); 826 + initMachine(); 827 + }); 828 + 829 + document.getElementById('play').addEventListener('click', () => { 830 + isPlaying = !isPlaying; 831 + document.getElementById('play').textContent = isPlaying ? '⏸ Pause' : '▶ Play'; 832 + if (isPlaying) { 833 + animateSolution(); 834 + } 835 + }); 836 + 837 + // Speed control 838 + const speedSlider = document.getElementById('speed'); 839 + const speedValue = document.getElementById('speedValue'); 840 + speedSlider.addEventListener('input', (e) => { 841 + const speed = parseInt(e.target.value); 842 + speedValue.textContent = \`\${speed}x\`; 843 + // Faster speed = shorter delay (inverse relationship) 844 + animationSpeed = 1000 / speed; 845 + }); 846 + 847 + function animateSolution() { 848 + if (!isPlaying) return; 849 + 850 + if (currentStep < solutionSteps.length) { 851 + // Toggle the next button in the solution 852 + const buttonIndex = solutionSteps[currentStep]; 853 + toggleButton(buttonIndex); 854 + currentStep++; 855 + 856 + // Use 10x faster speed for Part 2 (more button presses) 857 + const delay = currentMode === 2 ? animationSpeed / 10 : animationSpeed; 858 + setTimeout(animateSolution, delay); 859 + } else { 860 + // Mark this machine as solved 861 + const machine = machines[currentMachineIndex]; 862 + let isCorrect; 863 + if (currentMode === 1) { 864 + isCorrect = currentState.every((state, i) => state === machine.target[i]); 865 + } else { 866 + isCorrect = currentState.every((state, i) => state === machine.joltages[i]); 867 + } 868 + 869 + if (isCorrect) { 870 + solvedMachines.add(currentMachineIndex); 871 + updateStats(); 872 + } 873 + 874 + // Current machine done, move to next immediately 875 + if (currentMachineIndex < machines.length - 1) { 876 + if (isPlaying) { 877 + currentMachineIndex++; 878 + initMachine(); 879 + setTimeout(animateSolution, animationSpeed); 880 + } 881 + } else { 882 + // All done 883 + isPlaying = false; 884 + document.getElementById('play').textContent = '▶ Play'; 885 + setTimeout(() => { 886 + currentMachineIndex = 0; 887 + initMachine(); 888 + }, animationSpeed * 4); 889 + } 890 + } 891 + } 892 + 893 + function initMachine() { 894 + const machine = machines[currentMachineIndex]; 895 + showingSolution = false; 896 + currentStep = 0; 897 + 898 + if (currentMode === 1) { 899 + // Part 1 900 + currentState = new Array(machine.target.length).fill(false); 901 + buttonStates = new Array(machine.buttons.length).fill(0); 902 + 903 + const solution = solveMachine(machine); 904 + solutionSteps = []; 905 + solution.forEach((shouldPress, idx) => { 906 + if (shouldPress === 1) { 907 + solutionSteps.push(idx); 908 + } 909 + }); 910 + } else { 911 + // Part 2 912 + currentState = new Array(machine.joltages.length).fill(0); 913 + buttonStates = new Array(machine.buttons.length).fill(0); 914 + 915 + const solution = solveMachinePart2(machine); 916 + solutionSteps = []; 917 + solution.forEach((pressCount, idx) => { 918 + for (let i = 0; i < pressCount; i++) { 919 + solutionSteps.push(idx); 920 + } 921 + }); 922 + } 923 + 924 + renderMachine(); 925 + updateStats(); 926 + } 927 + 928 + // Initialize 929 + initMachine(); 930 + </script> 931 + </body> 932 + </html>`; 933 + 934 + await Bun.write(`${scriptDir}/index.html`, html);
+687
vis/10/index.html
··· 1 + <!DOCTYPE html> 2 + <html lang="en"> 3 + <head> 4 + <meta charset="UTF-8"> 5 + <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 + <title>AoC 2025 Day 10 - Factory</title> 7 + <style> 8 + * { 9 + box-sizing: border-box; 10 + } 11 + body { 12 + background: #1e1e2e; 13 + color: #cdd6f4; 14 + font-family: "Source Code Pro", monospace; 15 + font-size: 14pt; 16 + font-weight: 300; 17 + padding: 20px; 18 + display: flex; 19 + flex-direction: column; 20 + align-items: center; 21 + min-height: 100vh; 22 + margin: 0; 23 + } 24 + h1 { 25 + color: #a6e3a1; 26 + text-shadow: 0 0 2px #a6e3a1, 0 0 5px #a6e3a1; 27 + margin-bottom: 10px; 28 + font-size: 1em; 29 + font-weight: normal; 30 + } 31 + .controls { 32 + background: #11111b; 33 + border: 1px solid #313244; 34 + padding: 15px; 35 + margin: 15px 0; 36 + max-width: 1200px; 37 + border-radius: 4px; 38 + width: 100%; 39 + } 40 + .control-row { 41 + display: flex; 42 + gap: 15px; 43 + align-items: center; 44 + margin-bottom: 15px; 45 + flex-wrap: wrap; 46 + justify-content: center; 47 + } 48 + .control-row:last-child { 49 + margin-bottom: 0; 50 + } 51 + button { 52 + background: #11111b; 53 + color: #a6e3a1; 54 + border: 1px solid #313244; 55 + padding: 8px 16px; 56 + cursor: pointer; 57 + font-family: inherit; 58 + font-size: 14px; 59 + border-radius: 3px; 60 + } 61 + button:hover { 62 + background: #181825; 63 + } 64 + button:disabled { 65 + opacity: 0.5; 66 + cursor: not-allowed; 67 + } 68 + .speed-control { 69 + display: flex; 70 + align-items: center; 71 + gap: 8px; 72 + font-size: 13px; 73 + color: #a6adc8; 74 + } 75 + .speed-control input[type="range"] { 76 + width: 120px; 77 + height: 6px; 78 + background: #313244; 79 + outline: none; 80 + -webkit-appearance: none; 81 + border-radius: 3px; 82 + } 83 + .speed-control input[type="range"]::-webkit-slider-thumb { 84 + -webkit-appearance: none; 85 + appearance: none; 86 + width: 14px; 87 + height: 14px; 88 + background: #a6e3a1; 89 + cursor: pointer; 90 + border-radius: 50%; 91 + border: 1px solid #313244; 92 + } 93 + .speed-control input[type="range"]::-moz-range-thumb { 94 + width: 14px; 95 + height: 14px; 96 + background: #a6e3a1; 97 + cursor: pointer; 98 + border-radius: 50%; 99 + border: 1px solid #313244; 100 + } 101 + .machine-display { 102 + background: #11111b; 103 + border: 1px solid #313244; 104 + padding: 20px; 105 + margin: 20px 0; 106 + max-width: 1200px; 107 + border-radius: 4px; 108 + width: 100%; 109 + } 110 + .lights { 111 + display: flex; 112 + gap: 10px; 113 + justify-content: center; 114 + margin: 20px 0; 115 + flex-wrap: wrap; 116 + } 117 + .light { 118 + width: 50px; 119 + height: 50px; 120 + border-radius: 50%; 121 + border: 2px solid #313244; 122 + display: flex; 123 + flex-direction: column; 124 + align-items: center; 125 + justify-content: center; 126 + font-size: 9px; 127 + transition: all 0.3s ease; 128 + overflow: hidden; 129 + text-align: center; 130 + padding: 3px; 131 + line-height: 1.1; 132 + } 133 + .light.off { 134 + background: #1e1e2e; 135 + color: #6c7086; 136 + } 137 + .light.on { 138 + background: #a6e3a1; 139 + color: #1e1e2e; 140 + box-shadow: 0 0 10px #a6e3a1; 141 + } 142 + .light.target { 143 + border-color: #f9e2af; 144 + border-width: 3px; 145 + } 146 + .buttons-grid { 147 + display: grid; 148 + grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); 149 + gap: 10px; 150 + margin: 20px 0; 151 + } 152 + .button-display { 153 + background: #181825; 154 + border: 1px solid #313244; 155 + padding: 10px; 156 + border-radius: 4px; 157 + text-align: center; 158 + cursor: pointer; 159 + transition: all 0.2s ease; 160 + } 161 + .button-display:hover { 162 + background: #313244; 163 + } 164 + .button-display.pressed { 165 + background: #a6e3a1; 166 + color: #1e1e2e; 167 + border-color: #a6e3a1; 168 + } 169 + .button-label { 170 + font-size: 12px; 171 + margin-bottom: 5px; 172 + color: #a6adc8; 173 + } 174 + .button-toggles { 175 + font-size: 11px; 176 + color: #6c7086; 177 + } 178 + .stats { 179 + background: #11111b; 180 + border: 1px solid #313244; 181 + padding: 10px 15px; 182 + margin: 10px 0; 183 + max-width: 1200px; 184 + border-radius: 4px; 185 + text-align: center; 186 + font-size: 13px; 187 + color: #a6adc8; 188 + width: 100%; 189 + margin-top: auto; 190 + } 191 + .info { 192 + margin: 10px 0; 193 + text-align: center; 194 + color: #f9e2af; 195 + } 196 + a { 197 + text-decoration: none; 198 + color: #a6e3a1; 199 + outline: 0; 200 + } 201 + a:hover, a:focus { 202 + text-decoration: underline; 203 + } 204 + </style> 205 + </head> 206 + <body> 207 + <h1>AoC 2025 Day 10 - Factory Machines</h1> 208 + 209 + <div class="controls"> 210 + <div class="control-row"> 211 + <button id="togglePart" style="color: #f9e2af; font-weight: bold;">Part 1</button> 212 + <button id="prev">← Previous Machine</button> 213 + <button id="play">▶ Play</button> 214 + <button id="next">Next Machine →</button> 215 + <button id="reset">↺ Reset</button> 216 + <div class="speed-control"> 217 + <label for="speed">Speed:</label> 218 + <input type="range" id="speed" min="1" max="25" value="5" step="1"> 219 + <span id="speedValue">5x</span> 220 + </div> 221 + </div> 222 + </div> 223 + 224 + <div class="info" id="machineInfo">Machine 1 / 197</div> 225 + 226 + <div class="machine-display"> 227 + <h2 id="displayTitle" style="text-align: center; color: #89b4fa; font-size: 18px; margin-bottom: 20px;">Indicator Lights</h2> 228 + <div class="lights" id="lights"></div> 229 + 230 + <h2 style="text-align: center; color: #89b4fa; font-size: 18px; margin: 30px 0 20px 0;">Buttons</h2> 231 + <div class="buttons-grid" id="buttons"></div> 232 + </div> 233 + 234 + <div class="stats"> 235 + <div id="statsInfo">Buttons Pressed: 0 | Target: ? | Accumulated Total: 0</div> 236 + <div style="margin-top: 5px; font-size: 11px;"><a href="../index.html">[Return to Index]</a></div> 237 + </div> 238 + 239 + <script type="module"> 240 + const machines = [{"target":[false,false,false,true,true,true,false,true,false,true],"buttons":[[1,8],[0,4,5,6],[2,3,4,5,6,7,8],[5],[0,3,5],[0,1,5,6,7,9],[0,7,9],[0,1,2,3,5,6,8,9],[0,1,2,3,4,5,7,8,9],[0,2,4,6,7,8,9],[1,2,3,4,6,7,8,9],[0,9]],"joltages":[65,41,48,35,50,67,76,68,55,61]},{"target":[true,true,false,true,false,false],"buttons":[[0,2,3,5],[0,2,3,4],[0,1,2,4],[1,4],[2,3,4,5],[1,4,5],[0,3,4],[3]],"joltages":[56,191,62,82,236,212]},{"target":[false,false,false,true,false],"buttons":[[2,3,4],[1,2],[1,2,3,4],[0,2,3],[3],[0,3,4]],"joltages":[194,25,212,218,39]},{"target":[true,true,true,false,false],"buttons":[[1,2],[1,2,3],[3,4],[0,1,2],[1,3,4]],"joltages":[12,52,35,43,28]},{"target":[true,false,false,true,true,true,true],"buttons":[[0,3,4,5,6],[0,1,3,5,6],[0,1,2,6],[0,3],[0,1,2,3],[4,5],[3,4]],"joltages":[47,46,31,136,104,19,27]},{"target":[true,false,true,false,true],"buttons":[[0,1,2],[1,2,3],[0,2,3],[1,2],[0,4],[1,3]],"joltages":[35,44,50,27,10]},{"target":[false,true,false,false,false,true,true,true,false],"buttons":[[4,5,6],[3,5,6],[0,2,4,6],[0,2,6,8],[0,1,8],[1,3],[0,1,2,4,5,7,8],[2,5,7]],"joltages":[39,33,32,11,41,35,37,15,29]},{"target":[false,true,false,true,true,true,true],"buttons":[[0,1],[0,4,5,6],[1,3,4,5],[1,5],[1,2,3],[1,2,3,6],[0,1,3,4,6]],"joltages":[43,87,30,61,37,26,44]},{"target":[false,true,true,true,true,true,true,false],"buttons":[[0,3,4,5,7],[1,2,4,5,6,7],[1,2,3,4,6,7],[0,1,2],[5,7],[0,1,2,3,4,6],[0,4,5],[2,3],[0,2,3,4,5,7],[0,1,5,7]],"joltages":[34,43,49,20,33,47,21,47]},{"target":[false,true,true,true,true,true],"buttons":[[0,3],[0,1,3,5],[1,2,3,4,5],[2],[0,1,2]],"joltages":[34,170,162,185,153,168]},{"target":[false,true,false,true],"buttons":[[1,3],[0,2,3]],"joltages":[154,10,154,164]},{"target":[false,false,true,false,true,true],"buttons":[[0,3,4],[2,4,5],[0,1,3,4,5],[0,1,3,5]],"joltages":[28,12,2,28,23,14]},{"target":[false,false,false,true,false],"buttons":[[1,2,3,4],[3],[1,2,4],[0,3],[1,4]],"joltages":[168,22,12,188,22]},{"target":[true,true,false,false,false],"buttons":[[1,2,4],[2,3],[2,3,4],[1,2],[1,2,3],[0,2],[4]],"joltages":[3,30,36,15,11]},{"target":[false,false,true,true],"buttons":[[1],[1,2],[2,3],[2],[0,1,3],[0,3]],"joltages":[11,11,143,25]},{"target":[false,true,true,true,false,false,true,false,false],"buttons":[[1,2,4,5,7,8],[0,3,4,5,7,8],[1,3,7,8],[5,7],[6],[0,1,3,4,6],[0,1,2,4,5,6,7,8],[1,3,4,6,7],[0,2,3,4,7,8],[1,5,6],[3,4,5,6,7,8]],"joltages":[49,151,36,57,71,160,141,79,63]},{"target":[false,true,false,true],"buttons":[[1,3],[2,3],[1,2],[0,1],[0,1,3]],"joltages":[23,48,18,47]},{"target":[false,true,false,false,false,false,false,false,true],"buttons":[[0,2,4,6],[1,4,5],[0,2,3],[0,2,4,7,8],[1,3,5,6,7,8],[3,7],[2,3,4,7,8],[1,8],[0,2]],"joltages":[42,20,228,213,224,19,14,205,201]},{"target":[true,false,false,true,false],"buttons":[[4],[0,1,3],[2,3,4],[1],[0,3],[3,4],[1,2,4]],"joltages":[14,29,10,18,29]},{"target":[false,true,true,true,true,true,false,true],"buttons":[[0,1,5,7],[0,4,5,6,7],[2,6],[2,3,5],[1,4,5],[3,5,7],[1,2,3,4,5,6,7]],"joltages":[13,42,24,35,37,68,25,45]},{"target":[true,true,true,false,true,true,true,false,true],"buttons":[[4,6,7],[2,4,6,7],[0,1,4,5],[2,3,4,5,6,7,8],[1,8],[1,2,3,4,6,8],[2,5,6],[0,2,3,5,6,8],[0,5,6,7,8],[1,2,4,6,8]],"joltages":[27,15,61,25,57,58,94,57,47]},{"target":[true,true,false,true,true,false,false,false,false],"buttons":[[0,1,2,5,6,7,8],[0,1,2,3,6,7],[0,1,2,6,7],[2,3,6],[0,3,4,7,8],[0,1,2,4,6],[5,7,8],[4,6,7]],"joltages":[47,45,61,37,32,209,77,249,211]},{"target":[false,true,true,false,true,true,false,true,false,true],"buttons":[[2,4,7,9],[1,4,5,8],[0,1,3,5],[1,4,5],[7],[1,2,8,9],[2,3,7,8],[0,1,2,3,4,7,8],[0,5],[0,2,3],[1,2,5,6,7,8,9],[0,1,2,3,5,9],[4,6,7,9]],"joltages":[69,76,81,72,49,58,6,51,46,40]},{"target":[true,true,false,false],"buttons":[[0,2],[0,1,3],[0,1]],"joltages":[26,6,20,2]},{"target":[false,true,false,true,false,true,false],"buttons":[[0,1,6],[0,3,4],[1,2,3,6],[1,2,3,4,5],[1,2,3,5,6],[0,1,2,3]],"joltages":[21,33,28,34,7,7,22]},{"target":[true,false,false,true,true,false,true,true,true,true],"buttons":[[8],[3,5],[1,3,4,6],[4,5,7,8],[2,3,4,6,9],[0,1,4,6,7,9],[1,2,3,4,5,6],[1,4,5,6,7],[1,5,6,7],[6,9],[3,6],[0,1,2,3,4,5,8,9]],"joltages":[25,161,35,166,175,74,190,42,29,50]},{"target":[true,false,false,true,false],"buttons":[[0,2,4],[1,4],[0,3]],"joltages":[22,5,20,2,25]},{"target":[false,false,false,false,false,false,false,true,false,false],"buttons":[[0,3,4,5],[2,3,5,6,8,9],[1,2,3,5,7,8],[0,1,3,4,7],[0,2,3,4,5,6,7],[1,2,5,6,7],[0,1,3,6,8,9],[0,2,6],[0,2],[0,1,3,4,5,7,8]],"joltages":[79,31,88,74,43,75,58,49,44,20]},{"target":[false,true,true,false,false,true,true,true,false],"buttons":[[0,2],[1,6],[7,8],[1,3,7],[2,3],[3,4,7,8],[0,2,3,4,5,7],[4,7],[1,2,5,6,7],[0,2,3,4,5,8]],"joltages":[19,38,37,33,26,30,21,65,31]},{"target":[true,true,true,false,false,true,false,false],"buttons":[[5,6],[0,4],[0,1,2,4,5,7],[0,3,5],[1,2,3,5,6],[0,2],[0,1,2,4,7],[0,3,6]],"joltages":[55,49,51,38,32,53,23,32]},{"target":[false,false,true,true,false,true],"buttons":[[1,5],[0,1,2,3,4],[0,1,3],[2,4],[0,3,4],[0,2,4,5]],"joltages":[122,133,27,118,28,20]},{"target":[true,false,false,false,true,false,true],"buttons":[[0,1,2,6],[1,3,6],[0,3,4,5,6],[1],[0,1,4,5,6],[0,4,5],[2,3,4,5,6],[2,3,4]],"joltages":[47,37,38,37,55,37,47]},{"target":[true,true,false,true,true,true],"buttons":[[0,1,3,4,5],[1,4],[0,5],[1,3,4,5],[1,2,3,5],[0,2,3,4,5]],"joltages":[36,43,22,54,47,57]},{"target":[false,true,true,false,false,false,true,false,false],"buttons":[[0,1,3,4,5,7],[0,1,2,3,4,6,8],[0,4,8],[1,5,6,7],[0,1,5,6,7,8],[0,2,4,5,7,8],[0,1,3,5,6]],"joltages":[78,68,23,32,40,77,62,58,53]},{"target":[false,false,true,true,false,false,false,false,false],"buttons":[[0,4,6,7,8],[1,2,3,5,7],[3,6],[1,3,4],[0,1,2,4,5,6,7,8],[0,1,2,3,4,5],[0,5,6],[2,5,6]],"joltages":[34,44,55,49,35,59,55,33,18]},{"target":[false,true,true,false,true,false,true,false,false,true],"buttons":[[1,2,3,6,8,9],[1,2,5,7,8],[3,7,9],[1,2,4,6,9],[1,2,4,6,8,9],[1,2,5,6,7,8,9],[0,2,5,6,7,8],[0,3,4,6,7,9],[0,2,5,6,7,8,9]],"joltages":[20,44,61,26,25,34,59,55,44,62]},{"target":[true,false,true,false],"buttons":[[0,1,3],[0,2]],"joltages":[213,18,195,18]},{"target":[true,false,false,true,true,false],"buttons":[[3,4],[0,1,2,5],[2,5],[0,2,3,4],[0,1,3,4,5],[0,5]],"joltages":[27,12,27,15,15,41]},{"target":[false,true,true,false,false],"buttons":[[0],[1,2,3],[0,4],[1,2],[0,1,2,3],[3,4],[1,3]],"joltages":[42,207,201,207,36]},{"target":[false,true,true,false,true,false,false],"buttons":[[1,2,3,4,5],[0,3],[2,3,4],[1,3,6],[1,2,4,5,6],[0,1,3,4],[0]],"joltages":[34,123,34,153,35,14,114]},{"target":[true,false,true,false,true,false,true],"buttons":[[1,3,5,6],[0,5],[3,6],[1,2,3,4],[0,2]],"joltages":[33,22,29,26,16,26,10]},{"target":[true,false,false,false,true,true,false,false,false],"buttons":[[0,1,2,4,5,6,7],[0,1,2,8],[0,2,3,4,6,7,8],[0,2,3],[1,2,3,4,6,7,8],[0,1,2,3,5,6,8],[1,3,5,6],[1,2,4,5,6],[0,5,6,8]],"joltages":[53,48,74,47,55,29,61,48,42]},{"target":[true,true,false,true,false],"buttons":[[1,3,4],[0,4],[1,4],[0,1,2,3],[1,2,4]],"joltages":[177,213,173,193,44]},{"target":[false,true,false,true,false,true,true,false,true],"buttons":[[1,3,7],[8],[0,1],[4,5],[4,5,8],[0,3,4,5,6,7,8],[2,7],[2,4,6],[0,2,3]],"joltages":[22,15,30,9,21,9,15,17,24]},{"target":[true,false,false,false,false,false,false,true,false,true],"buttons":[[0,1,2,4,6,7,8],[1,3,7,9],[5,7],[0,2,4,6],[2,4,5,7,9],[3,5,7],[0,1,2,5,6,9],[0,7,8]],"joltages":[54,27,50,24,36,58,34,77,28,35]},{"target":[true,false,true,false,false,true,true],"buttons":[[0,1,3],[0,2],[1,2,4,6],[3,5],[5,6],[0,4,6],[0,1,3,5,6],[2,6]],"joltages":[33,28,31,20,26,14,44]},{"target":[true,false,false,true,true],"buttons":[[0,1],[2,3],[1,3,4],[0,1,4]],"joltages":[175,177,0,2,168]},{"target":[false,true,true,true,false,false,false,true,true,false],"buttons":[[8],[0,3,4,5,6,7,8,9],[0,4,5,9],[0,1,2,3,5,7,8],[2,3,4,5,6,7,9],[1,2,3,6,7,9],[0,1,2,3,4,5,7,8],[2,3,5,8,9],[6,8,9],[1,2,3,4,5,6,7,9],[1,4,6,8,9],[0,3,6,9],[0,2,3,7]],"joltages":[65,50,69,97,72,86,95,82,68,117]},{"target":[true,false,false,true,false,true,false,false,false,false],"buttons":[[0,2,4,7],[1,8,9],[0,1,3,4,6,7,8,9],[8],[0,1,3,4,5,6,9],[1,3,5,6,7],[0,3,5,6,7],[1,3],[0,3,5],[0,1,4,8],[0,1,2,4,5,7,8,9]],"joltages":[80,81,27,53,70,31,38,56,62,53]},{"target":[true,false,false,false],"buttons":[[0,1,2],[1,3],[1,2],[0,2],[2,3]],"joltages":[19,41,38,23]},{"target":[false,true,true,false,false],"buttons":[[1,2],[1,3,4],[0,3]],"joltages":[20,29,9,40,20]},{"target":[false,false,true,false,true,false],"buttons":[[3,4,5],[2,3,5],[0,1,2,5],[3,5],[0,1,2],[2,3,4,5],[2,3]],"joltages":[27,27,76,67,25,72]},{"target":[true,true,false,true,true,false,false,false,true],"buttons":[[7,8],[0,2,4,5,7,8],[1,4,6,7],[2,4,5,6],[2,3,4,5,6],[0,1,3,5,6,8],[1,5,7,8],[0,2,5,8],[0,1,3,6],[2,3,4,5,6,7,8],[0,2,3]],"joltages":[56,44,44,48,44,68,60,44,61]},{"target":[true,false,false,true,false],"buttons":[[0,2,3,4],[0,1,2,3],[1,2,3],[2,4]],"joltages":[12,13,132,25,119]},{"target":[false,false,true,false,false,false,true],"buttons":[[1,2,4],[2,3,4],[2],[0,1,4,5,6],[2,4],[0,1,2,4],[0,2,3,4,5],[0,2,4,5,6],[0,1,2,3,6]],"joltages":[58,42,71,22,64,34,49]},{"target":[false,false,true,true,false],"buttons":[[0,2,4],[0,1,2,3],[0,1,4],[1,4],[2,3,4],[1,2,4]],"joltages":[22,44,18,11,41]},{"target":[true,false,true,false],"buttons":[[0,1,3],[0,2]],"joltages":[21,1,20,1]},{"target":[true,false,false,false],"buttons":[[0,3],[0,1,3],[0,2,3],[1],[1,2,3],[2,3]],"joltages":[120,35,134,153]},{"target":[false,true,false,true,true,false,true],"buttons":[[1,3,4,6],[0,1,2,4,5,6],[0,1,2,4,5],[0,2,6],[2,3,5],[4]],"joltages":[54,48,67,27,55,47,50]},{"target":[true,true,false,true],"buttons":[[0,2,3],[0,1,3]],"joltages":[18,17,1,18]},{"target":[true,false,true,true,false,false,false,false,false,true],"buttons":[[0,2,3,9],[6,8],[1,6,7],[4,5,6],[0,1,3,4,8,9],[3,4,5,6,8],[0,3,7,8],[0,2,3]],"joltages":[22,19,19,28,16,15,36,20,12,1]},{"target":[true,true,false,true,false],"buttons":[[0,2,3],[0,1,4],[1,3,4],[1,4],[0,1,3],[1,3]],"joltages":[19,62,1,36,42]},{"target":[true,false,true,true,true],"buttons":[[1,3,4],[0,2,3,4],[2,3]],"joltages":[12,19,30,49,31]},{"target":[false,false,false,true,true],"buttons":[[0,1,4],[1,2,3,4],[0,2],[0,3],[3,4],[1,2],[0]],"joltages":[18,19,18,18,18]},{"target":[true,false,false,true,false,false,true,false,true],"buttons":[[0,1,4],[5,7,8],[2,5,6,7,8],[0,4,5,6],[0,2,3,4,6,8],[1,3,4,5,6,7],[0,2,3,5,6,7,8],[0,1,2,3,4,6,7],[1,2,3,6,7,8],[2,4,5,7]],"joltages":[209,187,45,48,215,71,78,64,43]},{"target":[true,true,false,false,false,false,true,false],"buttons":[[2,3,4,7],[1,4,5],[0,3,4,5],[0,1,2,5,7],[1,4],[0,1,4,6],[0,3,4],[0,6,7]],"joltages":[30,38,108,107,138,10,17,108]},{"target":[false,false,true,true,true,false,true,true,true,false],"buttons":[[0,9],[1,7],[0,1,2,3,5,6],[2,5,7,8],[0,2,3,4,5,7,9],[1,2,3,4,5,7,8,9],[1,2,3,4,5,6],[0,1,2,5,6,8],[0,1,2,4,5,6,7,8],[0,1,2,5],[0,1,2,4,6,7,8,9]],"joltages":[82,105,103,33,55,85,74,77,79,37]},{"target":[true,false,true,false,true,false,true,true,false],"buttons":[[1,2,3,4,5,6,7],[1,6,8],[2,3,5],[5,6],[1,2,4,6,7],[0,1,2,7,8],[0,2,3,4,5,7,8],[0,1,3,4,5,6,8]],"joltages":[37,45,79,49,42,52,30,59,40]},{"target":[true,false,false,false,true,true,false],"buttons":[[0,2,3,4,5],[0,3,6],[0,4,5],[1,3,5,6],[1,2,4,5],[4,6],[0,2,3,4,5,6]],"joltages":[27,18,22,34,33,29,45]},{"target":[true,false,false,true,true,false,true,false],"buttons":[[0,1,4],[0,5,7],[1,2,4,5,6],[2],[0,5],[3,4,6,7],[0,2,3,4,6]],"joltages":[24,171,185,10,181,178,176,7]},{"target":[true,false,false,true,false,true,true,false],"buttons":[[0,3,4,6],[4,6],[0,4,5],[1,2,3,4,5,7],[0,1,2,3,6],[0,1,2,4,6,7],[1,2,3],[1,2,3,4]],"joltages":[62,61,61,57,84,21,65,22]},{"target":[true,false,true,false,true,true,false],"buttons":[[0,1,2,4,5],[3,6],[1,2,4,5,6],[1,3,5,6],[0,1,6],[1,2]],"joltages":[16,149,136,27,17,25,38]},{"target":[true,false,true,false,true,false,false,true,false,true],"buttons":[[0,3,6,7,9],[0,2,3,5,6,7,8,9],[3,6,8],[0,2,5,6,9],[2,3,4,7],[0,1,2,4,5,6,7,8],[0,1,3,4,5,6,7,9],[0,1,2,3,7,9],[5,8,9],[2,5,8,9],[3]],"joltages":[54,41,64,92,37,43,52,67,47,59]},{"target":[true,true,false,false,true,false],"buttons":[[3,4,5],[1,5],[1,2,4],[1,4],[1,2],[0,3,5],[0]],"joltages":[23,47,31,10,33,12]},{"target":[true,false,false,true,true,false,true],"buttons":[[2,4],[1,3,4,5],[0,1,5,6],[0,2,4,5,6],[0,1,4,5,6]],"joltages":[47,41,24,12,55,59,47]},{"target":[true,false,true,false,true,true,false,true],"buttons":[[0,1,2,4,5,7],[0,2,3,6,7],[0,3,4,5],[3,4,5,6],[0,1,3,5,6,7],[1,2,4,5,6,7],[0,2,3],[2,4,5,6,7],[1,7]],"joltages":[32,34,35,34,44,47,32,42]},{"target":[false,false,true,false,true,false,false,false,false,true],"buttons":[[0,2,3,5,6,7,8,9],[1,3,4,5,6,7,8,9],[0,2,7,8,9],[5,6,9],[3],[0,1,4,5,9],[1,5,9],[0,1,2,3,4,5,8],[2,5],[4,8]],"joltages":[26,38,191,38,31,233,23,8,24,46]},{"target":[false,true,false,false,false,false,true,false,true,false],"buttons":[[2,3,4,8],[0,1,2,5,6,7,9],[0,2,3,4,7,8,9],[0,2,3,5,6,7,8,9],[1,3],[4,5,6,9],[0,3,4,5,6,7,8],[0,8,9],[3,4,5,7,8,9],[0,1,2,3,4,6,8,9],[1,2,5,6,7,8,9],[3,4,5]],"joltages":[70,55,62,73,59,77,79,59,69,100]},{"target":[true,false,false,false,true,true,true,false,false,false],"buttons":[[0,3,6,9],[5,8,9],[1,2,3,4,6,8,9],[1,2,5,7],[0,1,2,3,4,6,7,8],[1,2,3,4,6,7,8,9],[3,5],[1,5,6,7,8,9],[4,5,6],[1,2,3,4,5,6,7,9]],"joltages":[33,65,60,67,57,30,75,48,63,62]},{"target":[true,false,true,true],"buttons":[[1,2],[0,1],[0,2,3]],"joltages":[8,22,16,1]},{"target":[true,true,false,false,true,true],"buttons":[[1,2,5],[0,1,2,3,5],[0,3,4],[0,2,4]],"joltages":[20,11,21,10,17,11]},{"target":[false,true,false,true],"buttons":[[1,3],[0,2],[0,3]],"joltages":[21,10,9,22]},{"target":[true,false,false,true,true,false,true,true],"buttons":[[0,1,2,3,4,6,7],[3,4,7],[2,3,7],[2,3,4,5,7],[2,3,5,6],[2,3,6,7],[3,4],[1,3,7],[0,4,5,6],[2,3]],"joltages":[3,14,61,108,49,34,27,62]},{"target":[true,true,true,true,true,true,true,true,false,false],"buttons":[[0,2,3,4,9],[0,3,6,7,8,9],[0,1,2,3,4,5,6,7],[4,5,7,9],[0,1,2,3,4,7,8,9],[0,2,3,4,6,7,8,9],[1,3,5,6,8,9],[0,1,4,5,8,9],[0,2,3],[1,8],[0,5,8]],"joltages":[58,39,41,60,41,33,38,48,46,47]},{"target":[true,false,false,true,false,true,false,false,true],"buttons":[[0,3,6,7],[3,4,6,7],[0,2,5],[0,5,8],[0,6],[0,1,2,3,4,5,7,8],[1,3,4,6,7,8],[0,3,5,8],[4,7],[0,1,3,4,7,8]],"joltages":[49,22,13,36,43,26,47,47,35]},{"target":[false,true,false,false,false,false,false],"buttons":[[1,2,3,4,5],[1,2,3,4],[1,2,3,4,6],[0,2,4,6],[0,1,2,4,5]],"joltages":[6,29,33,27,33,18,8]},{"target":[true,true,false,true,true,true,false,true,false,true],"buttons":[[0,2,5,6,8],[1,2,3,4,5],[0,2,3,5,7,8,9],[0,1,2,4,5,6,9],[2,3,6,7,9],[0,1,2,3,4,5,7,9],[0,2,9],[2,3,4,7,9]],"joltages":[38,39,69,47,42,56,30,28,17,39]},{"target":[false,false,true,true,false,true,false],"buttons":[[0,1,3,4,5],[2,5],[0,1,4,5],[1,4,6],[0,3,4]],"joltages":[128,128,12,21,142,126,14]},{"target":[true,true,true,false],"buttons":[[1,3],[0,2,3],[3],[0,1],[2],[1]],"joltages":[24,41,14,44]},{"target":[true,true,false,true,true,false,false,false],"buttons":[[0,1,4,6,7],[0,1,3,4],[4,6],[0,2,3,4],[6,7],[3,5,6],[0,2,3,5,7]],"joltages":[38,20,18,31,42,23,54,42]},{"target":[true,false,true,false,false],"buttons":[[0,2,3],[3,4],[0,3],[4],[1,2],[0,1]],"joltages":[42,175,174,42,14]},{"target":[false,true,true,true,true,true,true,true],"buttons":[[0,2,6],[0,1,2,3,5,6],[1,7],[2,4,5,6,7],[1,2,4,5],[2,3,4,5,6]],"joltages":[2,8,22,7,20,20,22,21]},{"target":[false,true,false,true,true,true,false,true,true,true],"buttons":[[3,7,8],[0,8,9],[1,2,3,4,5,7,8,9],[0,1,2,3,5,6,9],[0,1,2,3,4,6,7],[0,1,2,3,5,6,8,9],[0,4,6,8],[0,1,2,4,8,9],[0,1,5,8]],"joltages":[191,63,54,46,150,41,166,15,177,48]},{"target":[true,false,true,false],"buttons":[[1,2,3],[0,2]],"joltages":[11,14,25,14]},{"target":[true,false,false,false],"buttons":[[0,3],[1,2,3],[3],[0,1,2],[2],[0,2]],"joltages":[7,7,14,22]},{"target":[false,false,false,false,true,true,false,false],"buttons":[[5,7],[0,6],[2,7],[1,2,3,5,6,7],[0,3,4,5,6,7],[0,1,3,5,7],[1,4],[0,1,2,3,5,7],[0,1,2,3,4,5,7]],"joltages":[37,30,22,26,13,31,14,31]},{"target":[true,false,false,false,true,true,false,false,false,false],"buttons":[[0,2,7],[2,5],[0,1,4,5,6,9],[0,1,6,7,8,9],[0,2,3,4,5,7,8],[0,2,3,4,5],[1,2,3,5,6,7,8],[0,1,2,6],[1,2,4,6],[3,8,9]],"joltages":[76,83,91,53,48,56,83,51,57,48]},{"target":[true,false,true,true,false,true,true,true,true],"buttons":[[0,1,3,4,6,7,8],[0,2,3,5,6,7,8],[2,4],[2,3,4,5,6,7,8],[0,1,3,4,5,7,8],[5,6],[2,3,6,7,8]],"joltages":[31,27,50,68,55,45,60,68,68]},{"target":[false,false,true,false,false,false,false,true,true],"buttons":[[0,1,4,5,6,7,8],[0,4,6,7,8],[1,3,4,5,7,8],[1,2,6,7,8],[0,2,3,4,8],[1,2,4,5],[0,4,5,6,7],[0,1,3,4,6,7,8]],"joltages":[52,52,40,41,71,35,43,53,68]},{"target":[false,true,false,true],"buttons":[[1,3],[0,2]],"joltages":[19,106,19,106]},{"target":[false,true,false,true],"buttons":[[0,3],[1,2,3],[1,2],[2],[0,1,3]],"joltages":[20,44,28,31]},{"target":[true,true,true,true,false],"buttons":[[0,2,4],[1,2],[0,1,2,3],[0,2,3,4],[1]],"joltages":[134,128,137,125,10]},{"target":[true,true,true,false,false,false,true,true],"buttons":[[0,4,5,6,7],[0,1,2,5],[1,4,5,7],[0,1,5],[2,3,4,7],[0,2,5,6,7],[0,2,3,6],[1,3,5],[0,1,2,3,6,7],[1,2,4,5,6]],"joltages":[201,193,197,35,42,211,32,55]},{"target":[false,false,true,false,true,true],"buttons":[[2,3,4,5],[0,1,2,3,5],[1,4],[0,1],[0,3,4],[0,3,5]],"joltages":[29,31,12,23,24,17]},{"target":[true,false,false,true],"buttons":[[2],[0,1],[0,1,2],[1,2],[3],[0,1,3]],"joltages":[23,25,25,20]},{"target":[false,true,true,false,true,true,false,false,true,false],"buttons":[[2,4,9],[0,1,3,4,5,6,8,9],[2,4,5,6,7],[1,2,3,4,6,7,8,9],[0,4,5,7,8],[0,3,4,6,7,8,9],[1,2,4,5,6,7,9],[0,3,4,5,6,7,8]],"joltages":[17,16,30,28,47,16,41,41,28,36]},{"target":[true,false,false,true,false,true],"buttons":[[0,3,5],[1,3,4],[1,3,5],[0,2,3,5],[4,5]],"joltages":[24,173,9,197,12,209]},{"target":[false,false,true,false,true],"buttons":[[0,1,3,4],[1,2,3],[0,1,2,4],[0,2,3]],"joltages":[160,25,158,146,22]},{"target":[true,true,true,false,false,true,true,true],"buttons":[[1,2,4,5,7],[0,2,3,5,7],[0,3,4,5,6,7],[1,2,6,7],[0,1],[1,2,4,7],[3,4,5,7],[0,2,3,5,6,7]],"joltages":[46,41,57,45,49,65,42,79]},{"target":[true,false,true,true],"buttons":[[1,2,3],[2,3],[0,2,3]],"joltages":[14,1,18,18]},{"target":[false,true,true,false,true,true,true,true,true,true],"buttons":[[1,2,3,4,5],[0,2,7],[0,2,4,5,6,7,8,9],[6,8,9],[0,1,3,4,6,8,9],[5],[5,6,9],[0,1,4,5,7,8,9],[0,2,3],[0,1,2,6,7,8,9],[1,2,5,6,7,8,9]],"joltages":[58,38,41,16,30,38,65,43,58,72]},{"target":[false,true,false,false,false,true,true,false,true],"buttons":[[0,1,2,3,4,6,7,8],[0,2,3,4,5,7],[0,1,5,6],[0,2,3,4,5,6,7],[0,1,2,6,7,8],[2,3,4,5,7],[0,2,4,7],[3,5,8]],"joltages":[220,14,230,224,217,223,32,230,32]},{"target":[true,true,true,true,false,false,true,false,false],"buttons":[[0,2,5],[3,4],[0,2,4,5],[0,4,5,7],[0,2,4,5,6,8],[0,1,5,8],[0,1,2,6,7],[0,1,3,4,5,7,8],[0,1,4,5,6],[0,2,3,4,5,6,8],[0,4,5,7,8]],"joltages":[302,229,63,40,99,283,47,64,243]},{"target":[false,false,false,true,false,true,false],"buttons":[[0,2,3,4,5],[3,4,5,6],[0,1,3,4,6],[3,4,5],[1,2,3,4,6],[0,3,6],[0,2,5],[0,1,5],[0,2,4,5,6]],"joltages":[87,25,61,70,76,80,58]},{"target":[true,true,true,false,false,false,false,false,false],"buttons":[[0,1,3,6,7,8],[3,6],[2,3,4,5,6,7],[0,4,8],[1,5,6,8],[0,1,3,4,6,7],[0,1,2,4,6,7,8],[1,2],[1,2,6]],"joltages":[145,188,47,160,29,35,188,157,156]},{"target":[false,false,false,true,true,false,true],"buttons":[[3,4,6],[0,1,3,4,6],[0,2,3,6],[3],[0,6],[4,5,6],[0,1,2,4,5],[0,3,5],[1,4,5,6]],"joltages":[38,26,19,40,39,21,35]},{"target":[true,true,true,true,false,false,true,true],"buttons":[[0,1,2,4,7],[1,6],[0,1,3,6],[0,7],[2,6],[0,1,3],[1,2,4,7],[3,5,6,7]],"joltages":[28,38,208,23,24,12,210,43]},{"target":[false,true,false,false,false,false,false],"buttons":[[0,1],[0,3,4,6],[2,3,4,6],[4,5,6],[1,2,4,5,6],[0,1,3,4,5],[3,4,6]],"joltages":[44,44,23,55,83,47,64]},{"target":[true,false,true,false,true,true,false,false,false,false],"buttons":[[0,1,2,3,7,8],[2,4,5,7,8],[0,1,3,4,8,9],[0,5,7,9],[3,4],[0,1,2,3,4,5,8,9],[0,1,2,3,4,5,6,7,9],[0,2,3,4,6,8,9]],"joltages":[48,26,154,61,184,135,23,130,167,47]},{"target":[true,true,false,true,true,true,true,true,true,true],"buttons":[[2,3,5,6,8,9],[0,5,9],[1,2,9],[0,2,3,4,5,6,7,8],[2,6,8],[0,3,5,6],[0,1,2,3,4,5,7,9],[3,4,9],[0,2,5,6,8],[3,7]],"joltages":[35,17,158,154,7,167,147,13,141,171]},{"target":[true,false,true,true,false,true,false,false],"buttons":[[0,3],[0,2,4],[1,2,3,5,6],[0,1,2,3,6],[1,2,3,4,5,7],[2,3],[3,4],[2,3,4,7],[0,1,2,7],[0,1,6,7]],"joltages":[72,60,68,67,41,16,39,45]},{"target":[true,true,true,false,false],"buttons":[[3],[1,2,3],[0,1,2,3],[3,4],[0,1,4],[0,3,4],[0,2]],"joltages":[37,26,24,34,18]},{"target":[false,false,false,true,false,false,false,true,true,true],"buttons":[[2,3,5],[0,3,4,5,6,9],[3,6],[2,8],[0,1,4,5,6,7,9],[1,3],[0,1,3,4,5,6,7,8,9],[5,7,9],[0,2,4,8]],"joltages":[50,36,32,66,50,63,46,33,22,48]},{"target":[true,false,false,true],"buttons":[[0,1,3],[0,2,3],[1],[1,2]],"joltages":[16,181,165,16]},{"target":[true,false,true,false],"buttons":[[0,2],[0,1,3]],"joltages":[19,15,4,15]},{"target":[true,true,false,true,true,true,true],"buttons":[[0,1,3],[0,4,5,6],[0,1,3,4,5,6],[0,2,4,5,6],[0,1,2,4,5,6],[2,3,4]],"joltages":[28,18,38,24,43,24,24]},{"target":[true,false,false,true,false,false],"buttons":[[0,3],[1,2,3,4],[1,2,4,5],[0,1,2,3,4,5]],"joltages":[19,227,227,33,227,213]},{"target":[true,false,true,true],"buttons":[[1,2,3],[0,1],[1,2],[2,3]],"joltages":[17,49,32,12]},{"target":[false,true,false,true,true],"buttons":[[0,1,3],[3,4],[2],[0,2,4]],"joltages":[16,13,20,28,18]},{"target":[true,true,false,false],"buttons":[[2],[0],[3],[0,2],[1,3],[0,2,3]],"joltages":[15,15,33,31]},{"target":[false,true,true,false,true,false,true,true,true,false],"buttons":[[1,6,8],[6,7],[0,1,2],[1,5,6,7,9],[2,3,4,5,6,8,9],[7,8],[2,4,5,6,7,8],[3,6,7,9],[0,1,3,5,6,7,8,9],[1,2,3,5,6,7],[0,2,5,6,8,9],[0,2,3,4,5,8,9]],"joltages":[19,59,26,37,9,46,82,69,41,50]},{"target":[true,false,true,false,false,false,true],"buttons":[[0,1,4,6],[0,3],[3,6],[1,2,4,5,6],[0,1,5],[1,4,5,6],[0,1,2,3,5],[0,1,4,5,6],[1,3,4,6]],"joltages":[51,67,24,33,42,59,42]},{"target":[true,true,true,true],"buttons":[[1,3],[0,1,2,3]],"joltages":[12,16,12,16]},{"target":[false,true,false,true,false],"buttons":[[0,2,3],[0,3,4],[0,1],[0,2],[0,3],[3],[0,1,2]],"joltages":[58,8,27,181,16]},{"target":[false,false,true,false,false,false,false],"buttons":[[2,3],[2,6],[2,3,5],[0,1,3,4,5],[4,6],[0,3,5,6],[0,6],[1,2,4,5,6]],"joltages":[19,26,59,29,26,44,49]},{"target":[true,true,false,false],"buttons":[[0,1,3],[3],[0],[0,1,2]],"joltages":[35,28,10,25]},{"target":[true,false,false,true,true,false,true],"buttons":[[0,2,3],[1,4],[1,2,3,5,6],[0,4],[2,3],[0,3,4],[4,6],[0,2,4,5,6],[0,3,4,6]],"joltages":[62,8,36,54,72,20,49]},{"target":[true,true,false,false,true,true,false,false,false],"buttons":[[0,2,3,4,8],[0,1,8],[0,1,3,4,5,6,7,8],[0,3,4,5,6,7,8],[2,5,7,8],[0,1,2,3,6,8],[0,6,7],[3,5,8],[2,7]],"joltages":[57,32,170,62,35,43,37,178,72]},{"target":[false,true,true,false,false,false,true],"buttons":[[0,2,3,5],[1,2,3,4,5],[0,1,2,5],[0,1,4,6],[0,5,6]],"joltages":[52,33,32,15,16,38,21]},{"target":[false,false,false,false,true,false],"buttons":[[0,2,3],[0,2],[3,5],[0,1,2,3,5],[1],[3,4]],"joltages":[12,17,12,24,5,17]},{"target":[false,false,false,false,true,false,false,true,false,false],"buttons":[[2,6],[0,2,3,4,5,6,7,8],[0,1,3,7,8,9],[3,4,9],[0,1,2,3,4,5,6,9],[1,3,5,7,8,9],[0,2,3,4,6,7,9],[0,1,8],[1,3,4,8],[0,1,3,4,6,7,8,9]],"joltages":[41,47,28,70,62,27,43,32,44,52]},{"target":[true,false,true,true,false,true,false],"buttons":[[1,2,4,6],[1,2,3,4],[0,2,3,5,6],[0,2],[0,1,3,4,6]],"joltages":[28,18,46,29,18,20,29]},{"target":[true,true,false,false,true,false],"buttons":[[1,2,4,5],[5],[0,2],[0,1,2,4],[0],[4,5],[1,3,4,5],[3,4,5]],"joltages":[33,34,37,192,225,221]},{"target":[true,true,false,false,false,true,true,false],"buttons":[[0,3,4],[2,5],[1,4],[2,4,6],[0,1,3,7],[0,2,4,6,7]],"joltages":[164,10,193,10,185,20,173,158]},{"target":[false,false,false,false,false,false,false,true],"buttons":[[4,5],[1,2,4,7],[0,5,7],[1,4],[1,2,3,4,5,6,7],[1,2,3,4,5,7],[0,3,5,6,7],[0,1,2,5,6,7]],"joltages":[44,63,52,44,62,80,38,85]},{"target":[true,true,true,true,false,false,true,false,true,true],"buttons":[[0,3,5,8,9],[0,2,9],[1,3,5,6,7,8,9],[7,8],[0,2,3,4,5,8,9],[4,8,9],[0,1,3,4,5,6,7,9],[0,1],[0,1,2,3,4,5,7,9],[0,2,4,5,6,7],[1,3,6,8],[0,1,4,9],[4,6]],"joltages":[178,69,47,175,63,177,53,67,149,185]},{"target":[false,true,true,false,false,true,true,true,true],"buttons":[[3,4,6],[0,3,4,5,6,7,8],[4,5,8],[0,1,2,3,5,6,7,8],[4,5],[1,2,4,7],[6],[1,3,7,8]],"joltages":[29,40,24,62,75,62,54,55,61]},{"target":[true,true,false,true,true,true,false],"buttons":[[0,1,2,3,4],[0,3,6],[0,3,5,6],[3,5],[0,4],[0,1,3,4,5]],"joltages":[249,205,200,242,214,25,35]},{"target":[true,true,false,false,false,false,true,true],"buttons":[[1,3,4,6],[1,2,4,5,6,7],[0,1,3,4,5,7],[0,1,2,3,5,6],[2,3,4,5,6,7],[0,3,4,6,7],[0,4,5]],"joltages":[43,37,32,45,52,55,46,22]},{"target":[true,true,false,false,false,false,true,true,true,false],"buttons":[[2,6,8,9],[3,9],[2,4,6],[5,6,7],[4,7],[0,1,2,3,7],[2],[1,5,6,9],[0,1,3,6,8,9],[3,4,5,6],[1,2,3,4,5,6,8],[0,1,3,4,6,8],[9]],"joltages":[37,51,76,53,52,23,82,42,55,55]},{"target":[false,false,true,true,false],"buttons":[[2,3],[0,2,3,4],[1,3,4],[1,2,3,4]],"joltages":[8,18,34,37,26]},{"target":[true,true,false,true,false,false,false,false,true],"buttons":[[2,5],[0,1,2,5,8],[3,4,5,6,8],[1,2,3,4,6,7,8],[0,1,3,4,5,6,8],[1,4,7],[2,3,5,7,8],[1,2,3,5,7]],"joltages":[29,65,46,36,47,40,32,38,54]},{"target":[true,true,true,false,true,false,true],"buttons":[[2,5],[0,4],[2,3],[1,2],[2],[0,3,6],[0,2,6],[0,3],[0,1,4,5,6]],"joltages":[88,25,56,42,38,32,51]},{"target":[true,false,false,true,true,true,false,true,true],"buttons":[[0,1,4,5,6],[0,1,3,4,5,6,7,8],[0,1,2,7,8],[1,2,3,4,5],[0,3,8],[1,3,4,5,6,7],[4,6],[0,1,3,5,6,7],[8],[0,2,3,4,5,6,7],[1,7]],"joltages":[175,196,12,182,43,176,171,187,52]},{"target":[false,true,false,true,true,true,false,false],"buttons":[[2,4,5],[2,6,7],[2,4,5,6,7],[3,4],[0,3,4,5,7],[1,2,3,4,5,7],[5],[2,5,6],[1,3,4,5,6,7],[0,2,4,6,7]],"joltages":[14,25,37,189,194,64,34,47]},{"target":[false,true,true,false],"buttons":[[0,1],[0,2,3],[0,1,2],[1,2]],"joltages":[35,31,38,20]},{"target":[true,false,true,false,false,false,true],"buttons":[[0,1,4,5],[1,2,4],[0,1,4,6],[1,2,4,5,6],[0,2,6],[1,2,3],[3,4]],"joltages":[42,60,34,19,63,35,39]},{"target":[false,true,true,true,false,false,false],"buttons":[[4],[0,2,3,4,6],[0,1,2,3,4,5],[0,2,4,5,6],[0,1,3,4,5],[1,2,3]],"joltages":[37,35,20,36,44,36,3]},{"target":[true,false,true,false,false],"buttons":[[0,3],[2,3],[3,4],[0,3,4],[2,4],[0,1,3]],"joltages":[200,3,39,227,212]},{"target":[true,false,true,false,true,false,false,false],"buttons":[[2],[1,7],[0,3,4,6],[3],[1,4,5,6,7],[0,2,3,5,6]],"joltages":[33,211,25,52,29,30,46,211]},{"target":[false,false,false,false,true,true],"buttons":[[0,1,4,5],[0,1,5],[2,3,4],[1,3],[0,1,3],[1,2,5],[0],[1,2,3,4]],"joltages":[36,41,20,34,21,16]},{"target":[false,true,true,false,true,true,true,false,true,false],"buttons":[[0,2,3,4,9],[1,7],[1,2,3,5,6,7,8,9],[0,1,2,4,5,7,9],[3,4,5,6,7],[4,6],[2],[0,1,2,3,6,7,9],[0,6,7,8,9]],"joltages":[138,163,164,156,25,29,162,172,22,157]},{"target":[false,false,true,false,true,false],"buttons":[[0,1,2,4,5],[0,2,3],[0,2,5],[0,4,5]],"joltages":[53,2,34,19,21,34]},{"target":[true,false,false,false,true,true],"buttons":[[1,2,3,4],[0,3,5],[1,5],[0,1,4,5],[0,2,3,4,5],[0,2,3],[0,1,2,3]],"joltages":[32,41,28,39,15,30]},{"target":[true,true,false,true,true,true,false,false],"buttons":[[0,2,5,6],[0,5,6,7],[4,5,7],[1,3,6,7],[0,2,5,7],[1],[3,4,6,7],[0,6],[1,2,3,5]],"joltages":[30,45,38,45,35,55,43,64]},{"target":[false,true,false,true,false,false,true,false,false,false],"buttons":[[3,7],[0,4,5,9],[3,4,6,8],[0,1,2,3,5,6,8,9],[2,3,4,5,6,7,8,9],[8,9],[0,1,2,3,4,6,8],[0,1,2],[0,1,2,4,5,7,8,9],[0,1,3,4,6],[0,1,3,7,9],[0,1,6,7,8,9]],"joltages":[263,243,67,237,236,61,224,76,91,99]},{"target":[false,true,true,false,true,true],"buttons":[[0,2,3,5],[1],[0,1,2,4,5],[4,5],[1,3],[0],[0,2,3]],"joltages":[44,31,42,42,15,35]},{"target":[true,true,true,false],"buttons":[[1,3],[1,2],[0,2],[2],[2,3]],"joltages":[9,155,45,146]},{"target":[true,false,true,false,false,false,true,false,true,false],"buttons":[[0,1,2,5,6],[0,1,2,5,7],[1,2,4,5,6],[0,1,3,5,7,8,9],[2,3,4,5,6,8],[4,6],[0,1,2,3,4,5,6,8],[0,3,4,5,9],[5,6,7,8],[1,4,6,7,8],[2,3,8,9],[2,3,4,9],[0,1,2,4,5,7,8]],"joltages":[76,79,96,73,82,86,58,63,80,61]},{"target":[false,false,false,true,true,true],"buttons":[[0,3,4],[3,4,5],[0,1,4,5],[0,2,3,4]],"joltages":[34,10,10,32,42,18]},{"target":[false,false,true,true,false],"buttons":[[1,2,4],[0,2,3],[2,3]],"joltages":[17,7,28,21,7]},{"target":[false,true,true,true],"buttons":[[1,2,3],[0,2]],"joltages":[4,19,23,19]},{"target":[true,true,true,false],"buttons":[[2,3],[0,1,3],[0,1],[1,2]],"joltages":[15,32,30,26]},{"target":[false,false,true,false,true,false],"buttons":[[0,2,4],[3,4],[0,1,2,4,5],[0,1,3],[1,2,3,5]],"joltages":[37,29,33,31,48,21]},{"target":[true,true,true,false,false,true,true,true],"buttons":[[1,3,6],[0,1,2,3,4,5,7],[0,2,4,5,6,7],[1,2,6],[0,3,6],[1,5,7]],"joltages":[27,26,20,16,20,37,36,37]},{"target":[false,true,true,false],"buttons":[[2,3],[1,2],[0,3]],"joltages":[14,1,1,14]},{"target":[false,true,false,true,true,false,false,false,true],"buttons":[[3,4,5,6,8],[1,2,3,6,7,8],[1,2,3,5,6,7],[3,7],[2,3,4,5,6,7,8],[0,1,2,8],[0,3,4,5,7,8]],"joltages":[153,46,47,212,158,173,51,196,189]},{"target":[true,false,true,true,true,false],"buttons":[[0,1,4,5],[0,1,2,5],[1,2,3],[1,2,3,4,5],[0,2,3,5],[0,3,4],[1,2],[2,3,4,5]],"joltages":[220,54,54,223,212,30]},{"target":[true,false,true,true,true,true],"buttons":[[1,2,3,5],[0,1,5],[1,2,3,4],[0,2,3,4],[2,3]],"joltages":[21,25,36,36,20,14]},{"target":[false,false,false,true,false,false,false,false,true,true],"buttons":[[0,9],[4,5,6],[0,2,4,6,7,9],[0,2,3,4,7,8,9],[0,1,4,7],[0,3,7,8],[8,9],[0,7,8],[0,1,2,5,6,7]],"joltages":[65,26,36,8,49,35,47,46,18,49]},{"target":[false,true,true,true,true,false,true,true],"buttons":[[1,2,3,5,6,7],[0,1,3,4,6,7],[1,2,3,4,5,6],[0,2,4,7],[1,3,5],[3,4,5,6,7],[4,7],[0,1,4,6,7],[0,7]],"joltages":[19,35,12,42,55,27,40,46]},{"target":[false,true,false,true,true,true],"buttons":[[0,2,3,5],[1,3,4,5],[0,1,2,4],[1,5],[1,2,3,5]],"joltages":[29,50,39,38,35,43]},{"target":[false,false,true,false,false,true,true,false,true],"buttons":[[2,3,8],[1,5],[1,4,5,6,7,8],[1,3,4,5,7,8],[2,3,4,5,7],[0,1,3,4],[0,1,3,4,6],[0,2,3,4,5,7,8]],"joltages":[28,173,36,70,64,171,30,46,60]},{"target":[false,true,true,false],"buttons":[[1],[0,2,3],[1,2]],"joltages":[3,11,10,3]},{"target":[true,false,true,false,false,false,false,true,true],"buttons":[[1,2,3,8],[1,2,3,4,5],[0,1,3,7],[0,1,2,3,6,7],[0,1,2,3,7,8],[4],[1,2,3,4,5,7,8]],"joltages":[27,49,45,49,31,19,6,42,35]},{"target":[true,true,false,false],"buttons":[[1],[0,1,2],[2,3],[0]],"joltages":[22,19,28,9]},{"target":[true,true,false,false,true,true,true],"buttons":[[1,2,3,4,5],[2,3,4,5],[0,2,4,5],[1,4],[0,2,4],[3],[0,1,3,6],[1,3,6]],"joltages":[37,171,27,179,33,24,158]},{"target":[false,true,true,true,true,false],"buttons":[[1,2,3,4],[0,4],[0,1,3],[1,2,3],[2,3,4,5],[1,2,3,4,5],[0,2]],"joltages":[44,38,47,45,44,21]},{"target":[false,true,true,false,true,false,false,false,true],"buttons":[[1,6,8],[2,3,4,5,8],[0,1,2,3,6,8],[0,2,3,4,7,8],[5,7],[0,1,2,3,4,5,8],[1,3,4,5],[0,1,4],[1,2,3,6,7,8],[4,5,6,7],[0,1,2,4,5,6,8]],"joltages":[59,172,61,70,85,56,141,54,164]},{"target":[false,true,true,false,false,false,false,false,false],"buttons":[[7,8],[3,5],[1,2],[1,3,5,6,8],[2,3,4,5,6],[0,4,7,8],[2,4],[1,2,3,4,5,6,7]],"joltages":[4,35,43,56,44,56,47,41,33]},{"target":[true,false,false,false,false,true,false,false,false,false],"buttons":[[0,1,2,3,4,5,7,8,9],[2,4,5,9],[3,5,6],[3,9],[0,3,5,9],[0,1,4],[0,1,3,5,6,8],[0,1,2,4,5,6,7,8],[0,2,5,6,7,8,9],[0,1,3,6,8,9],[4,6,8]],"joltages":[217,50,191,56,54,220,203,176,191,209]},{"target":[false,true,false,false,true,false],"buttons":[[0,2,4],[1,3],[1,3,5],[1,2,3,5],[0,1,2,3],[3],[0,3,4,5]],"joltages":[145,21,28,151,139,132]},{"target":[true,false,false,true,true,true],"buttons":[[3,4],[2],[1,3,5],[1,2,3,5],[0,1,2],[0,2,4,5],[0,2,3,4],[0,2,3]],"joltages":[42,19,63,44,38,13]},{"target":[true,false,true,false,false,false,false,false,false],"buttons":[[0,2,4,6,7],[0,3,4,6,8],[0,3,4,5,8],[0,1,4,6],[2,4,5],[2,3,5],[1,3,5,7],[3,8]],"joltages":[32,17,39,53,46,56,18,25,25]},{"target":[true,true,true,false,false,false,false,false,false,true],"buttons":[[0,1,2,5],[5,6,9],[0,2,8,9],[0,2,3,5],[2],[0,1,2,3,4,5,6,7],[0,1,2,3,5,6,7,9],[7],[0,3,4]],"joltages":[73,56,84,44,19,78,52,49,9,44]},{"target":[true,false,true,true],"buttons":[[1,2],[2],[0,1,3],[0,1,2]],"joltages":[21,27,190,4]},{"target":[false,false,false,true,false,false,true,false,true,true],"buttons":[[0,2,3,4,6,7,8,9],[0,2,3,4,8,9],[0,1,2,5,6,8,9],[2,3],[0,1,2,5,6,7,8],[1,2,5,8],[0,1,2,3,5,7,8,9],[2,7],[0,3,8,9],[2,4,9]],"joltages":[36,32,70,37,11,32,14,33,37,42]}]; 241 + 242 + let currentMode = 1; // 1 or 2 243 + let currentMachineIndex = 0; 244 + let currentState = []; 245 + let buttonStates = []; // Track which buttons are "on" (pressed odd number of times) 246 + let isPlaying = false; 247 + let showingSolution = false; 248 + let solutionSteps = []; 249 + let currentStep = 0; 250 + let solvedMachines = new Set(); // Track which machines have been solved 251 + let animationSpeed = 200; // ms between button presses (default 5x) 252 + 253 + 254 + function renderMachine() { 255 + const machine = machines[currentMachineIndex]; 256 + 257 + // Update title based on mode 258 + const titleEl = document.getElementById('displayTitle'); 259 + if (currentMode === 1) { 260 + titleEl.textContent = 'Indicator Lights'; 261 + titleEl.style.color = '#89b4fa'; 262 + } else { 263 + titleEl.textContent = 'Joltage Counters'; 264 + titleEl.style.color = '#f9e2af'; 265 + } 266 + 267 + // Render lights or counters 268 + const lightsDiv = document.getElementById('lights'); 269 + lightsDiv.innerHTML = ''; 270 + 271 + if (currentMode === 1) { 272 + // Part 1: Indicator lights 273 + machine.target.forEach((target, i) => { 274 + const light = document.createElement('div'); 275 + light.className = `light ${currentState[i] ? 'on' : 'off'} ${target ? 'target' : ''}`; 276 + light.textContent = i; 277 + lightsDiv.appendChild(light); 278 + }); 279 + } else { 280 + // Part 2: Joltage counters 281 + machine.joltages.forEach((target, i) => { 282 + const counter = document.createElement('div'); 283 + const current = currentState[i] || 0; 284 + const isTarget = current === target; 285 + counter.className = `light ${isTarget ? 'on' : 'off'} ${true ? 'target' : ''}`; 286 + counter.innerHTML = `<div style="font-size: 7px; opacity: 0.7;">[${i}]</div><div style="font-size: 10px; font-weight: bold;">${current}/<span style="color: #f9e2af;">${target}</span></div>`; 287 + lightsDiv.appendChild(counter); 288 + }); 289 + } 290 + 291 + // Render buttons 292 + const buttonsDiv = document.getElementById('buttons'); 293 + buttonsDiv.innerHTML = ''; 294 + machine.buttons.forEach((toggles, i) => { 295 + const btn = document.createElement('div'); 296 + const pressCount = buttonStates[i] || 0; 297 + const isPressed = currentMode === 1 ? (pressCount % 2 === 1) : (pressCount > 0); 298 + btn.className = `button-display ${isPressed ? 'pressed' : ''}`; 299 + btn.innerHTML = ` 300 + <div class="button-label">Button ${i}${currentMode === 2 ? ` (${pressCount})` : ''}</div> 301 + <div class="button-toggles">Affects: ${toggles.join(', ')}</div> 302 + `; 303 + btn.addEventListener('click', () => toggleButton(i)); 304 + buttonsDiv.appendChild(btn); 305 + }); 306 + } 307 + 308 + function toggleButton(buttonIndex) { 309 + const machine = machines[currentMachineIndex]; 310 + 311 + if (currentMode === 1) { 312 + // Part 1: Toggle lights (XOR) 313 + buttonStates[buttonIndex] = buttonStates[buttonIndex] ? 0 : 1; 314 + machine.buttons[buttonIndex].forEach(lightIndex => { 315 + currentState[lightIndex] = !currentState[lightIndex]; 316 + }); 317 + } else { 318 + // Part 2: Increment counters 319 + buttonStates[buttonIndex] = (buttonStates[buttonIndex] || 0) + 1; 320 + machine.buttons[buttonIndex].forEach(counterIndex => { 321 + currentState[counterIndex] = (currentState[counterIndex] || 0) + 1; 322 + }); 323 + } 324 + 325 + renderMachine(); 326 + updateStats(); 327 + } 328 + 329 + function solveMachine(machine) { 330 + const n = machine.target.length; 331 + const m = machine.buttons.length; 332 + 333 + const matrix = []; 334 + for (let i = 0; i < n; i++) { 335 + const row = []; 336 + for (let j = 0; j < m; j++) { 337 + row.push(machine.buttons[j].includes(i) ? 1 : 0); 338 + } 339 + row.push(machine.target[i] ? 1 : 0); 340 + matrix.push(row); 341 + } 342 + 343 + const pivotCols = []; 344 + for (let col = 0; col < m; col++) { 345 + let pivotRow = -1; 346 + for (let row = pivotCols.length; row < n; row++) { 347 + if (matrix[row][col] === 1) { 348 + pivotRow = row; 349 + break; 350 + } 351 + } 352 + 353 + if (pivotRow === -1) continue; 354 + 355 + const targetRow = pivotCols.length; 356 + if (pivotRow !== targetRow) { 357 + [matrix[pivotRow], matrix[targetRow]] = [matrix[targetRow], matrix[pivotRow]]; 358 + } 359 + 360 + pivotCols.push(col); 361 + 362 + for (let row = 0; row < n; row++) { 363 + if (row !== targetRow && matrix[row][col] === 1) { 364 + for (let c = 0; c <= m; c++) { 365 + matrix[row][c] ^= matrix[targetRow][c]; 366 + } 367 + } 368 + } 369 + } 370 + 371 + const solution = new Array(m).fill(0); 372 + for (let i = pivotCols.length - 1; i >= 0; i--) { 373 + const col = pivotCols[i]; 374 + solution[col] = matrix[i][m]; 375 + for (let j = col + 1; j < m; j++) { 376 + if (matrix[i][j] === 1) { 377 + solution[col] ^= solution[j]; 378 + } 379 + } 380 + } 381 + 382 + return solution; 383 + } 384 + 385 + // Part 2 solver (copy of server-side logic) 386 + function solveMachinePart2(machine) { 387 + const n = machine.joltages.length; 388 + const m = machine.buttons.length; 389 + const target = machine.joltages; 390 + 391 + const A = []; 392 + for (let i = 0; i < n; i++) { 393 + const row = []; 394 + for (let j = 0; j < m; j++) { 395 + row.push(machine.buttons[j].includes(i) ? 1 : 0); 396 + } 397 + A.push(row); 398 + } 399 + 400 + const matrix = []; 401 + for (let i = 0; i < n; i++) { 402 + matrix.push([...A[i], target[i]]); 403 + } 404 + 405 + const pivotCols = []; 406 + for (let col = 0; col < m; col++) { 407 + let pivotRow = -1; 408 + for (let row = pivotCols.length; row < n; row++) { 409 + if (matrix[row][col] !== 0) { 410 + pivotRow = row; 411 + break; 412 + } 413 + } 414 + 415 + if (pivotRow === -1) continue; 416 + 417 + const targetRow = pivotCols.length; 418 + if (pivotRow !== targetRow) { 419 + [matrix[pivotRow], matrix[targetRow]] = [matrix[targetRow], matrix[pivotRow]]; 420 + } 421 + 422 + pivotCols.push(col); 423 + 424 + const pivot = matrix[targetRow][col]; 425 + for (let c = 0; c <= m; c++) { 426 + matrix[targetRow][c] /= pivot; 427 + } 428 + 429 + for (let row = 0; row < n; row++) { 430 + if (row !== targetRow && matrix[row][col] !== 0) { 431 + const factor = matrix[row][col]; 432 + for (let c = 0; c <= m; c++) { 433 + matrix[row][c] -= factor * matrix[targetRow][c]; 434 + } 435 + } 436 + } 437 + } 438 + 439 + const isPivot = new Array(m).fill(false); 440 + pivotCols.forEach(col => isPivot[col] = true); 441 + const freeVars = []; 442 + for (let j = 0; j < m; j++) { 443 + if (!isPivot[j]) freeVars.push(j); 444 + } 445 + 446 + if (freeVars.length > 8) { // Reduced limit for browser 447 + return new Array(m).fill(0); 448 + } 449 + 450 + let minPresses = Infinity; 451 + let bestSolution = []; 452 + 453 + const maxTarget = Math.max(...target); 454 + const maxFreeValue = Math.min(maxTarget * 2, 100); 455 + 456 + function searchFreeVars(idx, currentSol) { 457 + if (idx === freeVars.length) { 458 + const sol = [...currentSol]; 459 + let valid = true; 460 + for (let i = pivotCols.length - 1; i >= 0; i--) { 461 + const col = pivotCols[i]; 462 + let val = matrix[i][m]; 463 + for (let j = col + 1; j < m; j++) { 464 + val -= matrix[i][j] * sol[j]; 465 + } 466 + sol[col] = val; 467 + 468 + if (val < -1e-9 || Math.abs(val - Math.round(val)) > 1e-9) { 469 + valid = false; 470 + break; 471 + } 472 + } 473 + 474 + if (valid) { 475 + const intSol = sol.map(x => Math.round(Math.max(0, x))); 476 + const presses = intSol.reduce((sum, x) => sum + x, 0); 477 + if (presses < minPresses) { 478 + minPresses = presses; 479 + bestSolution = intSol; 480 + } 481 + } 482 + return; 483 + } 484 + 485 + for (let val = 0; val <= maxFreeValue; val++) { 486 + currentSol[freeVars[idx]] = val; 487 + searchFreeVars(idx + 1, currentSol); 488 + } 489 + } 490 + 491 + searchFreeVars(0, new Array(m).fill(0)); 492 + return bestSolution; 493 + } 494 + 495 + function getCurrentSolution() { 496 + const machine = machines[currentMachineIndex]; 497 + return currentMode === 1 ? solveMachine(machine) : solveMachinePart2(machine); 498 + } 499 + 500 + function showSolution() { 501 + const machine = machines[currentMachineIndex]; 502 + const solution = getCurrentSolution(); 503 + 504 + if (currentMode === 1) { 505 + currentState = new Array(machine.target.length).fill(false); 506 + buttonStates = [...solution].map(v => v === 1); 507 + 508 + solution.forEach((shouldPress, buttonIndex) => { 509 + if (shouldPress === 1) { 510 + machine.buttons[buttonIndex].forEach(lightIndex => { 511 + currentState[lightIndex] = !currentState[lightIndex]; 512 + }); 513 + } 514 + }); 515 + } else { 516 + currentState = new Array(machine.joltages.length).fill(0); 517 + buttonStates = [...solution]; 518 + 519 + solution.forEach((pressCount, buttonIndex) => { 520 + for (let p = 0; p < pressCount; p++) { 521 + machine.buttons[buttonIndex].forEach(counterIndex => { 522 + currentState[counterIndex]++; 523 + }); 524 + } 525 + }); 526 + } 527 + 528 + showingSolution = true; 529 + renderMachine(); 530 + updateStats(); 531 + } 532 + 533 + function updateStats() { 534 + const machine = machines[currentMachineIndex]; 535 + const solution = getCurrentSolution(); 536 + const minPresses = solution.reduce((a, b) => a + b, 0); 537 + 538 + let totalPressed; 539 + if (currentMode === 1) { 540 + totalPressed = buttonStates.filter(b => b).length; 541 + } else { 542 + totalPressed = buttonStates.reduce((sum, count) => sum + (count || 0), 0); 543 + } 544 + 545 + // Calculate accumulated total for solved machines 546 + let accumulatedTotal = 0; 547 + solvedMachines.forEach(idx => { 548 + const m = machines[idx]; 549 + const sol = currentMode === 1 ? solveMachine(m) : solveMachinePart2(m); 550 + accumulatedTotal += sol.reduce((a, b) => a + b, 0); 551 + }); 552 + 553 + document.getElementById('statsInfo').textContent = `Buttons Pressed: ${totalPressed} | Target: ${minPresses} | Accumulated Total: ${accumulatedTotal}`; 554 + document.getElementById('machineInfo').textContent = `Machine ${currentMachineIndex + 1} / ${machines.length}`; 555 + } 556 + 557 + document.getElementById('prev').addEventListener('click', () => { 558 + if (currentMachineIndex > 0) { 559 + isPlaying = false; 560 + document.getElementById('play').textContent = '▶ Play'; 561 + currentMachineIndex--; 562 + initMachine(); 563 + } 564 + }); 565 + 566 + document.getElementById('next').addEventListener('click', () => { 567 + if (currentMachineIndex < machines.length - 1) { 568 + isPlaying = false; 569 + document.getElementById('play').textContent = '▶ Play'; 570 + currentMachineIndex++; 571 + initMachine(); 572 + } 573 + }); 574 + 575 + document.getElementById('reset').addEventListener('click', initMachine); 576 + 577 + document.getElementById('togglePart').addEventListener('click', () => { 578 + currentMode = currentMode === 1 ? 2 : 1; 579 + document.getElementById('togglePart').textContent = `Part ${currentMode}`; 580 + solvedMachines.clear(); 581 + initMachine(); 582 + }); 583 + 584 + document.getElementById('play').addEventListener('click', () => { 585 + isPlaying = !isPlaying; 586 + document.getElementById('play').textContent = isPlaying ? '⏸ Pause' : '▶ Play'; 587 + if (isPlaying) { 588 + animateSolution(); 589 + } 590 + }); 591 + 592 + // Speed control 593 + const speedSlider = document.getElementById('speed'); 594 + const speedValue = document.getElementById('speedValue'); 595 + speedSlider.addEventListener('input', (e) => { 596 + const speed = parseInt(e.target.value); 597 + speedValue.textContent = `${speed}x`; 598 + // Faster speed = shorter delay (inverse relationship) 599 + animationSpeed = 1000 / speed; 600 + }); 601 + 602 + function animateSolution() { 603 + if (!isPlaying) return; 604 + 605 + if (currentStep < solutionSteps.length) { 606 + // Toggle the next button in the solution 607 + const buttonIndex = solutionSteps[currentStep]; 608 + toggleButton(buttonIndex); 609 + currentStep++; 610 + 611 + // Use 10x faster speed for Part 2 (more button presses) 612 + const delay = currentMode === 2 ? animationSpeed / 10 : animationSpeed; 613 + setTimeout(animateSolution, delay); 614 + } else { 615 + // Mark this machine as solved 616 + const machine = machines[currentMachineIndex]; 617 + let isCorrect; 618 + if (currentMode === 1) { 619 + isCorrect = currentState.every((state, i) => state === machine.target[i]); 620 + } else { 621 + isCorrect = currentState.every((state, i) => state === machine.joltages[i]); 622 + } 623 + 624 + if (isCorrect) { 625 + solvedMachines.add(currentMachineIndex); 626 + updateStats(); 627 + } 628 + 629 + // Current machine done, move to next immediately 630 + if (currentMachineIndex < machines.length - 1) { 631 + if (isPlaying) { 632 + currentMachineIndex++; 633 + initMachine(); 634 + setTimeout(animateSolution, animationSpeed); 635 + } 636 + } else { 637 + // All done 638 + isPlaying = false; 639 + document.getElementById('play').textContent = '▶ Play'; 640 + setTimeout(() => { 641 + currentMachineIndex = 0; 642 + initMachine(); 643 + }, animationSpeed * 4); 644 + } 645 + } 646 + } 647 + 648 + function initMachine() { 649 + const machine = machines[currentMachineIndex]; 650 + showingSolution = false; 651 + currentStep = 0; 652 + 653 + if (currentMode === 1) { 654 + // Part 1 655 + currentState = new Array(machine.target.length).fill(false); 656 + buttonStates = new Array(machine.buttons.length).fill(0); 657 + 658 + const solution = solveMachine(machine); 659 + solutionSteps = []; 660 + solution.forEach((shouldPress, idx) => { 661 + if (shouldPress === 1) { 662 + solutionSteps.push(idx); 663 + } 664 + }); 665 + } else { 666 + // Part 2 667 + currentState = new Array(machine.joltages.length).fill(0); 668 + buttonStates = new Array(machine.buttons.length).fill(0); 669 + 670 + const solution = solveMachinePart2(machine); 671 + solutionSteps = []; 672 + solution.forEach((pressCount, idx) => { 673 + for (let i = 0; i < pressCount; i++) { 674 + solutionSteps.push(idx); 675 + } 676 + }); 677 + } 678 + 679 + renderMachine(); 680 + updateStats(); 681 + } 682 + 683 + // Initialize 684 + initMachine(); 685 + </script> 686 + </body> 687 + </html>