From 27aa24f5038124def8c41dcbf1d44e6ccf6d3881 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Fri, 15 Dec 2023 14:10:45 -0700 Subject: [PATCH] Day 15. So random this year. Fricking AIs --- day15/main.zig | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 day15/main.zig diff --git a/day15/main.zig b/day15/main.zig new file mode 100644 index 0000000..d96b228 --- /dev/null +++ b/day15/main.zig @@ -0,0 +1,115 @@ +const std = @import("std"); + +const Lens = struct { label: []const u8, focalLength: u8 }; + +pub fn main() !void { + var content = @embedFile("data.txt"); + + var words = std.mem.split(u8, content, ","); + + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const allocator = gpa.allocator(); + + var boxes = std.AutoHashMap(u32, std.ArrayList(Lens)).init(allocator); + defer boxes.deinit(); + + var part1: u32 = 0; + while (words.next()) |w| { + // stupid last char thing + const word = if (w[w.len - 1] == 10) w[0 .. w.len - 2] else w; + + // Part 1 + part1 += hash(word); + + // Part 2 + const dash = std.mem.indexOf(u8, word, "-"); + const equals = std.mem.indexOf(u8, word, "="); + const idx = dash orelse equals orelse unreachable; + const label = word[0..idx]; + const box = hash(label); + std.debug.print("\nAfter \"{s}\":\n", .{word}); + + if (dash != null) { + // if dash, find the box + if (boxes.getPtr(box)) |list| { + // get the list, and find a lens with this label in it + var indexToRemove: ?usize = null; + for (list.items, 0..) |l, i| { + if (std.mem.eql(u8, l.label, label)) { + indexToRemove = i; + } + } + + // if it's there, remove it + if (indexToRemove) |i| { + _ = list.orderedRemove(i); + } + } + } else { + // if equals, parse out parts, put it in the box + const focalLength = try std.fmt.parseInt(u8, word[idx + 1 ..], 10); + const lens = Lens{ .focalLength = focalLength, .label = label }; + + // does this list exist? use it. otherwise make a new one + var list = boxes.get(box) orelse std.ArrayList(Lens).init(allocator); + + // find if this lens is already in the list + var dupIdx: ?usize = null; + for (list.items, 0..) |l, i| { + if (std.mem.eql(u8, l.label, label)) { + dupIdx = i; + } + } + + // if it is, replace it with the new lens + if (dupIdx) |i| { + try list.replaceRange(i, 1, &[_]Lens{lens}); + } else { + try list.append(lens); + } + try boxes.put(box, list); + } + + printBoxes(boxes); + } + + std.debug.print("Part 1: {d}\n", .{part1}); + + var part2: usize = 0; + var it = boxes.iterator(); + while (it.next()) |box| { + const boxNumber = box.key_ptr.*; + + for (box.value_ptr.items, 0..) |lens, slotNumber| { + part2 += (boxNumber + 1) * (slotNumber + 1) * lens.focalLength; + } + } + + std.debug.print("Part 2: {d}\n", .{part2}); +} + +fn hash(word: []const u8) u32 { + var sum: u32 = 0; + for (word) |c| { + if (c == 10) { + break; + } + sum += c; + sum *= 17; + sum = sum % 256; + } + + return sum; +} + +fn printBoxes(boxes: std.AutoHashMap(u32, std.ArrayList(Lens))) void { + var it = boxes.iterator(); + while (it.next()) |list| { + std.debug.print("Box {d}: ", .{list.key_ptr.*}); + + for (list.value_ptr.items) |lens| { + std.debug.print("[{s} {d}] ", .{ lens.label, lens.focalLength }); + } + std.debug.print("\n", .{}); + } +}