diff options
| author | Orfeas <38209077+0xfea5@users.noreply.github.com> | 2023-12-18 19:29:23 +0200 |
|---|---|---|
| committer | Orfeas <38209077+0xfea5@users.noreply.github.com> | 2025-10-28 23:20:45 +0200 |
| commit | f3ae9a6c76a1f2963d2cb7f3fc76f6a18112999d (patch) | |
| tree | bc25dce8488add1130d42d50587a19e3bfaa7bb3 | |
| parent | day16 (diff) | |
| download | aoc23-f3ae9a6c76a1f2963d2cb7f3fc76f6a18112999d.tar.gz aoc23-f3ae9a6c76a1f2963d2cb7f3fc76f6a18112999d.zip | |
day17
| -rw-r--r-- | day17/example1.txt | 13 | ||||
| -rw-r--r-- | day17/example2.txt | 5 | ||||
| -rw-r--r-- | day17/solution.zig | 108 |
3 files changed, 126 insertions, 0 deletions
diff --git a/day17/example1.txt b/day17/example1.txt new file mode 100644 index 0000000..f400d6e --- /dev/null +++ b/day17/example1.txt | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | 2413432311323 | ||
| 2 | 3215453535623 | ||
| 3 | 3255245654254 | ||
| 4 | 3446585845452 | ||
| 5 | 4546657867536 | ||
| 6 | 1438598798454 | ||
| 7 | 4457876987766 | ||
| 8 | 3637877979653 | ||
| 9 | 4654967986887 | ||
| 10 | 4564679986453 | ||
| 11 | 1224686865563 | ||
| 12 | 2546548887735 | ||
| 13 | 4322674655533 | ||
diff --git a/day17/example2.txt b/day17/example2.txt new file mode 100644 index 0000000..e456899 --- /dev/null +++ b/day17/example2.txt | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | 111111111111 | ||
| 2 | 999999999991 | ||
| 3 | 999999999991 | ||
| 4 | 999999999991 | ||
| 5 | 999999999991 | ||
diff --git a/day17/solution.zig b/day17/solution.zig new file mode 100644 index 0000000..00591ff --- /dev/null +++ b/day17/solution.zig | |||
| @@ -0,0 +1,108 @@ | |||
| 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 | const math = std.math; | ||
| 8 | |||
| 9 | const fin = mem.trim(u8, @embedFile("./input.txt"), &std.ascii.whitespace); | ||
| 10 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; | ||
| 11 | const allocator = gpa.allocator(); | ||
| 12 | |||
| 13 | const move = [_][2]i64{ | ||
| 14 | [_]i64{ -1, 0 }, | ||
| 15 | [_]i64{ 0, 1 }, | ||
| 16 | [_]i64{ 1, 0 }, | ||
| 17 | [_]i64{ 0, -1 }, | ||
| 18 | }; | ||
| 19 | |||
| 20 | const Point = struct { | ||
| 21 | i: usize, | ||
| 22 | j: usize, | ||
| 23 | best: [4]u64, | ||
| 24 | |||
| 25 | pub fn Cmp(_: void, lhs: Point, rhs: Point) math.Order { | ||
| 26 | return std.math.order(mem.min(u64, &lhs.best), mem.min(u64, &rhs.best)); | ||
| 27 | } | ||
| 28 | }; | ||
| 29 | |||
| 30 | const inf: u64 = math.maxInt(u32); | ||
| 31 | const MAXSIZE = 200; | ||
| 32 | |||
| 33 | fn evaluate(grid: []const []const u8, comptime min_dist: u64, comptime max_dist: u64) !u64 { | ||
| 34 | var dp = [_][MAXSIZE][4]u64{[_][4]u64{[_]u64{inf} ** 4} ** MAXSIZE} ** MAXSIZE; | ||
| 35 | const w = grid[0].len; | ||
| 36 | const h = grid.len; | ||
| 37 | var pq = std.PriorityQueue(Point, void, Point.Cmp).init(allocator, {}); | ||
| 38 | |||
| 39 | dp[0][0] = [_]u64{0} ** 4; | ||
| 40 | |||
| 41 | try pq.add(Point{ | ||
| 42 | .i = 0, | ||
| 43 | .j = 0, | ||
| 44 | .best = dp[0][0], | ||
| 45 | }); | ||
| 46 | |||
| 47 | while (pq.removeOrNull()) |curr| { | ||
| 48 | for (move, 0..) |m, dirTo| { | ||
| 49 | const dirFrom = dirTo ^ 0b10; | ||
| 50 | const dpbest = res: { | ||
| 51 | var best: u64 = inf; | ||
| 52 | |||
| 53 | for (0..4) |dir| { | ||
| 54 | if (dir != dirFrom and dir != dirTo) { | ||
| 55 | best = @min(best, dp[curr.i][curr.j][dir]); | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | break :res best; | ||
| 60 | }; | ||
| 61 | |||
| 62 | var s: u64 = 0; | ||
| 63 | for (1..max_dist + 1) |dist| { | ||
| 64 | const ni: u64 = @bitCast(@as(i64, @bitCast(curr.i)) + m[0] * @as(i64, @bitCast(dist))); | ||
| 65 | const nj: u64 = @bitCast(@as(i64, @bitCast(curr.j)) + m[1] * @as(i64, @bitCast(dist))); | ||
| 66 | |||
| 67 | if (ni >= h or nj >= w) { | ||
| 68 | break; | ||
| 69 | } | ||
| 70 | |||
| 71 | s += grid[ni][nj] - '0'; | ||
| 72 | |||
| 73 | if (dist < min_dist) { | ||
| 74 | continue; | ||
| 75 | } | ||
| 76 | |||
| 77 | if (dp[ni][nj][dirFrom] > dpbest + s) { | ||
| 78 | dp[ni][nj][dirFrom] = dpbest + s; | ||
| 79 | try pq.add(Point{ | ||
| 80 | .i = ni, | ||
| 81 | .j = nj, | ||
| 82 | .best = dp[ni][nj], | ||
| 83 | }); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | } | ||
| 87 | } | ||
| 88 | return mem.min(u64, &dp[h - 1][w - 1]); | ||
| 89 | } | ||
| 90 | |||
| 91 | pub fn solve(grid: []const []const u8) !void { | ||
| 92 | const part1 = try evaluate(grid, 1, 3); | ||
| 93 | print("{d}\n", .{part1}); | ||
| 94 | |||
| 95 | const part2 = try evaluate(grid, 4, 10); | ||
| 96 | print("{d}\n", .{part2}); | ||
| 97 | } | ||
| 98 | |||
| 99 | pub fn main() !void { | ||
| 100 | var splitLines = mem.splitScalar(u8, fin, '\n'); | ||
| 101 | var grid = ArrayList([]const u8).init(allocator); | ||
| 102 | |||
| 103 | while (splitLines.next()) |line| { | ||
| 104 | try grid.append(line); | ||
| 105 | } | ||
| 106 | |||
| 107 | try solve(grid.items); | ||
| 108 | } | ||
