From 8563c691ba77a33bb10e778f686cb98bb7dff700 Mon Sep 17 00:00:00 2001 From: Patrick Auernig Date: Fri, 8 Dec 2023 19:22:51 +0100 Subject: [PATCH] Add solution for 2023 day 05 part 1 --- 2023/README.md | 2 +- 2023/day-05/common.zig | 175 ++++++++++++++++++++++++++++++++ 2023/day-05/inputs/puzzle.txt | 183 ++++++++++++++++++++++++++++++++++ 2023/day-05/inputs/sample.txt | 33 ++++++ 2023/day-05/part_one.zig | 46 +++++++++ README.md | 2 +- 6 files changed, 439 insertions(+), 2 deletions(-) create mode 100644 2023/day-05/common.zig create mode 100644 2023/day-05/inputs/puzzle.txt create mode 100644 2023/day-05/inputs/sample.txt create mode 100644 2023/day-05/part_one.zig diff --git a/2023/README.md b/2023/README.md index a02854f..bf65bac 100644 --- a/2023/README.md +++ b/2023/README.md @@ -8,7 +8,7 @@ | [02] | ✓ | ✓ | [Zig] | | [03] | ✓ | ✓ | [Zig] | | [04] | ✓ | ✓ | [Zig] | -| [05] | | | | +| [05] | ✓ | | [Zig] | | [06] | | | | | [07] | | | | | [08] | | | | diff --git a/2023/day-05/common.zig b/2023/day-05/common.zig new file mode 100644 index 0000000..1b8968a --- /dev/null +++ b/2023/day-05/common.zig @@ -0,0 +1,175 @@ +const std = @import("std"); +const alloc = std.heap.page_allocator; +const List = std.ArrayList; +const HashMap = std.AutoHashMap(MappingKey, Mapping); +pub const Idx = u64; + +pub const SeedList = List(Idx); + +pub const MappingType = enum { + Seed, + Soil, + Fertilizer, + Water, + Light, + Temperature, + Humidity, + Location, +}; + +pub const MappingKey = struct { + MappingType, + MappingType, +}; + +pub const Mapping = struct { + dest_ranges: []MappingRange, + source_ranges: []MappingRange, + + pub fn get(self: Mapping, val: Idx) Idx { + for (self.source_ranges, 0..) |src_range, i| { + if (val >= src_range.start and val < src_range.end) { + const dest_range = self.dest_ranges[i]; + const dest_offset = (val - src_range.start); + return dest_range.start + dest_offset; + } + } + + return val; + } +}; + +pub const Input = struct { + mappings: HashMap, + seeds: SeedList, +}; + +pub const MappingRange = struct { + start: Idx, + end: Idx, +}; + +pub fn parse(data: []const u8) !Input { + var lines = std.mem.tokenizeSequence(u8, data, "\n"); + + var mappings = HashMap.init(alloc); + var seeds: SeedList = undefined; + var mapping_types: [2]MappingType = undefined; + var dest_ranges = List(MappingRange).init(alloc); + var source_ranges = List(MappingRange).init(alloc); + var collect_mapping = false; + + while (lines.next()) |line| { + if (std.mem.startsWith(u8, line, "seeds:")) { + seeds = try parse_seed_list(line); + } else if (std.mem.endsWith(u8, line, "map:")) { + mapping_types = parse_mapping_header(line); + } else { + const range = try parse_mapping_body(line); + try dest_ranges.append(range[0]); + try source_ranges.append(range[1]); + } + + if (lines.peek()) |next_line| { + const new_mapping = std.mem.endsWith(u8, next_line, "map:"); + collect_mapping = new_mapping and dest_ranges.items.len != 0; + } else { + collect_mapping = true; + } + + if (collect_mapping) { + const dranges = try dest_ranges.toOwnedSlice(); + const sranges = try source_ranges.toOwnedSlice(); + + const mapping = .{ + .dest_ranges = dranges, + .source_ranges = sranges, + }; + + const key = .{ + mapping_types[0], + mapping_types[1], + }; + + try mappings.put(key, mapping); + } + } + + const parsed = .{ .mappings = mappings, .seeds = seeds }; + + return parsed; +} + +fn parse_seed_list(line: []const u8) !SeedList { + var list = SeedList.init(alloc); + + var seeds = std.mem.tokenizeSequence(u8, line, " "); + _ = seeds.next(); + + while (seeds.next()) |seed| { + const seed_num = try std.fmt.parseInt(Idx, seed, 10); + try list.append(seed_num); + } + + return list; +} + +fn parse_mapping_header(line: []const u8) [2]MappingType { + const map_types = std.mem.trimRight(u8, line, " map:"); + + var map_types_iter = std.mem.tokenizeSequence(u8, map_types, "-to-"); + + var types: [2]MappingType = undefined; + + var i: u8 = 0; + while (map_types_iter.next()) |map_type| { + if (std.mem.eql(u8, map_type, "seed")) { + types[i] = MappingType.Seed; + } else if (std.mem.eql(u8, map_type, "soil")) { + types[i] = MappingType.Soil; + } else if (std.mem.eql(u8, map_type, "fertilizer")) { + types[i] = MappingType.Fertilizer; + } else if (std.mem.eql(u8, map_type, "water")) { + types[i] = MappingType.Water; + } else if (std.mem.eql(u8, map_type, "light")) { + types[i] = MappingType.Light; + } else if (std.mem.eql(u8, map_type, "temperature")) { + types[i] = MappingType.Temperature; + } else if (std.mem.eql(u8, map_type, "humidity")) { + types[i] = MappingType.Humidity; + } else if (std.mem.eql(u8, map_type, "location")) { + types[i] = MappingType.Location; + } else { + unreachable; + } + + i += 1; + } + + return types; +} + +fn parse_mapping_body(line: []const u8) ![2]MappingRange { + var values = std.mem.tokenizeScalar(u8, line, ' '); + + var parsed: [3]Idx = undefined; + + var i: u8 = 0; + while (values.next()) |val| { + const num = try std.fmt.parseInt(Idx, val, 10); + parsed[i] = num; + i += 1; + } + + const dest_range = .{ + .start = parsed[0], + .end = parsed[0] + parsed[2], + }; + + const source_range = .{ + .start = parsed[1], + .end = parsed[1] + parsed[2], + }; + + return .{ dest_range, source_range }; +} diff --git a/2023/day-05/inputs/puzzle.txt b/2023/day-05/inputs/puzzle.txt new file mode 100644 index 0000000..57d5462 --- /dev/null +++ b/2023/day-05/inputs/puzzle.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 \ No newline at end of file diff --git a/2023/day-05/inputs/sample.txt b/2023/day-05/inputs/sample.txt new file mode 100644 index 0000000..bd902a4 --- /dev/null +++ b/2023/day-05/inputs/sample.txt @@ -0,0 +1,33 @@ +seeds: 79 14 55 13 + +seed-to-soil map: +50 98 2 +52 50 48 + +soil-to-fertilizer map: +0 15 37 +37 52 2 +39 0 15 + +fertilizer-to-water map: +49 53 8 +0 11 42 +42 0 7 +57 7 4 + +water-to-light map: +88 18 7 +18 25 70 + +light-to-temperature map: +45 77 23 +81 45 19 +68 64 13 + +temperature-to-humidity map: +0 69 1 +1 0 69 + +humidity-to-location map: +60 56 37 +56 93 4 \ No newline at end of file diff --git a/2023/day-05/part_one.zig b/2023/day-05/part_one.zig new file mode 100644 index 0000000..0078c72 --- /dev/null +++ b/2023/day-05/part_one.zig @@ -0,0 +1,46 @@ +const std = @import("std"); +const common = @import("common.zig"); +const alloc = std.heap.page_allocator; +const List = std.ArrayList; +const Idx = common.Idx; + +const data = @embedFile("inputs/puzzle.txt"); + +pub fn main() !void { + const stdout = std.io.getStdOut().writer(); + + const parsed = try common.parse(data); + const mappings = parsed.mappings; + const seeds = parsed.seeds; + + var min_loc: ?Idx = null; + + for (seeds.items) |seed| { + const ss_map = mappings.get(.{ .Seed, .Soil }).?; + const soil = ss_map.get(seed); + + const sf_map = mappings.get(.{ .Soil, .Fertilizer }).?; + const fert = sf_map.get(soil); + + const fw_map = mappings.get(.{ .Fertilizer, .Water }).?; + const water = fw_map.get(fert); + + const wl_map = mappings.get(.{ .Water, .Light }).?; + const light = wl_map.get(water); + + const lt_map = mappings.get(.{ .Light, .Temperature }).?; + const temp = lt_map.get(light); + + const th_map = mappings.get(.{ .Temperature, .Humidity }).?; + const humi = th_map.get(temp); + + const hl_map = mappings.get(.{ .Humidity, .Location }).?; + const loc = hl_map.get(humi); + + if (min_loc == null or min_loc.? > loc) { + min_loc = loc; + } + } + + try stdout.print("{d}\n", .{min_loc.?}); +} diff --git a/README.md b/README.md index cc8c34f..78b8b81 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,4 @@ - [2020](2020/README.md) (20% completed) - [2021](2021/README.md) (68% completed) - [2022](2022/README.md) (54% completed) -- [2023](2023/README.md) (16% completed) +- [2023](2023/README.md) (18% completed)