const std = @import("std");
const ArrayList = std.ArrayList;
const Lens = struct {
name: []u8,
value: u32,
};
pub fn solve_part1(allocator: std.mem.Allocator, file: []const u8) !void {
var inputs = try std.fs.cwd().openFile(file, .{});
var contents = try inputs.readToEndAlloc(allocator, 100 * 1024 * 1024);
var part1_result: u64 = 0;
var iter = std.mem.tokenizeScalar(u8, contents[0 .. contents.len - 1], ',');
var part2_result: u64 = 0;
var buffer: [128]u8 = undefined;
_ = buffer;
var boxes: []ArrayList(Lens) = try allocator.alloc(ArrayList(Lens), 256);
for (0..256) |box| {
boxes[box] = ArrayList(Lens).init(allocator);
}
while (iter.next()) |token| {
part1_result += compute_hash(token);
var i: u32 = 0;
while (token[i] != '-' and token[i] != '=') {
i += 1;
}
var lens_name = token[0..i];
var hash = compute_hash(lens_name);
if (token[i] == '=') {
i += 1;
var lens_strength = try std.fmt.parseInt(u32, token[i..], 10);
var exists = false;
for (boxes[hash].items) |*box| {
if (std.mem.eql(u8, box.name, lens_name)) {
box.value = lens_strength;
exists = true;
break;
}
}
if (!exists) {
try boxes[hash].append(.{ .name = try allocator.dupe(u8, lens_name), .value = lens_strength });
}
} else if (token[i] == '-') {
std.log.debug("Removing: {s} from Box({d})", .{ lens_name, hash });
var j: i64 = -1;
for (boxes[hash].items, 0..) |box, item| {
if (std.mem.eql(u8, box.name, lens_name)) {
j = @intCast(item);
break;
}
}
if (j >= 0) {
_ = boxes[hash].orderedRemove(@intCast(j));
}
}
}
for (boxes, 0..) |box, i| {
if (box.items.len > 0) {
std.log.info("Box({d}) = {d}", .{ i, box.items.len });
}
for (box.items, 1..) |lens, slot| {
std.log.info("{s} = {d}, {d}", .{ lens.name, lens.value, (i + 1) * lens.value * slot });
part2_result += (i + 1) * lens.value * slot;
}
}
std.log.info("Part 1 result: {d}", .{part1_result});
std.log.info("Part 2 result: {d}", .{part2_result});
}
fn compute_hash(chars: []const u8) u8 {
var hash: u64 = 0;
for (0..chars.len) |i| {
if (chars[i] == ',') {
std.log.info("D: {d}", .{hash});
hash = 0;
continue;
}
hash += chars[i];
hash *= 17;
hash %= 256;
}
return @intCast(hash);
}