day 16, part 2

main
Inga 🏳‍🌈 5 months ago
parent 84be840255
commit a1dbe7a8d0
  1. 70
      day16-hard/build.zig
  2. 110
      day16-hard/hard.in
  3. 10
      day16-hard/sample.in
  4. 297
      day16-hard/src/main.zig

@ -0,0 +1,70 @@
const std = @import("std");
// Although this function looks imperative, note that its job is to
// declaratively construct a build graph that will be executed by an external
// runner.
pub fn build(b: *std.Build) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard optimization options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
// set a preferred release mode, allowing the user to decide how to optimize.
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "day16-hard",
// In this case the main source file is merely a path, however, in more
// complicated build scripts, this could be a generated file.
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
// This declares intent for the executable to be installed into the
// standard location when the user invokes the "install" step (the default
// step when running `zig build`).
b.installArtifact(exe);
// This *creates* a Run step in the build graph, to be executed when another
// step is evaluated that depends on it. The next line below will establish
// such a dependency.
const run_cmd = b.addRunArtifact(exe);
// By making the run step depend on the install step, it will be run from the
// installation directory rather than directly from within the cache directory.
// This is not necessary, however, if the application depends on other installed
// files, this ensures they will be present and in the expected location.
run_cmd.step.dependOn(b.getInstallStep());
// This allows the user to pass arguments to the application in the build
// command itself, like this: `zig build run -- arg1 arg2 etc`
if (b.args) |args| {
run_cmd.addArgs(args);
}
// This creates a build step. It will be visible in the `zig build --help` menu,
// and can be selected like this: `zig build run`
// This will evaluate the `run` step rather than the default, which is "install".
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
// Creates a step for unit testing. This only builds the test executable
// but does not run it.
const unit_tests = b.addTest(.{
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
const run_unit_tests = b.addRunArtifact(unit_tests);
// Similar to creating the run step earlier, this exposes a `test` step to
// the `zig build --help` menu, providing a way for the user to request
// running the unit tests.
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_unit_tests.step);
}

