Day 15. So random this year. Fricking AIs
parent
40798151a9
commit
27aa24f503
@ -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", .{});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue