diff --git a/day18.py b/day18.py new file mode 100644 index 0000000..5b62e3b --- /dev/null +++ b/day18.py @@ -0,0 +1,101 @@ +from tools.aoc import AOCDay +from tools.coordinate import Coordinate +from typing import Any, Iterable + + +DIRECTIONS = [Coordinate(1, 0), Coordinate(0, 1), Coordinate(-1, 0), Coordinate(0, -1)] +DIR_TRANS = {'R': 0, 'D': 1, 'L': 2, 'U': 3} + + +def get_borders(coords: set[tuple[Coordinate, Coordinate]]) -> (int, int, int, int): + """min_x, max_x, min_y, max_y""" + minX = list(sorted(coords))[0][0][0] + minY = list(sorted(coords, key=lambda d: (d[0][1], d[0][0])))[0][0][1] + maxX = list(sorted(coords, reverse=True))[0][0][0] + maxY = list(sorted(coords, key=lambda d: (d[0][1], d[0][0]), reverse=True))[0][0][1] + + return minX, maxX, minY, maxY + + +def split_polygon(coords: set[tuple[Coordinate, Coordinate]], cut_idx: int, horizontal: bool) -> (set[Coordinate], set[Coordinate]): + """split the polygon described by coords at cut_idx horizontally or vertically and return both resulting polygons""" + if horizontal: + vertical_edges = {x for x in coords if x[0].x == x[1].x} + intersecting_edges = {x for x in vertical_edges if min(x[0].y, x[1].y) <= cut_idx <= max(x[0].y, x[1].y)} + above = set() + below = set() + for c in coords: + if c in intersecting_edges: + # split into two + # c = ((from_x, from_y), (to_x, to_y)) + c_1 = (c[0], Coordinate(c[1].x, cut_idx)) + c_2 = (Coordinate(c[0].x, cut_idx), c[1]) + if c[0].y <= cut_idx: + above.add(c_1) + below.add(c_2) + else: + above.add(c_2) + below.add(c_1) + else: + if c[0].y <= cut_idx: + above.add(c) + if c[0].y >= cut_idx: + below.add(c) + return above, below + + +def get_inside_area(coords: set[tuple[Coordinate, Coordinate]]) -> int: + min_x, max_x, min_y, max_y = get_borders(coords) + if len(coords) == 4: # rectangle, hopefully + return (max_x - min_x - 1) * (max_y - min_y - 1) + else: + if max_x - min_x > max_y - min_y: + half_1, half_2 = split_polygon(coords, (max_x - min_x) // 2, horizontal=False) + else: + half_1, half_2 = split_polygon(coords, (max_y - min_y) // 2, horizontal=True) + return get_inside_area(half_1) + get_inside_area(half_2) + +class Day(AOCDay): + inputs = [ + [ + (62, "input18_test"), + (50603, "input18"), + ], + [ + (952408144115, "input18_test"), + (None, "input18"), + ] + ] + + def parse_input(self, part2: bool = False) -> Iterable[tuple[int, int]]: + for line in self.getInput(): + d, s, c = line.split() + if not part2: + yield DIR_TRANS[d], int(s) + else: + yield int(c[-2]), int(c[2:-2], 16) + + def get_lagoon_area(self, part2: bool = False) -> int: + start = Coordinate(0, 0) + edges = set() + perimeter = 0 + for d, l in self.parse_input(part2): + perimeter += l + end = start + DIRECTIONS[d] * l + edges.add((start, end)) + start = end + + print(split_polygon(edges, 4, True)) + + #return get_inside_area(edges) + perimeter + + def part1(self) -> Any: + return self.get_lagoon_area() + + def part2(self) -> Any: + return "" + + +if __name__ == '__main__': + day = Day(2023, 18) + day.run(verbose=True) diff --git a/inputs/input18 b/inputs/input18 new file mode 100644 index 0000000..38bda17 --- /dev/null +++ b/inputs/input18 @@ -0,0 +1,670 @@ +R 5 (#4f4602) +U 8 (#2c84c3) +R 7 (#5ad612) +D 3 (#4fe053) +R 3 (#469872) +D 8 (#3089f3) +R 2 (#74f592) +D 7 (#716733) +R 4 (#666e72) +U 5 (#4d3843) +R 7 (#6e9692) +U 5 (#721373) +R 4 (#0e6cd2) +U 8 (#1e2543) +R 7 (#464822) +U 8 (#1984a3) +R 2 (#523d02) +U 3 (#1984a1) +L 9 (#10c6c2) +U 5 (#1e2541) +L 6 (#449642) +U 6 (#504713) +L 4 (#00fdb2) +U 3 (#383883) +L 3 (#470ca0) +U 9 (#6653a3) +L 4 (#1941c0) +U 7 (#031ba3) +L 4 (#9cfe40) +D 4 (#389153) +L 11 (#010280) +D 2 (#7139e3) +R 11 (#15d4a0) +D 5 (#935731) +L 5 (#448f80) +D 5 (#20f881) +L 6 (#8aa820) +U 4 (#3bb9e1) +L 6 (#6e2700) +U 3 (#4113e3) +L 4 (#18af40) +U 2 (#38add3) +L 6 (#5369b0) +U 7 (#7647e3) +L 4 (#610f40) +U 5 (#50e583) +L 6 (#2294f0) +U 6 (#59f503) +L 3 (#0e3af0) +U 3 (#5cde83) +L 7 (#0e3af2) +U 7 (#618133) +L 8 (#14fbf2) +U 4 (#1ab3b3) +L 3 (#6d6092) +U 10 (#7e4f73) +L 3 (#15c672) +U 3 (#1e8e81) +L 5 (#3a0542) +U 5 (#1e8e83) +R 6 (#4b3772) +U 3 (#27f9f3) +R 3 (#230182) +U 8 (#675933) +R 5 (#73e602) +U 7 (#706813) +R 7 (#763b82) +U 7 (#1ba943) +R 4 (#197042) +D 10 (#583f83) +L 5 (#169440) +D 6 (#45bfc3) +L 2 (#169442) +D 5 (#21fb83) +R 7 (#0955a0) +D 4 (#8b2533) +R 3 (#297160) +U 7 (#2d7873) +R 5 (#586eb0) +D 7 (#3d8773) +R 6 (#586eb2) +U 3 (#504883) +R 4 (#44c900) +D 10 (#4f8971) +R 2 (#170290) +D 4 (#6bbef1) +R 4 (#4d28b0) +U 7 (#513df3) +R 3 (#9325a0) +U 7 (#3c61e3) +R 3 (#0d55d0) +U 4 (#556e51) +R 5 (#4810d0) +U 5 (#1f5151) +R 8 (#2411f0) +U 4 (#7406d1) +R 7 (#6c22c2) +U 3 (#2ffe91) +R 6 (#0137e0) +D 5 (#2b1981) +R 4 (#6a0340) +D 6 (#2b1983) +R 4 (#452420) +D 5 (#3dce83) +L 11 (#0e1920) +D 2 (#38f5a3) +R 11 (#182a90) +D 5 (#395b61) +R 5 (#293250) +U 4 (#315c21) +R 9 (#0b6a82) +U 3 (#343ab1) +L 9 (#0b6a80) +U 5 (#5a54d1) +R 5 (#4f39d0) +U 3 (#087193) +R 3 (#3fa802) +U 8 (#4d8be3) +R 4 (#1d4e70) +U 2 (#0f3b23) +R 5 (#1d4e72) +U 8 (#439893) +R 6 (#3fa800) +U 9 (#171a83) +R 4 (#478330) +U 7 (#395b63) +R 7 (#36b640) +U 3 (#8919b1) +R 3 (#1b5680) +U 5 (#5f5dc3) +R 3 (#3e6b10) +U 3 (#67d083) +L 7 (#5e6d10) +U 4 (#7ef021) +L 4 (#212c90) +D 6 (#483e21) +L 5 (#00e4b0) +U 6 (#8919b3) +L 5 (#57b580) +U 2 (#920b61) +L 5 (#1c5de0) +U 3 (#6c4233) +L 3 (#693bc0) +U 8 (#25c933) +L 6 (#0756d0) +U 3 (#875e93) +L 8 (#373ea0) +D 6 (#443e93) +R 8 (#0669d0) +D 2 (#383423) +R 3 (#0669d2) +D 3 (#26b6d3) +L 5 (#1a2210) +D 6 (#95dd33) +L 6 (#301710) +D 4 (#9fba63) +L 4 (#418770) +U 10 (#40bb51) +L 6 (#495cc0) +U 2 (#6569d1) +L 2 (#313920) +U 9 (#18e4e3) +L 3 (#155310) +U 11 (#6d8fd3) +L 2 (#155312) +U 8 (#1fb073) +L 6 (#188000) +U 9 (#513813) +L 7 (#56ad30) +D 9 (#56c443) +L 6 (#2b8730) +U 6 (#0a4033) +L 5 (#9f9650) +U 7 (#0a4031) +L 5 (#14e330) +U 7 (#7cfda3) +L 7 (#542ff2) +D 7 (#205843) +L 3 (#289f32) +U 7 (#050881) +L 6 (#555bb2) +U 6 (#79aa13) +R 6 (#322562) +U 6 (#79aa11) +R 3 (#46be72) +D 6 (#050883) +R 7 (#22c572) +U 6 (#954323) +R 3 (#0e3b10) +U 9 (#1247f1) +R 2 (#7193f0) +U 2 (#3b7fd3) +R 6 (#6004b0) +U 7 (#3b7fd1) +R 4 (#2c6650) +U 8 (#1247f3) +R 7 (#619a10) +D 7 (#5f5fd3) +R 3 (#5ad0a0) +U 9 (#0ff913) +R 4 (#51a360) +U 3 (#8c6673) +R 6 (#0d0080) +D 3 (#8c6671) +R 6 (#4518f0) +D 5 (#27bc61) +L 6 (#096fc2) +D 4 (#24d091) +R 3 (#5ae3c2) +D 3 (#075833) +L 5 (#688f72) +D 4 (#075831) +L 4 (#21b2f2) +U 4 (#2536d1) +L 7 (#762690) +D 8 (#3fd351) +R 7 (#511c00) +D 6 (#849391) +R 5 (#275350) +D 4 (#0a6f71) +R 6 (#0c6312) +D 10 (#9844f1) +L 6 (#0c6310) +D 4 (#2b6171) +R 4 (#0145e0) +D 7 (#647c43) +R 3 (#275b40) +D 5 (#5dc7e3) +R 6 (#840120) +U 10 (#353d53) +R 3 (#0c3f92) +U 2 (#170643) +R 4 (#0249d2) +U 8 (#56e233) +R 6 (#7bebd2) +U 3 (#03b7c3) +R 5 (#0f9372) +U 6 (#27b473) +L 5 (#1153c2) +U 3 (#0f6963) +R 2 (#6ee850) +U 2 (#1c6f33) +R 9 (#0058d2) +U 4 (#56f6d3) +L 5 (#451620) +U 6 (#4fe461) +L 6 (#692e30) +U 3 (#57e661) +R 7 (#126030) +U 4 (#46dc23) +R 3 (#4f8d80) +U 3 (#3639d3) +R 7 (#4f8d82) +U 5 (#2ab4d3) +R 3 (#1d7490) +U 2 (#5eb413) +R 9 (#665142) +U 6 (#19a163) +R 7 (#6d2c12) +U 4 (#19a161) +R 5 (#0a9bc2) +D 5 (#61cb83) +R 7 (#0058d0) +D 3 (#6dfe73) +R 7 (#404c90) +U 2 (#7be653) +R 2 (#2f2e70) +U 6 (#139a43) +R 4 (#9ec160) +U 6 (#2179b3) +R 6 (#439610) +U 6 (#40c653) +R 10 (#20f402) +U 5 (#3ddfd3) +R 8 (#0ad052) +D 3 (#1e77e3) +R 6 (#868962) +D 5 (#1dabe3) +R 3 (#355be0) +U 6 (#98d843) +R 4 (#43afb0) +U 4 (#089753) +L 5 (#0ba560) +U 8 (#4bae01) +L 2 (#4b6e90) +U 4 (#083f51) +R 7 (#4b6e92) +U 4 (#4d8241) +L 8 (#2d9cc0) +U 5 (#3df563) +R 8 (#13f780) +U 3 (#5ad861) +R 3 (#2d8ee0) +U 4 (#8c28c1) +R 4 (#416e50) +U 3 (#270d81) +R 5 (#3434f0) +U 7 (#131f21) +R 4 (#308032) +D 10 (#033631) +R 3 (#400412) +U 4 (#033633) +R 4 (#32ade2) +D 7 (#0ca571) +L 5 (#434850) +D 5 (#0014c1) +L 4 (#61d580) +D 2 (#7bd191) +L 6 (#49f1c0) +D 9 (#338cf1) +R 3 (#6ae010) +D 5 (#0f9861) +R 5 (#052ea0) +D 9 (#783f41) +R 7 (#4d9720) +D 5 (#2cf851) +R 8 (#16ab22) +D 4 (#2eb571) +R 3 (#5d2002) +D 3 (#6ec561) +R 4 (#1e1bf2) +D 5 (#9d7ad3) +R 2 (#2bbec2) +D 6 (#42c3f1) +R 3 (#053692) +D 5 (#7afb01) +R 7 (#3c5b42) +D 5 (#3de331) +R 3 (#2bee82) +D 4 (#49dfe3) +R 6 (#527f12) +D 3 (#386613) +R 4 (#25fc62) +D 5 (#8245f1) +R 6 (#38fbd2) +D 4 (#9f7551) +R 5 (#3016e2) +D 6 (#0e4b71) +R 9 (#2474f2) +D 3 (#794311) +L 9 (#545950) +D 4 (#3932d3) +R 4 (#89e900) +D 3 (#3932d1) +R 4 (#954110) +D 8 (#3720a1) +R 8 (#016650) +D 2 (#094423) +R 10 (#0370c0) +D 2 (#55c0d3) +R 4 (#57ed60) +U 7 (#48f7f3) +R 5 (#2db490) +D 7 (#2fad71) +R 3 (#0ab9f0) +D 7 (#5894f1) +L 5 (#0ab9f2) +D 10 (#1fba81) +L 6 (#351800) +D 3 (#28bbb1) +L 5 (#311772) +U 4 (#26c191) +L 3 (#5dbaf2) +U 4 (#26c193) +L 5 (#5941d2) +U 5 (#420791) +L 4 (#00f2b2) +D 2 (#8fe501) +L 2 (#023302) +D 11 (#5d6a03) +L 3 (#5585f2) +D 4 (#2ae131) +R 3 (#2d6612) +D 8 (#1e9a11) +R 4 (#2653d2) +D 9 (#777e11) +L 7 (#361ad2) +D 5 (#055663) +L 3 (#0d9700) +D 4 (#258fb3) +L 3 (#097a30) +U 3 (#6b82b3) +L 5 (#097a32) +U 6 (#141dd3) +L 4 (#0d9702) +U 3 (#1672c3) +L 4 (#4626a2) +U 3 (#5b1cc1) +L 7 (#00a3e2) +D 3 (#024d41) +L 6 (#8eae52) +D 7 (#11ad21) +L 2 (#632792) +D 5 (#124691) +L 5 (#8163d2) +D 4 (#0dae51) +R 9 (#83af20) +D 6 (#17b661) +L 5 (#3d9b20) +D 3 (#048e51) +L 3 (#766a02) +D 6 (#70b731) +L 4 (#150352) +U 6 (#149151) +L 5 (#35dcf2) +D 6 (#628761) +L 4 (#532780) +D 5 (#186df1) +R 8 (#5230f0) +D 5 (#5d00a1) +R 10 (#636ea0) +U 5 (#32f8c1) +R 3 (#08dbf2) +D 5 (#5353f1) +R 3 (#160d92) +D 4 (#141d61) +L 10 (#75ba32) +D 4 (#141d63) +L 2 (#25a1b2) +D 4 (#0a2cd1) +L 6 (#0a0520) +D 7 (#3af071) +L 7 (#458052) +D 4 (#84dc91) +L 4 (#458050) +D 4 (#064db1) +L 7 (#0a0522) +D 4 (#045c41) +L 2 (#2019b2) +D 8 (#464b01) +L 8 (#6545b2) +D 7 (#69de21) +L 4 (#36f092) +U 7 (#05b851) +L 7 (#465522) +U 3 (#5ac221) +L 7 (#0ff350) +U 9 (#18d201) +L 6 (#0ff352) +D 2 (#581881) +L 3 (#4f2400) +D 7 (#214703) +L 4 (#508c40) +D 3 (#6fafe3) +L 11 (#3ac130) +D 3 (#6fafe1) +R 7 (#4f65d0) +D 2 (#366683) +R 8 (#2f81b0) +D 5 (#3fd373) +L 7 (#0708b0) +D 7 (#5fa791) +L 6 (#5b5210) +D 5 (#37d961) +L 3 (#0136c0) +D 3 (#410391) +L 8 (#37d5c0) +D 3 (#5a4971) +L 5 (#37d5c2) +U 3 (#2ebf71) +L 5 (#3bcbe0) +U 8 (#8d40b3) +L 4 (#3e1ca0) +D 4 (#4ca9f3) +L 7 (#01f740) +D 8 (#0f45b3) +L 3 (#08f8a0) +D 6 (#81d273) +R 4 (#5b0040) +D 4 (#0827b1) +R 3 (#7e80b0) +D 5 (#5a7ea1) +R 3 (#35b430) +D 2 (#15f971) +R 6 (#35b432) +D 6 (#652251) +R 3 (#052ba0) +D 2 (#8d40b1) +R 7 (#3abef0) +D 4 (#508881) +R 6 (#6b21f2) +D 3 (#4b7eb1) +L 5 (#383b32) +D 2 (#0961c1) +L 7 (#1dded2) +D 3 (#2826f1) +R 3 (#5a6252) +D 11 (#40f431) +R 5 (#674fc2) +U 11 (#691b23) +R 4 (#1b55e2) +D 4 (#958121) +R 4 (#3755f0) +D 4 (#33fc01) +R 4 (#6a0d30) +D 4 (#33fc03) +R 9 (#4351f0) +D 5 (#21b291) +R 5 (#2e0cb0) +D 6 (#7d92b1) +R 5 (#212b60) +D 6 (#051951) +R 7 (#423c40) +U 6 (#06bfa1) +R 5 (#351560) +U 7 (#29b8f1) +R 4 (#1076a2) +U 6 (#51b301) +R 5 (#603ea2) +D 7 (#3ceaa1) +R 8 (#23c2c2) +D 3 (#47d7a1) +L 4 (#82ddc2) +D 2 (#5bb811) +L 4 (#783d42) +D 7 (#46cc41) +R 6 (#3c0fc0) +D 6 (#48add1) +L 4 (#3c7a40) +D 10 (#2cfbe1) +L 3 (#6a7490) +D 9 (#39ae81) +L 6 (#2c4d52) +U 4 (#8af541) +L 2 (#609a12) +U 7 (#8af543) +L 2 (#561732) +U 8 (#182b51) +L 7 (#7ac5b2) +D 7 (#1ab131) +L 7 (#4b0582) +U 6 (#4e36b1) +L 5 (#297762) +U 3 (#2fbec1) +L 9 (#297760) +U 4 (#434bf1) +L 2 (#136902) +U 3 (#3a5061) +L 3 (#6b8802) +D 3 (#3fa353) +L 2 (#3fbc90) +D 5 (#1e3ae3) +L 2 (#512542) +D 2 (#02b0d3) +L 7 (#3b5302) +D 2 (#7fadd3) +L 4 (#0bc5d2) +D 4 (#2b6a83) +L 4 (#4883f2) +U 3 (#8c02f3) +L 4 (#251df0) +U 8 (#63f6b1) +L 6 (#645560) +D 9 (#63f6b3) +L 4 (#574eb0) +D 2 (#1564e3) +L 3 (#3fbc92) +D 7 (#462163) +R 7 (#552242) +D 5 (#3edd13) +R 6 (#7059a2) +U 5 (#637143) +R 3 (#0bebb0) +D 7 (#0bc2f1) +R 5 (#3c0500) +D 3 (#028063) +R 4 (#6d8d70) +U 4 (#028061) +R 8 (#08de10) +U 6 (#0bc2f3) +R 6 (#0e6110) +D 5 (#3d9523) +R 2 (#293642) +D 5 (#606173) +R 7 (#55b2a2) +D 6 (#606171) +L 8 (#4dd462) +D 5 (#549da3) +L 8 (#85a922) +U 5 (#39f221) +L 5 (#714a02) +D 2 (#263a61) +L 3 (#33a852) +D 9 (#107611) +L 5 (#4e5c20) +U 2 (#53ea81) +L 2 (#569630) +U 9 (#3116f1) +L 5 (#4e7762) +D 8 (#3edd11) +L 5 (#6319f2) +D 3 (#62bd83) +R 4 (#5297e2) +D 5 (#1a3a73) +R 2 (#6232a2) +D 6 (#875fb3) +L 6 (#3548b2) +D 4 (#4906a3) +R 4 (#3548b0) +D 2 (#5cbda3) +R 5 (#640af2) +D 9 (#3ea403) +L 5 (#0f1652) +D 10 (#122bf3) +L 2 (#39bac2) +D 3 (#2dfe21) +L 2 (#286f22) +D 8 (#81f741) +R 5 (#286f20) +D 5 (#573921) +L 3 (#5a2cd2) +D 5 (#06a081) +L 3 (#99e732) +D 10 (#221fb1) +L 5 (#3d2472) +D 2 (#889cc1) +L 4 (#158342) +U 5 (#4bcdc3) +R 4 (#849802) +U 7 (#36e4c3) +L 4 (#021852) +U 5 (#088951) +L 3 (#2c6d22) +U 3 (#7a2931) +L 2 (#6701d2) +U 7 (#4cc381) +R 5 (#1a4512) +U 8 (#3ed731) +R 5 (#3b6510) +U 7 (#6aa701) +L 2 (#094e20) +U 3 (#915aa3) +L 8 (#51f690) +U 6 (#1feb03) +L 4 (#50f990) +U 8 (#1ec891) +L 5 (#40dee0) +U 4 (#5ff961) +L 8 (#40dee2) +U 3 (#3283b1) +L 4 (#24fdf0) +U 9 (#6105b1) +L 3 (#7a6ac0) +U 5 (#526101) +L 3 (#4783d2) +D 9 (#7da9e1) +L 4 (#2af352) +U 9 (#0e3ea1) +L 5 (#39ce52) +D 5 (#68e421) +L 6 (#228070) +U 4 (#66e011) +L 4 (#228072) +U 4 (#3ab461) +L 4 (#536572) +U 3 (#6feee3) +L 3 (#33fcf2) +U 7 (#073003) +L 3 (#54c3a2) +U 4 (#231ef3) +L 3 (#54c3a0) +U 8 (#703ac3) +R 5 (#22e582) +U 9 (#947293) +L 5 (#0599f2) +U 5 (#6a7f13) +L 3 (#74d552) +U 7 (#07bf23) +L 9 (#154f92) +U 4 (#389ee3) diff --git a/inputs/input18_test b/inputs/input18_test new file mode 100644 index 0000000..0ad754b --- /dev/null +++ b/inputs/input18_test @@ -0,0 +1,14 @@ +R 6 (#70c710) +D 5 (#0dc571) +L 2 (#5713f0) +D 2 (#d2c081) +R 2 (#59c680) +D 2 (#411b91) +L 5 (#8ceee2) +U 2 (#caa173) +L 1 (#1b58a2) +U 2 (#caa171) +R 2 (#7807d2) +U 3 (#a77fa3) +L 2 (#015232) +U 2 (#7a21e3) \ No newline at end of file