@ -0,0 +1,110 @@
\...|.........\........./.................\...\.../.\/../|....\................./..../........-\..-.\-..../...
...|....\................../.............../-....--..........-......-......\....-........../-..............|..
..............\....../.........../...................|.........\.................|.-................../.......
.........................\........../..-........./.../..........|....................-....\./.........|.......
.-.......\......-.-................|......................................-..............\......./............
............|...|..|.|............................../-..........\..\.......................................\-.
...|.|.\........./......|....|......./............/...\......../.../.........../.../............/.-...-.|.....
..................../.....-.........\......-....|.......................\.....-...............................
../............|.|.-....-.........../|........-..|....|.....................-.-.....\...-.......|.............
..-./..............-.............-......................./............/.......|.....-..........|.........../..
......|.........-|.|/..........-......................\.|./.....\....-..........................|./-./........
.|...-.............-.....-.............|.../..............|-........................\........\...|./..........
............/.........\.......-..........|........../.....\......\....|...............|.......................
|...||....\.......|..........|.....|................./.......-...................|............/...............
.......-.....\-.....................\...|................................|..........|......\..\.........-/....
............../.............................\.........................\|............-.........................
.......-..|........./..........|...-......././......./...../..........................|...../............/....
.-/......-.............../../........................\............\.....|.//.......-.................|.......\
........-......|.....-.............\............\...................-...\...............-............|........
...-.......................-...................\....|.......-.............|./..\....|.....................|...
.......-..\...|/.\........\...........-.....................\.../.....|.|........../.........-................
....|..../..........\/..........-..................-............|......./.......-......\.....||....../.....-..
|.-........................-....\...../......\.......|\......-...........-......\.............................
\.....\........\........\......................-....................\...........-.../.........................
..-...|.|.........--.........-.|......\........-.................\...................................|.......|
-..|.....-.......-.......|......|./........../...........-......|..................-..........................
...................||..\........|............\..|............\............-..-.......|........................
..........-..........-..|........./....|..-......./..-|...|.....\......./...-|../.../......./..|..............
....\|..................|......................................................../.....|.....|....||../.......
.......................-.../..|.............-.|..........|.......................-....-......-................
.......|./.............-........./...........\..........|-........\.....-....|....|........-.......\....\.....
../........./.......................|................/.....-...................|...............\.../.....\....
........................|...........................|.................................................../.....
|\.....|....................-..................-.........................\......\...-..............-..........
..................................|.....\..\-|........................................................-.......
.../....-...../|-.|.....\.../............/|......................./.....-............|.\.......-../...........
.\......|.......................\..-\.........|.....-........./............\.......|....|...|...././....\....-
.\......\..........................\......-.......|.\.............../...\/.....-........|....|................
\...-.......|\..|............../.../...........|.............-.................-.......................\./.|..
....-......................../.......................\..../................\.............\................/..|
...-...|......../.-...........-.........................................../\.|....-|........-\................
\-.../........|.......................-.....................|......./........................|...........\.\-.
......\.-......./............\.................-...|..............|./../....\.-............-./.......|........
........./...........|.....|../........./....................|.\..\-..|........\......|\..................../.
-..........\......-.............................\....|......\..........|.................-....................
.......................|.....|....................................-..\...................................../..
......../.\........./.../....\.../..||.\|......................................|........................../...
..\..................|....../.........\.........-....-|........-.....................-........\...../..|......
...|.........|...|.....|.....\..-.../...../.........-.....|............../....................................
.......\.........\......-...-........./.............../........./......|../.............../........-....-.....
..........|..........................\.-...\.........../..../..\................|.........../.....\...........
.........\....../.....................................................-.............|.-.......................
......-..........|..-......-.................\................/........../............-.|....|.|\......-......
....\............|..../..................|......|..-.-....\......|./.........|...........|....//.|..-.........
|........................||...../-.........../...../.-..................................|..........-.........-
....-\...............|.............................\.-..../......................./....\..............\../.|..
......\.|................/../..|............-.....|...\..............................|.............|.........-
...................\.....|...............|..\.-......\........../.\...........................................
........|....................-..\\....................-/...../......../.|...........\......-.|........-.......
............\...-./........./.....................................................-...........................
\...|.....\...\......................-......./..../../...............\......./../......................-.....-
.........../.......\..../..................................-......|.../.............././.....................\
.....................|......\........-......................../.|....................|...................../.-
.....\./....\..../\..|...........|.-.....|..............\..............-.\............../.....................
.......-.....|...........\.|\....\..|......|.......././............/...-...|-.-../......||...\................
...................../...\....|../..|................-.......\...............................\................
.......-.....\\......\....\...|....|......\...........\.\..../.....\.......................|.../..............
........-......................../.\............................./................|.....|.....................
......\-...../.|.........\..........\...\/..-......................//.....................|..................\
...............|/.........../.......................-....|..................\........-...\-...\...........\...
...-/..................................................|.........................-.......\.-.............|....
|/......................../.........../........../....|...../............-.........\....-.....................
.............-/....|../.............|.............-.-.\.\......./\............../.....\...|................|..
|......-.........../...|........\........../........................................./.................-......
....|......../..-|....-..........|-..................\.\..\.................\.-..|............./.......-......
...............-.........-........../....................||.-........................-.....-.\................
...............|........\.......|./.../...........-...../...\....-./....|.....................\...\...........
........../................................./.\........./......./.....|.../....|./...../...........\...|.\.-..
.../..../........................|....-..........................-..|.\-..............|.....\.........-.......
......|..|........../.................|.........|..../..............././............\-.-...............-.....-
......\../|.|......../........................\..\.......|........................\./........./...............
...../......../........\.|.................|............................-........................|....\.......
|.-|........|.|./.-...........-\...-../../.../..|..........................\.....|.........../................
..\...././............././...../...............|./.../..../..........-........-../...-....................\...
.....\....................../..|.........................\.....-/................-......................../...
...........|............................../....|.......................-........|......................./.....
../..|............-..............\.................//..................../\.|......-.//........./.............
........|....................../|...........|...../......|......-....\................/.............-......||.
\....-..............\..............-../.....-.....................-.../............/............../.\...-.....
./....\...............|..................|..../.....\..........-|......../...........-.\./....................
/..-....../........................../.\....\....\-............................../....-........\..............
..............-.\..............-..............\-|....|............../..-..././..............\..|..............
......................\-..............|........-....-........-....................../......\..................
................\.|./.......|....../...-.........-..................\............-........./.|................
...................-............................................-...|...../....\........../...-.../...........
.....\....................-...................\../....................................|..........-............
..../.......\/-.\...-........./......./........|....................................-.........................
....|....................................-.........|\..................\.......-..\.....-...\-......|.........
................................./.................................../.-../...|.\...............|.....\.......
..|..........-.-\...........................|................-.........../...\..............-\/............-.-
....|......./-.........|.................|............|...|.........................-.....................\...
.-.|.........-...|.............................\......../.\............|..............-...\........\|./...|./.
..../\...........\............-.../..\...................././....-..........|.........|..|.............|......
....................-..................................-...........\|....................|...\...|............
...-.|......................./.-...................-.../......|.........................../...................
...........................\....|\........\.......\.|...../.............-.|../.......................-........
...........................................|...-............\......................../.............-..........
..........|.|..........\.../.........|.....-.........-....|............-........../....../......./..-........|
.../.....\.................\........\.................................../....|...-......./..........\.....|/..
.......|....\.....|...............|........-|.........../............/../.\...\......................\........

