From aeea7ee99ce4af448dcc3b462c9c7d982bd51385 Mon Sep 17 00:00:00 2001 From: xeals Date: Tue, 30 Jul 2024 13:42:38 +1000 Subject: [PATCH] day10? --- src/day10.zig | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 src/day10.zig diff --git a/src/day10.zig b/src/day10.zig new file mode 100644 index 0000000..1f8804c --- /dev/null +++ b/src/day10.zig @@ -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); +}