parent
a684d9b238
commit
6065242de9
159
src/day16.zig
Normal file
159
src/day16.zig
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const util = @import("util.zig");
|
||||||
|
const mem = std.mem;
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
const input = @embedFile("data/day16.txt");
|
||||||
|
const sln = try solve(util.gpa, input);
|
||||||
|
std.debug.print("{d}\n", .{sln.a});
|
||||||
|
std.debug.print("{d}\n", .{sln.b});
|
||||||
|
}
|
||||||
|
|
||||||
|
const Solution = struct {
|
||||||
|
a: usize,
|
||||||
|
b: usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Direction = enum {
|
||||||
|
up,
|
||||||
|
right,
|
||||||
|
down,
|
||||||
|
left,
|
||||||
|
|
||||||
|
fn x(self: @This()) isize {
|
||||||
|
return switch (self) {
|
||||||
|
.up, .down => 0,
|
||||||
|
.left => -1,
|
||||||
|
.right => 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn y(self: @This()) isize {
|
||||||
|
return switch (self) {
|
||||||
|
.left, .right => 0,
|
||||||
|
.up => -1,
|
||||||
|
.down => 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rotate(self: @This(), nineties: usize) Direction {
|
||||||
|
return @enumFromInt((@intFromEnum(self) + nineties) % std.enums.values(@This()).len);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Point = struct {
|
||||||
|
x: isize,
|
||||||
|
y: isize,
|
||||||
|
dir: Direction,
|
||||||
|
};
|
||||||
|
|
||||||
|
var states: std.AutoArrayHashMap(Point, void) = undefined;
|
||||||
|
|
||||||
|
fn run(alloc: mem.Allocator, grid: [][]u8, visited: [][]bool, init_x: isize, init_y: isize, init_dir: Direction) !void {
|
||||||
|
var x = init_x;
|
||||||
|
var y = init_y;
|
||||||
|
var dir = init_dir;
|
||||||
|
|
||||||
|
while (0 <= x and x < grid[0].len - 1 and 0 <= y and y < grid.len - 1) {
|
||||||
|
visited[@intCast(y)][@intCast(x)] = true;
|
||||||
|
var looped = try states.getOrPut(.{ .x = x, .y = y, .dir = dir });
|
||||||
|
if (looped.found_existing) break;
|
||||||
|
// std.debug.print("-----\n", .{});
|
||||||
|
// std.debug.print("{} {} {}\n", .{ x, y, dir });
|
||||||
|
// std.time.sleep(1_000_000_000);
|
||||||
|
switch (grid[@intCast(y)][@intCast(x)]) {
|
||||||
|
'.' => {
|
||||||
|
x += dir.x();
|
||||||
|
y += dir.y();
|
||||||
|
},
|
||||||
|
'|' => {
|
||||||
|
switch (dir) {
|
||||||
|
.up, .down => y += dir.y(),
|
||||||
|
.left, .right => {
|
||||||
|
try run(alloc, grid, visited, x, y - 1, .up);
|
||||||
|
try run(alloc, grid, visited, x, y + 1, .down);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'-' => {
|
||||||
|
switch (dir) {
|
||||||
|
.left, .right => x += dir.x(),
|
||||||
|
.up, .down => {
|
||||||
|
try run(alloc, grid, visited, x - 1, y, .left);
|
||||||
|
try run(alloc, grid, visited, x + 1, y, .right);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'/' => {
|
||||||
|
switch (dir) {
|
||||||
|
.left, .right => dir = dir.rotate(3),
|
||||||
|
.up, .down => dir = dir.rotate(1),
|
||||||
|
}
|
||||||
|
x += dir.x();
|
||||||
|
y += dir.y();
|
||||||
|
},
|
||||||
|
'\\' => {
|
||||||
|
switch (dir) {
|
||||||
|
.left, .right => dir = dir.rotate(1),
|
||||||
|
.up, .down => dir = dir.rotate(3),
|
||||||
|
}
|
||||||
|
x += dir.x();
|
||||||
|
y += dir.y();
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn solve(alloc: mem.Allocator, comptime input: []const u8) !Solution {
|
||||||
|
const trimmed = mem.trimRight(u8, input, "\n\r");
|
||||||
|
const w = mem.indexOfScalar(u8, trimmed, '\n') orelse unreachable;
|
||||||
|
const h = mem.count(u8, trimmed, "\n");
|
||||||
|
|
||||||
|
var visited = try util.allocGrid(bool, alloc, w, h, false);
|
||||||
|
const grid = try util.toGridOwned(alloc, trimmed, '\n');
|
||||||
|
|
||||||
|
states = std.AutoArrayHashMap(Point, void).init(alloc);
|
||||||
|
defer states.deinit();
|
||||||
|
try run(alloc, grid, visited, 0, 0, .right);
|
||||||
|
|
||||||
|
var energized: usize = 0;
|
||||||
|
for (visited) |row| {
|
||||||
|
for (row) |cell| {
|
||||||
|
if (cell) energized += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (grid) |row| {
|
||||||
|
alloc.free(row);
|
||||||
|
}
|
||||||
|
for (visited) |row| {
|
||||||
|
alloc.free(row);
|
||||||
|
}
|
||||||
|
alloc.free(grid);
|
||||||
|
alloc.free(visited);
|
||||||
|
return .{ .a = energized, .b = 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
const sample =
|
||||||
|
\\.|...\....
|
||||||
|
\\|.-.\.....
|
||||||
|
\\.....|-...
|
||||||
|
\\........|.
|
||||||
|
\\..........
|
||||||
|
\\.........\
|
||||||
|
\\..../.\\..
|
||||||
|
\\.-.-/..|..
|
||||||
|
\\.|....-|.\
|
||||||
|
\\..//.|....
|
||||||
|
;
|
||||||
|
|
||||||
|
test "silver" {
|
||||||
|
const sln = try solve(std.testing.allocator, sample);
|
||||||
|
try std.testing.expectEqual(@as(usize, 46), sln.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "gold" {
|
||||||
|
// const sln = try solve(std.testing.allocator, input);
|
||||||
|
// try std.testing.expectEqual(@as(usize, 0), sln.b);
|
||||||
|
}
|
28
src/util.zig
28
src/util.zig
@ -35,3 +35,31 @@ pub fn splitLines(buffer: []const u8) mem.SplitIterator(u8, .scalar) {
|
|||||||
pub fn splitSpace(buffer: []const u8) mem.SplitIterator(u8, .scalar) {
|
pub fn splitSpace(buffer: []const u8) mem.SplitIterator(u8, .scalar) {
|
||||||
return split(buffer, ' ');
|
return split(buffer, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn allocGrid(comptime T: type, alloc: mem.Allocator, w: usize, h: usize, init: T) ![][]T {
|
||||||
|
var grid = try alloc.alloc([]T, h);
|
||||||
|
for (0..h) |i| {
|
||||||
|
grid[i] = try alloc.alloc(T, w);
|
||||||
|
@memset(grid[i], init);
|
||||||
|
}
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toGridOwned(alloc: mem.Allocator, buffer: []const u8, sep: u8) ![][]u8 {
|
||||||
|
if (buffer.len == 0) return error.Empty;
|
||||||
|
const w = mem.indexOfScalar(u8, buffer, sep) orelse unreachable;
|
||||||
|
var h = mem.count(u8, buffer, &[_]u8{sep});
|
||||||
|
if (buffer[buffer.len - 1] != sep) h += 1;
|
||||||
|
|
||||||
|
var grid = try alloc.alloc([]u8, h);
|
||||||
|
|
||||||
|
var it = split(buffer, sep);
|
||||||
|
var i: usize = 0;
|
||||||
|
while (it.next()) |line| {
|
||||||
|
grid[i] = try alloc.alloc(u8, w);
|
||||||
|
@memcpy(grid[i], line);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user