parent
84be840255
commit
a1dbe7a8d0
@ -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…
Reference in new issue