solve day 15
This commit is contained in:
parent
31c2a661c2
commit
ab6a4d4bb9
@ -2,7 +2,6 @@ const std = @import("std");
|
|||||||
const aoc = @import("./aoc.zig");
|
const aoc = @import("./aoc.zig");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const PointU32 = @import("./point.zig").Point(u32);
|
|
||||||
|
|
||||||
const Tile = enum {
|
const Tile = enum {
|
||||||
Empty,
|
Empty,
|
||||||
|
159
src/day15.zig
Normal file
159
src/day15.zig
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const aoc = @import("./aoc.zig");
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
const Input = struct {
|
||||||
|
parts: std.ArrayList([]const u8),
|
||||||
|
|
||||||
|
fn init(allocator: Allocator) Input {
|
||||||
|
return Input{
|
||||||
|
.parts = std.ArrayList([]const u8).init(allocator)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deinit(self: Input) void {
|
||||||
|
self.parts.deinit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const HashMapItem = struct {
|
||||||
|
key: []const u8,
|
||||||
|
value: u8
|
||||||
|
};
|
||||||
|
|
||||||
|
const HashMap = struct {
|
||||||
|
boxes: [256]std.ArrayList(HashMapItem),
|
||||||
|
|
||||||
|
fn init(allocator: Allocator) HashMap {
|
||||||
|
var boxes: [256]std.ArrayList(HashMapItem) = undefined;
|
||||||
|
for (0..256) |i| {
|
||||||
|
boxes[i] = std.ArrayList(HashMapItem).init(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
return HashMap{ .boxes = boxes };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deinit(self: HashMap) void {
|
||||||
|
for (self.boxes) |box| {
|
||||||
|
box.deinit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn put(self: *HashMap, key: []const u8, value: u8) !void {
|
||||||
|
const hash = compute_hash(key);
|
||||||
|
var box = &self.boxes[hash];
|
||||||
|
|
||||||
|
for (box.items) |*item| {
|
||||||
|
if (std.mem.eql(u8, item.key, key)) {
|
||||||
|
item.value = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try box.append(HashMapItem{ .key = key, .value = value });
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove(self: *HashMap, key: []const u8) void {
|
||||||
|
const hash = compute_hash(key);
|
||||||
|
var box = &self.boxes[hash];
|
||||||
|
for (0.., box.items) |i, item| {
|
||||||
|
if (std.mem.eql(u8, item.key, key)) {
|
||||||
|
_ = box.orderedRemove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn debug(self: HashMap) void {
|
||||||
|
for (0.., self.boxes) |i, box| {
|
||||||
|
if (box.items.len == 0) continue;
|
||||||
|
|
||||||
|
std.debug.print("Box {}:", .{i});
|
||||||
|
for (box.items) |item| {
|
||||||
|
std.debug.print(" [{s} {}]", .{item.key, item.value});
|
||||||
|
}
|
||||||
|
std.debug.print("\n", .{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn parse_input(allocator: Allocator, lines: []const []const u8) !Input {
|
||||||
|
var result = Input.init(allocator);
|
||||||
|
errdefer result.deinit();
|
||||||
|
|
||||||
|
var iter = std.mem.splitScalar(u8, lines[0], ',');
|
||||||
|
while (iter.next()) |part| {
|
||||||
|
try result.parts.append(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_hash(text: []const u8) u8 {
|
||||||
|
var current: u16 = 0;
|
||||||
|
for (text) |symbol| {
|
||||||
|
current += symbol;
|
||||||
|
current *= 17;
|
||||||
|
current %= 256;
|
||||||
|
}
|
||||||
|
return @intCast(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part1(input: *aoc.Input) !aoc.Result {
|
||||||
|
const parsed = try parse_input(input.allocator, input.lines);
|
||||||
|
defer parsed.deinit();
|
||||||
|
|
||||||
|
var result: u64 = 0;
|
||||||
|
for (parsed.parts.items) |item| {
|
||||||
|
result += compute_hash(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{ .uint = result };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part2(input: *aoc.Input) !aoc.Result {
|
||||||
|
const allocator = input.allocator;
|
||||||
|
const parsed = try parse_input(input.allocator, input.lines);
|
||||||
|
defer parsed.deinit();
|
||||||
|
|
||||||
|
var hash_map = HashMap.init(allocator);
|
||||||
|
defer hash_map.deinit();
|
||||||
|
|
||||||
|
for (parsed.parts.items) |inst| {
|
||||||
|
if (inst[inst.len - 1] == '-') {
|
||||||
|
const key = inst[0..(inst.len-1)];
|
||||||
|
hash_map.remove(key);
|
||||||
|
} else {
|
||||||
|
const equal_pos = std.mem.indexOfScalar(u8, inst, '=') orelse return error.InvalidInstruction;
|
||||||
|
const key = inst[0..equal_pos];
|
||||||
|
const value = inst[(equal_pos+1)] - '0';
|
||||||
|
try hash_map.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// std.debug.print("After \"{s}\":\n", .{inst});
|
||||||
|
// hash_map.debug();
|
||||||
|
// std.debug.print("\n", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
var result: u64 = 0;
|
||||||
|
for (1.., hash_map.boxes) |box_idx, box| {
|
||||||
|
for (1.., box.items) |item_idx, item| {
|
||||||
|
result += box_idx * item_idx * item.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{ .uint = result };
|
||||||
|
}
|
||||||
|
|
||||||
|
const example_input = [_][]const u8{
|
||||||
|
"rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7"
|
||||||
|
};
|
||||||
|
|
||||||
|
test "part 1 example" {
|
||||||
|
try aoc.expectAnswerUInt(part1, 1320, &example_input);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "part 2 example" {
|
||||||
|
try aoc.expectAnswerUInt(part2, 145, &example_input);
|
||||||
|
}
|
@ -35,6 +35,7 @@ const Days = [_]aoc.Day{
|
|||||||
create_day(@import("./day12.zig")),
|
create_day(@import("./day12.zig")),
|
||||||
create_day(@import("./day13.zig")),
|
create_day(@import("./day13.zig")),
|
||||||
create_day(@import("./day14.zig")),
|
create_day(@import("./day14.zig")),
|
||||||
|
create_day(@import("./day15.zig")),
|
||||||
};
|
};
|
||||||
|
|
||||||
fn kilobytes(count: u32) u32 {
|
fn kilobytes(count: u32) u32 {
|
||||||
@ -73,10 +74,8 @@ fn run(allocator: Allocator, args: *cli) !u8 {
|
|||||||
lines.deinit();
|
lines.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
var line_buf: [1024]u8 = undefined;
|
while (try reader.readUntilDelimiterOrEofAlloc(allocator, '\n', kilobytes(32))) |line| {
|
||||||
while (try reader.readUntilDelimiterOrEof(&line_buf, '\n')) |line| {
|
try lines.append(std.mem.trimRight(u8, line, &.{'\r'}));
|
||||||
var trimmed_line = std.mem.trimRight(u8, line, &.{'\r'});
|
|
||||||
try lines.append(try allocator.dupe(u8, trimmed_line));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var input = aoc.Input{ .allocator = allocator, .lines = lines.items };
|
var input = aoc.Input{ .allocator = allocator, .lines = lines.items };
|
||||||
@ -193,4 +192,5 @@ test {
|
|||||||
_ = @import("./day12.zig");
|
_ = @import("./day12.zig");
|
||||||
_ = @import("./day13.zig");
|
_ = @import("./day13.zig");
|
||||||
_ = @import("./day14.zig");
|
_ = @import("./day14.zig");
|
||||||
|
_ = @import("./day15.zig");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user