This commit is contained in:
parent
6065242de9
commit
aeea7ee99c
170
src/day10.zig
Normal file
170
src/day10.zig
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const util = @import("util.zig");
|
||||||
|
const mem = std.mem;
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
const input = @embedFile("data/day10.txt");
|
||||||
|
const sln = try solve(util.gpa, input);
|
||||||
|
try printPipes(std.io.getStdOut(), 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(u2) {
|
||||||
|
up,
|
||||||
|
down,
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn Walker(comptime T: type) type {
|
||||||
|
return struct {
|
||||||
|
r: T,
|
||||||
|
c: T,
|
||||||
|
facing: Direction,
|
||||||
|
|
||||||
|
fn init(r: T, c: T) @This() {
|
||||||
|
return .{ .r = r, .c = c, .facing = .up };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn walk(self: *@This(), grid: [][]u8) void {
|
||||||
|
self.walkSpace(grid[self.r][self.c]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn walkSpace(self: *@This(), char: u8) void {
|
||||||
|
switch (char) {
|
||||||
|
'S' => {},
|
||||||
|
'|' => assert(self.facing == .up or self.facing == .down),
|
||||||
|
'-' => assert(self.facing == .left or self.facing == .right),
|
||||||
|
'L' => switch (self.facing) {
|
||||||
|
.down => self.turn(.right),
|
||||||
|
.left => self.turn(.up),
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
'J' => switch (self.facing) {
|
||||||
|
.down => self.turn(.left),
|
||||||
|
.right => self.turn(.up),
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
'7' => switch (self.facing) {
|
||||||
|
.up => self.turn(.left),
|
||||||
|
.right => self.turn(.down),
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
'F' => switch (self.facing) {
|
||||||
|
.up => self.turn(.right),
|
||||||
|
.left => self.turn(.down),
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
self.fwd();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move(self: *@This(), row: i32, col: i32) void {
|
||||||
|
self.*.r += row;
|
||||||
|
self.*.c += col;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fwd(self: *@This()) void {
|
||||||
|
switch (self.facing) {
|
||||||
|
.up => self.move(-1, 0),
|
||||||
|
.down => self.move(1, 0),
|
||||||
|
.left => self.move(0, -1),
|
||||||
|
.right => self.move(0, 1),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn turn(self: *@This(), dir: Direction) void {
|
||||||
|
self.*.facing = dir;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn solve(alloc: mem.Allocator, input: []const u8) !Solution {
|
||||||
|
_ = alloc;
|
||||||
|
var grid: [][]u8 = undefined; // try alloc.alloc(u8, mem.count(u8, input, &[_]u8{'\n'}));
|
||||||
|
|
||||||
|
var s_found = false;
|
||||||
|
var sr: u32 = 0;
|
||||||
|
var sc: u32 = 0;
|
||||||
|
|
||||||
|
var it = util.splitLines(input);
|
||||||
|
var curr_row: u32 = 0;
|
||||||
|
while (it.next()) |line| {
|
||||||
|
if (line.len == 0) continue;
|
||||||
|
// grid[curr_row] = line;
|
||||||
|
|
||||||
|
if (!s_found) {
|
||||||
|
if (mem.indexOfScalar(u8, line, 'S')) |col| {
|
||||||
|
_ = col;
|
||||||
|
sr = curr_row;
|
||||||
|
// sc = col;
|
||||||
|
s_found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find actual starting position.
|
||||||
|
var walker = Walker(u32).init(sr, sc);
|
||||||
|
if (mem.indexOfScalar(u8, "|7F", grid[sr - 1][sc])) |_| {
|
||||||
|
walker.facing = .up;
|
||||||
|
} else if (mem.indexOfScalar(u8, "|JL", grid[sr + 1][sc])) |_| {
|
||||||
|
walker.facing = .down;
|
||||||
|
} else if (mem.indexOfScalar(u8, "-LF", grid[sr][sc - 1])) |_| {
|
||||||
|
walker.facing = .left;
|
||||||
|
} else if (mem.indexOfScalar(u8, "-J7", grid[sr][sc + 1])) |_| {
|
||||||
|
walker.facing = .right;
|
||||||
|
}
|
||||||
|
|
||||||
|
var steps: u32 = 1;
|
||||||
|
while (true) {
|
||||||
|
steps += 1;
|
||||||
|
if (grid[walker.r][walker.c] == 'S') break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{ .a = steps / 2, .b = 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn printPipes(writer: anytype, input: []const u8) !void {
|
||||||
|
for (input) |char| {
|
||||||
|
_ = switch (char) {
|
||||||
|
'|' => try writer.write("│"),
|
||||||
|
'-' => try writer.write("─"),
|
||||||
|
'L' => try writer.write("└"),
|
||||||
|
'J' => try writer.write("┘"),
|
||||||
|
'7' => try writer.write("┐"),
|
||||||
|
'F' => try writer.write("┌"),
|
||||||
|
'.' => try writer.write(" "),
|
||||||
|
'S' => try writer.write("o"),
|
||||||
|
'\n' => try writer.write("\n"),
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "silver" {
|
||||||
|
const input =
|
||||||
|
\\-L|F7
|
||||||
|
\\7S-7|
|
||||||
|
\\L|7||
|
||||||
|
\\-L-J|
|
||||||
|
\\L|-JF
|
||||||
|
;
|
||||||
|
const sln = try solve(std.testing.allocator, input);
|
||||||
|
try std.testing.expectEqual(@as(usize, 6), sln.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "gold" {
|
||||||
|
const input =
|
||||||
|
\\
|
||||||
|
;
|
||||||
|
const sln = try solve(std.testing.allocator, input);
|
||||||
|
try std.testing.expectEqual(@as(usize, 0), sln.b);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user