From 7944889184e2a15a3aeb2057b49e2ac4d55035a8 Mon Sep 17 00:00:00 2001
From: Patrick Auernig <patrick.auernig@mykolab.com>
Date: Fri, 8 Dec 2023 20:42:10 +0100
Subject: [PATCH] Add solution for 2023 day 05 part 2

---
 2023/README.md           |  2 +-
 2023/day-05/common.zig   |  6 ++--
 2023/day-05/part_two.zig | 67 ++++++++++++++++++++++++++++++++++++++++
 README.md                |  2 +-
 4 files changed, 72 insertions(+), 5 deletions(-)
 create mode 100644 2023/day-05/part_two.zig

diff --git a/2023/README.md b/2023/README.md
index bf65bac..32dee94 100644
--- a/2023/README.md
+++ b/2023/README.md
@@ -8,7 +8,7 @@
 | [02] |   ✓    |   ✓    | [Zig]    |
 | [03] |   ✓    |   ✓    | [Zig]    |
 | [04] |   ✓    |   ✓    | [Zig]    |
-| [05] |   ✓    |        | [Zig]    |
+| [05] |   ✓    |   ✓    | [Zig]    |
 | [06] |        |        |          |
 | [07] |        |        |          |
 | [08] |        |        |          |
diff --git a/2023/day-05/common.zig b/2023/day-05/common.zig
index 1b8968a..80b9723 100644
--- a/2023/day-05/common.zig
+++ b/2023/day-05/common.zig
@@ -1,7 +1,7 @@
 const std = @import("std");
 const alloc = std.heap.page_allocator;
 const List = std.ArrayList;
-const HashMap = std.AutoHashMap(MappingKey, Mapping);
+pub const Mappings = std.AutoHashMap(MappingKey, Mapping);
 pub const Idx = u64;
 
 pub const SeedList = List(Idx);
@@ -40,7 +40,7 @@ pub const Mapping = struct {
 };
 
 pub const Input = struct {
-    mappings: HashMap,
+    mappings: Mappings,
     seeds: SeedList,
 };
 
@@ -52,7 +52,7 @@ pub const MappingRange = struct {
 pub fn parse(data: []const u8) !Input {
     var lines = std.mem.tokenizeSequence(u8, data, "\n");
 
-    var mappings = HashMap.init(alloc);
+    var mappings = Mappings.init(alloc);
     var seeds: SeedList = undefined;
     var mapping_types: [2]MappingType = undefined;
     var dest_ranges = List(MappingRange).init(alloc);
diff --git a/2023/day-05/part_two.zig b/2023/day-05/part_two.zig
new file mode 100644
index 0000000..863b1d5
--- /dev/null
+++ b/2023/day-05/part_two.zig
@@ -0,0 +1,67 @@
+const std = @import("std");
+const common = @import("common.zig");
+const Idx = common.Idx;
+const AtomicIdx = std.atomic.Value(Idx);
+const AtomicOrder = std.builtin.AtomicOrder;
+const Mappings = common.Mappings;
+const List = std.ArrayList;
+const alloc = std.heap.page_allocator;
+
+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 chunk = std.mem.window(Idx, seeds.items, 2, 2);
+    var threads = List(std.Thread).init(alloc);
+
+    var min_loc = AtomicIdx.init(18_446_744_073_709_551_615);
+
+    // Just brute force this bitch
+    while (chunk.next()) |pair| {
+        const start = pair[0];
+        const end = pair[0] + pair[1];
+
+        const thread = try std.Thread.spawn(.{}, get_min_location, .{ &mappings, &min_loc, start, end });
+        try threads.append(thread);
+    }
+
+    for (threads.items) |thread| {
+        thread.join();
+    }
+
+    try stdout.print("{d}\n", .{min_loc.raw});
+}
+
+fn get_min_location(mappings: *const Mappings, min_loc: *AtomicIdx, start: Idx, end: Idx) !void {
+    for (start..end) |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 (loc < min_loc.load(AtomicOrder.SeqCst)) {
+            min_loc.store(loc, AtomicOrder.SeqCst);
+        }
+    }
+}
diff --git a/README.md b/README.md
index 78b8b81..af438d7 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) (18% completed)
+-   [2023](2023/README.md) (20% completed)