From d636db3ca2f3019e49b0f39940b947d83518da0e Mon Sep 17 00:00:00 2001 From: Sebastian Seedorf Date: Thu, 7 Dec 2023 14:43:04 +0100 Subject: [PATCH] Day 05 --- day05/input.txt | 183 ++++++++++++++++++++++++++++++++++++++++++++++++ day05/part1.py | 61 ++++++++++++++++ day05/part2.py | 81 +++++++++++++++++++++ 3 files changed, 325 insertions(+) create mode 100644 day05/input.txt create mode 100644 day05/part1.py create mode 100644 day05/part2.py diff --git a/day05/input.txt b/day05/input.txt new file mode 100644 index 0000000..7cd63b1 --- /dev/null +++ b/day05/input.txt @@ -0,0 +1,183 @@ +seeds: 629551616 310303897 265998072 58091853 3217788227 563748665 2286940694 820803307 1966060902 108698829 190045874 3206262 4045963015 223661537 1544688274 293696584 1038807941 31756878 1224711373 133647424 + +seed-to-soil map: +3809825462 2725979505 339457863 +3359244708 2085610478 450580754 +652041572 2536191232 189788273 +841829845 3346349446 343599367 +1408035723 73701258 732851393 +2140887116 3689948813 88205018 +0 3778153831 371129494 +2953980724 0 73701258 +3027681982 1754047752 331562726 +2229092134 1029159162 724888590 +1185429212 806552651 222606511 +371129494 3065437368 280912078 + +soil-to-fertilizer map: +201390752 0 263005475 +772560454 263005475 186665885 +3597849741 3228095269 216867970 +959226339 951560560 85171934 +2882237029 3813801625 34286208 +0 586356609 16090261 +1460387186 1189054013 136970257 +2511361703 2581174071 147006778 +201110502 1477157137 280250 +3582774663 3444963239 15075078 +2073881675 2245158204 30510333 +3127914126 3163440286 64654983 +1724767985 602446870 349113690 +1597357443 1036732494 127410542 +1044398273 1164143036 24910977 +635875205 449671360 136685249 +2916523237 2728180849 211390889 +1069309250 1854080268 391077936 +167223128 1820192894 33887374 +4168481019 2454687794 126486277 +3496254979 4048626015 86519684 +2454687794 4238293387 56673909 +2104392008 1648916365 171276529 +3814717711 3460038317 353763308 +464396227 1477437387 171478978 +2658368481 2939571738 223868548 +16090261 1326024270 151132867 +3393107291 4135145699 103147688 +3192569109 3848087833 200538182 + +fertilizer-to-water map: +357701033 441924316 54941059 +2047098412 1574732688 106451110 +2414997091 2961420861 217583761 +3647103220 3202843177 147888878 +1781607871 3397471081 265490541 +433955285 629676938 29320532 +3280739425 2494455782 366363795 +2818710889 1426835569 147897119 +1120892574 3179004622 23838555 +1539573533 3662961622 195295312 +3794992098 1820059317 63264836 +0 84223283 357701033 +1144731129 1702496991 117562326 +2153549522 2046878176 261447569 +593734757 726830618 239035306 +987137385 83279657 943626 +2966608008 0 83279657 +1734868845 3350732055 46739026 +1438972249 2860819577 100601284 +2632580852 2308325745 186130037 +1262293455 965865924 108845646 +412642092 1681183798 21313193 +472462518 1305563330 121272239 +988081011 496865375 132811563 +463275817 2037691475 9186701 +3049887665 1074711570 230851760 +832770063 1883324153 154367322 +1371139101 658997470 67833148 + +water-to-light map: +4062286509 3839153068 91029970 +1610728246 3827168971 11474903 +2753947407 2725849236 1101319735 +2525484879 1829977386 228462528 +657837215 1095779595 241604827 +1895347620 1337384422 492592964 +1425623249 4009599599 185104997 +2446068318 3930183038 79416561 +1894838426 3838643874 509194 +2389619503 896001044 56448815 +3855267142 2058439914 207019367 +1187459420 657837215 238163829 +1622203149 2467395620 172372577 +2387940584 952449859 1678919 +985523081 2265459281 201936339 +4153316479 954128778 141650817 +1794575726 4194704596 100262700 +899442042 2688664470 37184766 +936626808 2639768197 48896273 + +light-to-temperature map: +0 2682471120 43545350 +2829609407 2423668531 227914183 +3685065657 3821208881 65673550 +1319277847 0 33132672 +818263707 3091863377 5216721 +3144636417 670795080 1340457 +1352410519 895535914 570572224 +2709351136 1662268878 120258271 +115643652 2726016470 93054822 +455333494 1538206440 124062438 +3839611769 4030334543 30664857 +3750739207 4258515305 36451991 +2070721515 33132672 155555065 +3132740473 2067641423 5192544 +4147162986 3685065657 58311172 +4278703737 3743376829 16263559 +1070098598 2174489282 249179249 +716608392 2072833967 101655315 +43545350 1466108138 72098302 +3057523590 3016646494 75216883 +2700979566 887164344 8371570 +4205474158 4060999400 73229579 +2226276580 188687737 474702986 +1971879519 1968799427 98841996 +3931845119 4134228979 124286326 +579395932 2819071292 137212460 +3137933017 672135537 6703400 +1062694241 663390723 7404357 +3787191198 3886882431 52420571 +269061216 1782527149 186272278 +1031805835 2651582714 30888406 +823480428 678838937 208325407 +3870276626 3759640388 61568493 +4056131445 3939303002 91031541 +1922982743 3097080098 48896776 +208698474 2956283752 60362742 + +temperature-to-humidity map: +219529182 731674447 232727899 +2748076784 2771987989 46463882 +2514344851 4061235363 233731933 +0 1369964423 219529182 +452257081 362359049 21789881 +4243457964 2720478657 51509332 +3085663754 3109574959 64704581 +1639319644 384148930 347525517 +3150368335 3626166922 251414834 +1986845161 0 139120377 +1382707786 1339581093 30383330 +1413091116 1113352565 226228528 +2794540666 2818451871 291123088 +2125965538 338187591 24171458 +474046962 139120377 157229612 +2361125570 1100881680 12470885 +631276574 296349989 41837602 +3401783169 3428035243 198131679 +3989702261 3174279540 253755703 +2224646236 964402346 136479334 +2150136996 2299087215 74509240 +3806048654 3877581756 183653607 +3599914848 2514344851 206133806 +673114176 1589493605 709593610 + +humidity-to-location map: +4029426902 1202474782 191291587 +2764446301 708692227 493782555 +2188304413 3350514524 33021460 +3318755823 4213528230 67155117 +2000392671 620732246 87959981 +3754724301 3075811923 274702601 +3258228856 1393766369 60526967 +2088352652 4113576469 99951761 +363515622 1849258760 614077493 +1213242541 342257124 11129119 +1733046668 353386243 267346003 +1224371660 4280683347 14283949 +2577070088 2888435710 187376213 +4220718489 2832149614 56286096 +324294413 1810037551 39221209 +3385910940 2463336253 368813361 +977593115 3383535984 235649426 +1238655609 3619185410 494391059 +4277004585 324294413 17962711 +2221325873 1454293336 355744215 diff --git a/day05/part1.py b/day05/part1.py new file mode 100644 index 0000000..d2d726d --- /dev/null +++ b/day05/part1.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +from typing import List, Tuple + +lines = (x.strip() for x in open("input.txt")) +seeds = () +current_map = "undef" +maps = {} +map_names = [] + +for line in lines: + match line: + case "" | "\n": + continue + case x if x.startswith("seeds: "): + rest = x[len("seeds: "):] + seeds = tuple(int(y) for y in rest.split(" ")) + case x if x.endswith(" map:"): + rest = x[:-len(" map:")] + current_map = rest + maps[current_map] = [] + map_names.append(current_map) + case x if len(x) and x[0].isdigit(): + maps[current_map].append(tuple(int(y) for y in x.split(" "))) + case _: + pass + +def parse_map(value: List[Tuple[int, int, int]]): + curr = 0 + out = [] + for dest, src, size in sorted(value, key=lambda x: x[1]): + if src > curr: + out.append((curr, 0)) + if size > 0: + out.append((src, dest-src)) + curr = src + size + out.append((curr, 0)) + return out + +print(maps) +maps = {name: parse_map(value) for name, value in maps.items()} +print(maps) + +def find_largest_smaller_value(sorted_list, x): + low, high = 0, len(sorted_list) + + while low < high - 1: + mid = (low + high) // 2 + if sorted_list[mid][0] <= x: + low = mid + else: + high = mid + + return sorted_list[low] + +result = float("inf") +for seed in seeds: + for name in map_names: + seed += find_largest_smaller_value(maps[name], seed)[1] + result = min(seed, result) + +print(result) diff --git a/day05/part2.py b/day05/part2.py new file mode 100644 index 0000000..5928fd8 --- /dev/null +++ b/day05/part2.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +from typing import List, Tuple +from tqdm import tqdm + +lines = (x.strip() for x in open("input.txt")) +seeds = () +current_map = "undef" +maps = {} +map_names = [] + +for line in lines: + match line: + case "" | "\n": + continue + case x if x.startswith("seeds: "): + rest = x[len("seeds: "):] + seeds = tuple(int(y) for y in rest.split(" ")) + case x if x.endswith(" map:"): + rest = x[:-len(" map:")] + current_map = rest + maps[current_map] = [] + map_names.append(current_map) + case x if len(x) and x[0].isdigit(): + maps[current_map].append(tuple(int(y) for y in x.split(" "))) + case _: + pass + +def parse_map(value: List[Tuple[int, int, int]]): + curr = 0 + out = [] + for dest, src, size in sorted(value, key=lambda x: x[1]): + if src > curr: + out.append((curr, 0)) + if size > 0: + out.append((src, dest-src)) + curr = src + size + out.append((curr, 0)) + return out + +maps = {name: parse_map(value) for name, value in maps.items()} + +def find_largest_smaller_value(sorted_list, x): + low, high = 0, len(sorted_list) + + while low < high - 1: + mid = (low + high) // 2 + if sorted_list[mid][0] <= x: + low = mid + else: + high = mid + + return sorted_list[low], low + + +def merge_list(curr_map, next_map): + next_mapping = [] + for i in range(0, len(curr_map)): + dest_start = curr_map[i][0] + curr_map[i][1] + dest_start_idx = find_largest_smaller_value(next_map, dest_start)[1] + dest_end = curr_map[i + 1][0] + curr_map[i][1] - 1 if i + 1 < len(curr_map) else None + dest_end_idx = find_largest_smaller_value(next_map, dest_end)[1] if dest_end is not None else len(next_map) - 1 + for next_start, next_offset in next_map[dest_start_idx:dest_end_idx + 1]: + next_mapping.append((max(curr_map[i][0], next_start - curr_map[i][1]), curr_map[i][1] + next_offset)) + return next_mapping + +# merge lists into a single one +curr_map = maps[map_names[0]] +for name in map_names[1:]: + curr_map = merge_list(curr_map, maps[name]) + + +result = float("inf") +for i in range(0, len(seeds), 2): + dest_start = seeds[i] + dest_start_idx = find_largest_smaller_value(curr_map, dest_start)[1] + dest_end = seeds[i] + seeds[i+1] - 1 + dest_end_idx = find_largest_smaller_value(curr_map, dest_end)[1] + for next_start, next_offset in curr_map[dest_start_idx:dest_end_idx + 1]: + result = min(result, next_start + next_offset) + +print(result)