You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.7 KiB
111 lines
3.7 KiB
const std = @import("std");
|
|
|
|
const SEVEN_BYTES: u64 = (1 << 56) - 1;
|
|
|
|
fn solveLine(line: []const u8) u64 {
|
|
var boxes = std.mem.zeroes([256][1024]usize);
|
|
|
|
var i: usize = 0;
|
|
while (i < line.len) {
|
|
var lens_hash: u16 = 0;
|
|
var lens_name: u64 = 0;
|
|
while (i < line.len and line[i] != '-' and line[i] != '=') : (i += 1) {
|
|
lens_hash += line[i];
|
|
lens_hash *= 17;
|
|
lens_hash %= 256;
|
|
|
|
lens_name *= 256;
|
|
lens_name += line[i];
|
|
}
|
|
|
|
if (lens_name | SEVEN_BYTES != SEVEN_BYTES) {
|
|
unreachable;
|
|
}
|
|
|
|
var box = &boxes[lens_hash];
|
|
|
|
switch (line[i]) {
|
|
'-' => {
|
|
//std.debug.print("Going to remove {x} from box {d}\n", .{ lens_name, lens_hash });
|
|
for (box, 0..) |*slot, slot_index| {
|
|
_ = slot_index;
|
|
if (slot.* & SEVEN_BYTES == lens_name) {
|
|
//std.debug.print("Removed from {d}\n", .{slot_index});
|
|
slot.* = 0;
|
|
}
|
|
}
|
|
|
|
i += 1;
|
|
},
|
|
'=' => {
|
|
i += 1;
|
|
|
|
switch (line[i]) {
|
|
'0'...'9' => {
|
|
const focus = line[i] - '0';
|
|
const new_slot_value = lens_name | (@as(u64, focus) << 56);
|
|
//std.debug.print("Going to insert {x} into box {d}\n", .{ new_slot_value, lens_hash });
|
|
|
|
var slot_index: usize = 0;
|
|
while (slot_index < boxes.len) : (slot_index += 1) {
|
|
if (box[slot_index] & SEVEN_BYTES == lens_name) {
|
|
//std.debug.print("Inserted at {d}\n", .{slot_index});
|
|
box[slot_index] = new_slot_value;
|
|
break;
|
|
}
|
|
} else while (slot_index > 0) : (slot_index -= 1) {
|
|
if (box[slot_index - 1] != 0) {
|
|
//std.debug.print("Inserted at {d}\n", .{slot_index});
|
|
box[slot_index] = new_slot_value;
|
|
break;
|
|
}
|
|
} else {
|
|
//std.debug.print("Inserted at {d}\n", .{0});
|
|
box[0] = new_slot_value;
|
|
}
|
|
|
|
i += 1;
|
|
},
|
|
else => unreachable,
|
|
}
|
|
},
|
|
else => unreachable,
|
|
}
|
|
|
|
if (i < line.len and line[i] != ',') {
|
|
unreachable;
|
|
}
|
|
|
|
i += 1;
|
|
}
|
|
|
|
var result: u64 = 0;
|
|
for (boxes, 0..) |box, box_number| {
|
|
//std.debug.print("Computing result for box {d}\n", .{box_number});
|
|
var actual_slot_number: usize = 1;
|
|
for (box) |slot_value| {
|
|
if (slot_value != 0) {
|
|
const power = (box_number + 1) * actual_slot_number * (slot_value >> 56);
|
|
//std.debug.print("Found value in slot {d}: {x}; adding {d} to result\n", .{ actual_slot_number, slot_value, power });
|
|
result += power;
|
|
actual_slot_number += 1;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
pub fn main() !void {
|
|
const stdout = std.io.getStdOut().writer();
|
|
|
|
const raw_in = std.io.getStdIn();
|
|
var buffered_reader = std.io.bufferedReader(raw_in.reader());
|
|
var reader = buffered_reader.reader();
|
|
|
|
var result: u64 = 0;
|
|
var line_buffer: [30000]u8 = undefined;
|
|
while (try reader.readUntilDelimiterOrEof(&line_buffer, '\n')) |line| {
|
|
result += solveLine(line);
|
|
}
|
|
try stdout.print("{d}\n", .{result});
|
|
}
|
|
|