diff options
| author | Orfeas <38209077+0xfea5@users.noreply.github.com> | 2023-12-11 22:16:01 +0200 |
|---|---|---|
| committer | Orfeas <38209077+0xfea5@users.noreply.github.com> | 2025-10-28 23:20:45 +0200 |
| commit | cd5600dfec9d59a8054cab53ff31c25be789ce9c (patch) | |
| tree | 4d03e479792023e67a06cc6a7580e15a2eb744b2 | |
| parent | day9 (diff) | |
| download | aoc23-cd5600dfec9d59a8054cab53ff31c25be789ce9c.tar.gz aoc23-cd5600dfec9d59a8054cab53ff31c25be789ce9c.zip | |
day10
| -rw-r--r-- | day10/example1.txt | 5 | ||||
| -rw-r--r-- | day10/example2.txt | 9 | ||||
| -rw-r--r-- | day10/example3.txt | 10 | ||||
| -rw-r--r-- | day10/example4.txt | 10 | ||||
| -rw-r--r-- | day10/solution.zig | 133 | ||||
| -rw-r--r-- | day11/solution.zig | 23 |
6 files changed, 190 insertions, 0 deletions
diff --git a/day10/example1.txt b/day10/example1.txt new file mode 100644 index 0000000..682499d --- /dev/null +++ b/day10/example1.txt | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | ..F7. | ||
| 2 | .FJ|. | ||
| 3 | SJ.L7 | ||
| 4 | |F--J | ||
| 5 | LJ... | ||
diff --git a/day10/example2.txt b/day10/example2.txt new file mode 100644 index 0000000..bd9cdf5 --- /dev/null +++ b/day10/example2.txt | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | ........... | ||
| 2 | .S-------7. | ||
| 3 | .|F-----7|. | ||
| 4 | .||.....||. | ||
| 5 | .||.....||. | ||
| 6 | .|L-7.F-J|. | ||
| 7 | .|..|.|..|. | ||
| 8 | .L--J.L--J. | ||
| 9 | ........... | ||
diff --git a/day10/example3.txt b/day10/example3.txt new file mode 100644 index 0000000..adaae96 --- /dev/null +++ b/day10/example3.txt | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | .F----7F7F7F7F-7.... | ||
| 2 | .|F--7||||||||FJ.... | ||
| 3 | .||.FJ||||||||L7.... | ||
| 4 | FJL7L7LJLJ||LJ.L-7.. | ||
| 5 | L--J.L7...LJS7F-7L7. | ||
| 6 | ....F-J..F7FJ|L7L7L7 | ||
| 7 | ....L7.F7||L7|.L7L7| | ||
| 8 | .....|FJLJ|FJ|F7|.LJ | ||
| 9 | ....FJL-7.||.||||... | ||
| 10 | ....L---J.LJ.LJLJ... | ||
diff --git a/day10/example4.txt b/day10/example4.txt new file mode 100644 index 0000000..8f950ae --- /dev/null +++ b/day10/example4.txt | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | FF7FSF7F7F7F7F7F---7 | ||
| 2 | L|LJ||||||||||||F--J | ||
| 3 | FL-7LJLJ||||||LJL-77 | ||
| 4 | F--JF--7||LJLJ7F7FJ- | ||
| 5 | L---JF-JLJ.||-FJLJJ7 | ||
| 6 | |F|F-JF---7F7-L7L|7| | ||
| 7 | |FFJF7L7F-JF7|JL---7 | ||
| 8 | 7-L-JL7||F7|L7F-7F7| | ||
| 9 | L.L7LFJ|||||FJL7||LJ | ||
| 10 | L7JLJL-JLJLJL--JLJ.L | ||
diff --git a/day10/solution.zig b/day10/solution.zig new file mode 100644 index 0000000..8028c94 --- /dev/null +++ b/day10/solution.zig | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | const std = @import("std"); | ||
| 2 | const print = std.debug.print; | ||
| 3 | const assert = std.debug.assert; | ||
| 4 | const ArrayList = std.ArrayList; | ||
| 5 | const HashMap = std.HashMap; | ||
| 6 | const mem = std.mem; | ||
| 7 | |||
| 8 | const fin = mem.trim(u8, @embedFile("./input.txt"), &std.ascii.whitespace); | ||
| 9 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; | ||
| 10 | const allocator = gpa.allocator(); | ||
| 11 | |||
| 12 | const Pair = struct { | ||
| 13 | row: isize, | ||
| 14 | col: isize, | ||
| 15 | |||
| 16 | pub fn eql(lhs: @This(), rhs: @This()) bool { | ||
| 17 | return lhs.col == rhs.col and lhs.row == rhs.row; | ||
| 18 | } | ||
| 19 | }; | ||
| 20 | |||
| 21 | const Direction = enum(u4) { | ||
| 22 | N = 0, | ||
| 23 | U = 1 << 0, | ||
| 24 | R = 1 << 1, | ||
| 25 | D = 1 << 2, | ||
| 26 | L = 1 << 3, | ||
| 27 | }; | ||
| 28 | |||
| 29 | const c2dir = blk: { | ||
| 30 | var res: [256]u4 = undefined; | ||
| 31 | res['S'] = | ||
| 32 | @intFromEnum(Direction.U) | @intFromEnum(Direction.R) | | ||
| 33 | @intFromEnum(Direction.D) | @intFromEnum(Direction.L); | ||
| 34 | res['|'] = @intFromEnum(Direction.U) | @intFromEnum(Direction.D); | ||
| 35 | res['J'] = @intFromEnum(Direction.U) | @intFromEnum(Direction.L); | ||
| 36 | res['L'] = @intFromEnum(Direction.U) | @intFromEnum(Direction.R); | ||
| 37 | res['7'] = @intFromEnum(Direction.D) | @intFromEnum(Direction.L); | ||
| 38 | res['F'] = @intFromEnum(Direction.D) | @intFromEnum(Direction.R); | ||
| 39 | res['-'] = @intFromEnum(Direction.L) | @intFromEnum(Direction.R); | ||
| 40 | res['.'] = @intFromEnum(Direction.N); | ||
| 41 | break :blk res; | ||
| 42 | }; | ||
| 43 | |||
| 44 | const dir2off = blk: { | ||
| 45 | var res: [256][2]i64 = undefined; | ||
| 46 | res[@intFromEnum(Direction.U)] = .{ -1, 0 }; | ||
| 47 | res[@intFromEnum(Direction.R)] = .{ 0, 1 }; | ||
| 48 | res[@intFromEnum(Direction.D)] = .{ 1, 0 }; | ||
| 49 | res[@intFromEnum(Direction.L)] = .{ 0, -1 }; | ||
| 50 | break :blk res; | ||
| 51 | }; | ||
| 52 | |||
| 53 | pub fn solve(grid: []const []const u8) !void { | ||
| 54 | const height = grid.len; | ||
| 55 | const width = grid[0].len; | ||
| 56 | const start = find_start: { | ||
| 57 | for (grid, 0..) |row, i| { | ||
| 58 | if (mem.indexOfScalar(u8, row, 'S')) |j| { | ||
| 59 | break :find_start Pair{ | ||
| 60 | .row = @bitCast(i), | ||
| 61 | .col = @bitCast(j), | ||
| 62 | }; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | unreachable; | ||
| 66 | }; | ||
| 67 | |||
| 68 | var pathNodes = ArrayList(Pair).init(allocator); | ||
| 69 | defer pathNodes.deinit(); | ||
| 70 | try pathNodes.append(start); | ||
| 71 | var blocked: u4 = 0b0000; | ||
| 72 | |||
| 73 | outer: while (true) { | ||
| 74 | const curr = pathNodes.getLast(); | ||
| 75 | const cdirs = c2dir[grid[@bitCast(curr.row)][@bitCast(curr.col)]]; | ||
| 76 | |||
| 77 | for (0..4) |i| { | ||
| 78 | const d: u4 = @shlExact(@as(u4, 1), @intCast(i)); | ||
| 79 | const nrow: i64 = curr.row + dir2off[d][0]; | ||
| 80 | const ncol: i64 = curr.col + dir2off[d][1]; | ||
| 81 | |||
| 82 | if (nrow < 0 or nrow >= height or ncol < 0 or ncol >= width) { | ||
| 83 | continue; | ||
| 84 | } | ||
| 85 | |||
| 86 | const next = Pair{ | ||
| 87 | .row = nrow, | ||
| 88 | .col = ncol, | ||
| 89 | }; | ||
| 90 | const ndirs = std.math.rotl(u4, c2dir[grid[@bitCast(next.row)][@bitCast(next.col)]], @as(u2, 2)); | ||
| 91 | |||
| 92 | if (d & cdirs & ndirs & ~blocked != 0) { | ||
| 93 | // Wrapped back to the beginning | ||
| 94 | if (next.eql(start)) { | ||
| 95 | break :outer; | ||
| 96 | } | ||
| 97 | blocked = std.math.rotl(u4, d, @as(u2, 2)); | ||
| 98 | try pathNodes.append(next); | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | } else { | ||
| 102 | unreachable; | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | const pathLen = pathNodes.items.len; | ||
| 107 | const part1 = pathLen / 2; | ||
| 108 | print("{d}\n", .{part1}); | ||
| 109 | |||
| 110 | // Use shoelace formula to calculate the area of the polygon | ||
| 111 | // https://en.wikipedia.org/wiki/Shoelace_formula#Shoelace_formula | ||
| 112 | var a2: isize = 0; | ||
| 113 | for (pathNodes.items, 1..) |f, j| { | ||
| 114 | const s = pathNodes.items[j % pathLen]; | ||
| 115 | a2 += f.row * s.col - f.col * s.row; | ||
| 116 | } | ||
| 117 | const a: isize = @divTrunc(if (a2 > 0) a2 else -a2, 2); | ||
| 118 | // Use Pick's formula to find the number of internal points | ||
| 119 | // https://en.wikipedia.org/wiki/Pick's_theorem#Formula | ||
| 120 | const part2 = a - @as(isize, @bitCast(part1)) + 1; | ||
| 121 | |||
| 122 | print("{d}\n", .{part2}); | ||
| 123 | } | ||
| 124 | |||
| 125 | pub fn main() !void { | ||
| 126 | var splitLines = mem.splitScalar(u8, fin, '\n'); | ||
| 127 | var grid = ArrayList([]const u8).init(allocator); | ||
| 128 | |||
| 129 | while (splitLines.next()) |line| { | ||
| 130 | try grid.append(line); | ||
| 131 | } | ||
| 132 | try solve(grid.items); | ||
| 133 | } | ||
diff --git a/day11/solution.zig b/day11/solution.zig new file mode 100644 index 0000000..059a120 --- /dev/null +++ b/day11/solution.zig | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | const std = @import("std"); | ||
| 2 | const print = std.debug.print; | ||
| 3 | const assert = std.debug.assert; | ||
| 4 | const ArrayList = std.ArrayList; | ||
| 5 | const HashMap = std.HashMap; | ||
| 6 | const mem = std.mem; | ||
| 7 | |||
| 8 | const fin = mem.trim(u8, @embedFile("./input.txt"), &std.ascii.whitespace); | ||
| 9 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; | ||
| 10 | const allocator = gpa.allocator(); | ||
| 11 | |||
| 12 | pub fn part1() void { | ||
| 13 | // Part 1 goes here | ||
| 14 | } | ||
| 15 | |||
| 16 | pub fn part2() void { | ||
| 17 | // Part 2 goes here | ||
| 18 | } | ||
| 19 | |||
| 20 | pub fn main() !void { | ||
| 21 | part1(); | ||
| 22 | part2(); | ||
| 23 | } | ||