@ -0,0 +1,10 @@
.|...\....
|.-.\.....
.....|-...
........|.
..........
.........\
..../.\\..
.-.-/..|..
.|....-|.\
..//.|....

@ -0,0 +1,297 @@
const std = @import("std");
fn StackList(comptime T: type, comptime capacity_type: type, comptime capacity: capacity_type) type {
return struct {
const Self = @This();
mem: [capacity]T,
length: capacity_type,
fn add(self: *Self, value: T) void {
self.mem[self.length] = value;
self.length += 1;
}
fn addIfNotNull(self: *Self, nullable_value: ?T) void {
if (nullable_value) |value| {
self.add(value);
}
}
fn has(self: *Self, needle: T) bool {
for (0..self.length) |i| {
if (self.mem[i] == needle) {
return true;
}
}
return false;
}
fn getMutableSlice(self: *Self) []T {
return (&self.mem)[0..self.length];
}
fn getSlice(self: *const Self) []const T {
return self.mem[0..self.length];
}
fn init() Self {
return Self{
.mem = undefined,
.length = 0,
};
}
};
}
const CellStatus = packed struct(u8) {
left: bool = false,
right: bool = false,
up: bool = false,
down: bool = false,
_padding: u4 = 0,
};
const Task = packed struct(u32) {
x: u12,
y: u12,
status: CellStatus,
};
const Queue = StackList(Task, usize, 65534);
fn getUpTask(original_task: Task) ?Task {
if (original_task.x == 0) {
return null;
}
return .{
.x = original_task.x - 1,
.y = original_task.y,
.status = .{ .up = true },
};
}
fn getDownTask(original_task: Task, lines: []const []const u8) ?Task {
if (original_task.x + 1 >= lines.len) {
return null;
}
return .{
.x = original_task.x + 1,
.y = original_task.y,
.status = .{ .down = true },
};
}
fn getLeftTask(original_task: Task) ?Task {
if (original_task.y == 0) {
return null;
}
return .{
.x = original_task.x,
.y = original_task.y - 1,
.status = .{ .left = true },
};
}
fn getRightTask(original_task: Task, lines: []const []const u8) ?Task {
if (original_task.y + 1 >= lines[original_task.x].len) {
return null;
}
return .{
.x = original_task.x,
.y = original_task.y + 1,
.status = .{ .right = true },
};
}
fn solveForStart(lines: []const []const u8, firstTask: Task) usize {
var state = std.mem.zeroes([128][128]CellStatus);
var tasks = Queue.init();
tasks.add(firstTask);
var step: usize = 0;
while (step < tasks.length) : (step += 1) {
const task = tasks.mem[step];
var cell_state = &state[task.x][task.y];
var cell_value = lines[task.x][task.y];
if (task.status.left and !cell_state.*.left) {
cell_state.*.left = true;
switch (cell_value) {
'.', '-' => {
tasks.addIfNotNull(getLeftTask(task));
},
'\\' => {
tasks.addIfNotNull(getUpTask(task));
},
'/' => {
tasks.addIfNotNull(getDownTask(task, lines));
},
'|' => {
tasks.addIfNotNull(getUpTask(task));
tasks.addIfNotNull(getDownTask(task, lines));
},
else => unreachable,
}
}
if (task.status.right and !cell_state.*.right) {
cell_state.*.right = true;
switch (cell_value) {
'.', '-' => {
tasks.addIfNotNull(getRightTask(task, lines));
},
'/' => {
tasks.addIfNotNull(getUpTask(task));
},
'\\' => {
tasks.addIfNotNull(getDownTask(task, lines));
},
'|' => {
tasks.addIfNotNull(getUpTask(task));
tasks.addIfNotNull(getDownTask(task, lines));
},
else => unreachable,
}
}
if (task.status.up and !cell_state.*.up) {
cell_state.*.up = true;
switch (cell_value) {
'.', '|' => {
tasks.addIfNotNull(getUpTask(task));
},
'\\' => {
tasks.addIfNotNull(getLeftTask(task));
},
'/' => {
tasks.addIfNotNull(getRightTask(task, lines));
},
'-' => {
tasks.addIfNotNull(getLeftTask(task));
tasks.addIfNotNull(getRightTask(task, lines));
},
else => unreachable,
}
}
if (task.status.down and !cell_state.*.down) {
cell_state.*.down = true;
switch (cell_value) {
'.', '|' => {
tasks.addIfNotNull(getDownTask(task, lines));
},
'/' => {
tasks.addIfNotNull(getLeftTask(task));
},
'\\' => {
tasks.addIfNotNull(getRightTask(task, lines));
},
'-' => {
tasks.addIfNotNull(getLeftTask(task));
tasks.addIfNotNull(getRightTask(task, lines));
},
else => unreachable,
}
}
}
var result: usize = 0;
for (0..state.len) |i| {
for (0..state[i].len) |j| {
if (@as(u8, @bitCast(state[i][j])) != 0) {
//std.debug.print("#", .{});
result += 1;
} else {
//std.debug.print(".", .{});
}
}
//std.debug.print("\n", .{});
}
return result;
}
fn solveLines(lines: []const []const u8) usize {
var result: usize = 0;
for (0..lines.len) |i| {
result = @max(result, solveForStart(lines, .{
.x = @intCast(i),
.y = 0,
.status = .{
.right = true,
},
}));
result = @max(result, solveForStart(lines, .{
.x = @intCast(i),
.y = @intCast(lines[i].len - 1),
.status = .{
.left = true,
},
}));
}
for (0..lines[0].len) |j| {
result = @max(result, solveForStart(lines, .{
.x = 0,
.y = @intCast(j),
.status = .{
.down = true,
},
}));
result = @max(result, solveForStart(lines, .{
.x = @intCast(lines.len - 1),
.y = @intCast(j),
.status = .{
.up = true,
},
}));
}
return result;
}
pub fn solveAll(reader: anytype) !usize {
var result: usize = 0;
while (true) {
var allocator_buffer: [20000]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&allocator_buffer);
var allocator = fba.allocator();
var lines = StackList([]u8, usize, 150).init();
var empty_line_reached = false;
var line_buffer: [1000]u8 = undefined;
while (try reader.readUntilDelimiterOrEof(&line_buffer, '\n')) |line| {
if (line.len == 0) {
empty_line_reached = true;
break;
}
lines.add(try allocator.dupe(u8, line));
}
result += solveLines(lines.getMutableSlice());
if (!empty_line_reached) {
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();
const result = try solveAll(&reader);
try stdout.print("{d}\n", .{result});
}
Loading…
Cancel
Save