|
| 1 | +#! /usr/bin/env python3 |
| 2 | +# |
| 3 | +# Advent of Code 2021 Day 22 |
| 4 | +# |
| 5 | + |
| 6 | +import re |
| 7 | +from collections import Counter |
| 8 | +from typing import NamedTuple |
| 9 | +from aoc import my_aocd |
| 10 | +import aocd |
| 11 | + |
| 12 | + |
| 13 | +class RebootStep(NamedTuple): |
| 14 | + x1: int |
| 15 | + x2: int |
| 16 | + y1: int |
| 17 | + y2: int |
| 18 | + z1: int |
| 19 | + z2: int |
| 20 | + on: bool |
| 21 | + |
| 22 | + |
| 23 | +def _parse(inputs: tuple[str]) -> list[RebootStep]: |
| 24 | + return [ |
| 25 | + RebootStep( |
| 26 | + *(map(int, re.findall(r'-?\d+', line))), |
| 27 | + line.split()[0] == "on") |
| 28 | + for line in inputs |
| 29 | + ] |
| 30 | + |
| 31 | + |
| 32 | +def _solve(steps: list[RebootStep]) -> int: |
| 33 | + cuboids = Counter() |
| 34 | + for s in steps: |
| 35 | + update = Counter() |
| 36 | + # delete = list() |
| 37 | + if s.on: |
| 38 | + update[(s.x1, s.x2, s.y1, s.y2, s.z1, s.z2)] += 1 |
| 39 | + for (ex1, ex2, ey1, ey2, ez1, ez2), en in cuboids.items(): |
| 40 | + # if ex1 >= s.x1 and ex2 <= s.x2 \ |
| 41 | + # and ey1 >= s.y1 and ey2 <= s.y2 \ |
| 42 | + # and ez1 >= s.z1 and ez2 <= s.z2: |
| 43 | + # delete.append((ex1, ex2, ey1, ey2, ez1, ez2)) |
| 44 | + # continue |
| 45 | + ix1 = max(s.x1, ex1) |
| 46 | + ix2 = min(s.x2, ex2) |
| 47 | + iy1 = max(s.y1, ey1) |
| 48 | + iy2 = min(s.y2, ey2) |
| 49 | + iz1 = max(s.z1, ez1) |
| 50 | + iz2 = min(s.z2, ez2) |
| 51 | + if ix1 <= ix2 and iy1 <= iy2 and iz1 <= iz2: |
| 52 | + update[(ix1, ix2, iy1, iy2, iz1, iz2)] -= en |
| 53 | + # for _ in delete: |
| 54 | + # del cuboids[_] |
| 55 | + cuboids.update(update) |
| 56 | + temp = Counter(cuboids) |
| 57 | + for k, v in temp.items(): |
| 58 | + if v == 0: |
| 59 | + del cuboids[k] |
| 60 | + return sum( |
| 61 | + ((x2 - x1 + 1) * (y2 - y1 + 1) * (z2 - z1 + 1)) * n |
| 62 | + for (x1, x2, y1, y2, z1, z2), n in cuboids.items() |
| 63 | + ) |
| 64 | + |
| 65 | + |
| 66 | +def part_1(inputs: tuple[str]) -> int: |
| 67 | + init_steps = [ |
| 68 | + s |
| 69 | + for s in _parse(inputs) |
| 70 | + if not (s.x1 < -50 or s.x2 > 50 |
| 71 | + or s.y1 < -50 or s.y2 > 50 |
| 72 | + or s.z1 < -50 or s.z2 > 50) |
| 73 | + ] |
| 74 | + return _solve(init_steps) |
| 75 | + |
| 76 | + |
| 77 | +def part_2(inputs: tuple[str]) -> int: |
| 78 | + return _solve(_parse(inputs)) |
| 79 | + |
| 80 | + |
| 81 | +TEST1 = """\ |
| 82 | +on x=10..12,y=10..12,z=10..12 |
| 83 | +on x=11..13,y=11..13,z=11..13 |
| 84 | +off x=9..11,y=9..11,z=9..11 |
| 85 | +on x=10..10,y=10..10,z=10..10 |
| 86 | +""".splitlines() |
| 87 | +TEST2 = """\ |
| 88 | +on x=-20..26,y=-36..17,z=-47..7 |
| 89 | +on x=-20..33,y=-21..23,z=-26..28 |
| 90 | +on x=-22..28,y=-29..23,z=-38..16 |
| 91 | +on x=-46..7,y=-6..46,z=-50..-1 |
| 92 | +on x=-49..1,y=-3..46,z=-24..28 |
| 93 | +on x=2..47,y=-22..22,z=-23..27 |
| 94 | +on x=-27..23,y=-28..26,z=-21..29 |
| 95 | +on x=-39..5,y=-6..47,z=-3..44 |
| 96 | +on x=-30..21,y=-8..43,z=-13..34 |
| 97 | +on x=-22..26,y=-27..20,z=-29..19 |
| 98 | +off x=-48..-32,y=26..41,z=-47..-37 |
| 99 | +on x=-12..35,y=6..50,z=-50..-2 |
| 100 | +off x=-48..-32,y=-32..-16,z=-15..-5 |
| 101 | +on x=-18..26,y=-33..15,z=-7..46 |
| 102 | +off x=-40..-22,y=-38..-28,z=23..41 |
| 103 | +on x=-16..35,y=-41..10,z=-47..6 |
| 104 | +off x=-32..-23,y=11..30,z=-14..3 |
| 105 | +on x=-49..-5,y=-3..45,z=-29..18 |
| 106 | +off x=18..30,y=-20..-8,z=-3..13 |
| 107 | +on x=-41..9,y=-7..43,z=-33..15 |
| 108 | +on x=-54112..-39298,y=-85059..-49293,z=-27449..7877 |
| 109 | +on x=967..23432,y=45373..81175,z=27513..53682 |
| 110 | +""".splitlines() |
| 111 | +TEST3 = """\ |
| 112 | +on x=-5..47,y=-31..22,z=-19..33 |
| 113 | +on x=-44..5,y=-27..21,z=-14..35 |
| 114 | +on x=-49..-1,y=-11..42,z=-10..38 |
| 115 | +on x=-20..34,y=-40..6,z=-44..1 |
| 116 | +off x=26..39,y=40..50,z=-2..11 |
| 117 | +on x=-41..5,y=-41..6,z=-36..8 |
| 118 | +off x=-43..-33,y=-45..-28,z=7..25 |
| 119 | +on x=-33..15,y=-32..19,z=-34..11 |
| 120 | +off x=35..47,y=-46..-34,z=-11..5 |
| 121 | +on x=-14..36,y=-6..44,z=-16..29 |
| 122 | +on x=-57795..-6158,y=29564..72030,z=20435..90618 |
| 123 | +on x=36731..105352,y=-21140..28532,z=16094..90401 |
| 124 | +on x=30999..107136,y=-53464..15513,z=8553..71215 |
| 125 | +on x=13528..83982,y=-99403..-27377,z=-24141..23996 |
| 126 | +on x=-72682..-12347,y=18159..111354,z=7391..80950 |
| 127 | +on x=-1060..80757,y=-65301..-20884,z=-103788..-16709 |
| 128 | +on x=-83015..-9461,y=-72160..-8347,z=-81239..-26856 |
| 129 | +on x=-52752..22273,y=-49450..9096,z=54442..119054 |
| 130 | +on x=-29982..40483,y=-108474..-28371,z=-24328..38471 |
| 131 | +on x=-4958..62750,y=40422..118853,z=-7672..65583 |
| 132 | +on x=55694..108686,y=-43367..46958,z=-26781..48729 |
| 133 | +on x=-98497..-18186,y=-63569..3412,z=1232..88485 |
| 134 | +on x=-726..56291,y=-62629..13224,z=18033..85226 |
| 135 | +on x=-110886..-34664,y=-81338..-8658,z=8914..63723 |
| 136 | +on x=-55829..24974,y=-16897..54165,z=-121762..-28058 |
| 137 | +on x=-65152..-11147,y=22489..91432,z=-58782..1780 |
| 138 | +on x=-120100..-32970,y=-46592..27473,z=-11695..61039 |
| 139 | +on x=-18631..37533,y=-124565..-50804,z=-35667..28308 |
| 140 | +on x=-57817..18248,y=49321..117703,z=5745..55881 |
| 141 | +on x=14781..98692,y=-1341..70827,z=15753..70151 |
| 142 | +on x=-34419..55919,y=-19626..40991,z=39015..114138 |
| 143 | +on x=-60785..11593,y=-56135..2999,z=-95368..-26915 |
| 144 | +on x=-32178..58085,y=17647..101866,z=-91405..-8878 |
| 145 | +on x=-53655..12091,y=50097..105568,z=-75335..-4862 |
| 146 | +on x=-111166..-40997,y=-71714..2688,z=5609..50954 |
| 147 | +on x=-16602..70118,y=-98693..-44401,z=5197..76897 |
| 148 | +on x=16383..101554,y=4615..83635,z=-44907..18747 |
| 149 | +off x=-95822..-15171,y=-19987..48940,z=10804..104439 |
| 150 | +on x=-89813..-14614,y=16069..88491,z=-3297..45228 |
| 151 | +on x=41075..99376,y=-20427..49978,z=-52012..13762 |
| 152 | +on x=-21330..50085,y=-17944..62733,z=-112280..-30197 |
| 153 | +on x=-16478..35915,y=36008..118594,z=-7885..47086 |
| 154 | +off x=-98156..-27851,y=-49952..43171,z=-99005..-8456 |
| 155 | +off x=2032..69770,y=-71013..4824,z=7471..94418 |
| 156 | +on x=43670..120875,y=-42068..12382,z=-24787..38892 |
| 157 | +off x=37514..111226,y=-45862..25743,z=-16714..54663 |
| 158 | +off x=25699..97951,y=-30668..59918,z=-15349..69697 |
| 159 | +off x=-44271..17935,y=-9516..60759,z=49131..112598 |
| 160 | +on x=-61695..-5813,y=40978..94975,z=8655..80240 |
| 161 | +off x=-101086..-9439,y=-7088..67543,z=33935..83858 |
| 162 | +off x=18020..114017,y=-48931..32606,z=21474..89843 |
| 163 | +off x=-77139..10506,y=-89994..-18797,z=-80..59318 |
| 164 | +off x=8476..79288,y=-75520..11602,z=-96624..-24783 |
| 165 | +on x=-47488..-1262,y=24338..100707,z=16292..72967 |
| 166 | +off x=-84341..13987,y=2429..92914,z=-90671..-1318 |
| 167 | +off x=-37810..49457,y=-71013..-7894,z=-105357..-13188 |
| 168 | +off x=-27365..46395,y=31009..98017,z=15428..76570 |
| 169 | +off x=-70369..-16548,y=22648..78696,z=-1892..86821 |
| 170 | +on x=-53470..21291,y=-120233..-33476,z=-44150..38147 |
| 171 | +off x=-93533..-4276,y=-16170..68771,z=-104985..-24507 |
| 172 | +""".splitlines() |
| 173 | + |
| 174 | + |
| 175 | +def main() -> None: |
| 176 | + puzzle = aocd.models.Puzzle(2021, 22) |
| 177 | + my_aocd.print_header(puzzle.year, puzzle.day) |
| 178 | + |
| 179 | + assert part_1(TEST1) == 39 |
| 180 | + assert part_1(TEST2) == 590_784 |
| 181 | + assert part_1(TEST3) == 474_140 |
| 182 | + assert part_2(TEST3) == 2_758_514_936_282_235 |
| 183 | + |
| 184 | + inputs = my_aocd.get_input(puzzle.year, puzzle.day, 420) |
| 185 | + result1 = part_1(inputs) |
| 186 | + print(f"Part 1: {result1}") |
| 187 | + result2 = part_2(inputs) |
| 188 | + print(f"Part 2: {result2}") |
| 189 | + my_aocd.check_results(puzzle, result1, result2) |
| 190 | + |
| 191 | + |
| 192 | +if __name__ == '__main__': |
| 193 | + main() |
0 commit comments