solve day 15

This commit is contained in:
Rokas Puzonas 2024-04-14 22:45:09 +03:00
parent 31c2a661c2
commit ab6a4d4bb9
3 changed files with 163 additions and 5 deletions

View File

@ -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
View 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);
}

View File

@ -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");
} }