diff options
| author | Orfeas <38209077+0xfea5@users.noreply.github.com> | 2023-12-19 04:21:10 +0200 |
|---|---|---|
| committer | Orfeas <38209077+0xfea5@users.noreply.github.com> | 2025-10-28 23:20:45 +0200 |
| commit | 6c8982230b9402cc2e705a70e5dcc61b0b9187ea (patch) | |
| tree | 44a756cfe90bcf10cfa2c07bd2c7b69900da7122 | |
| parent | day17 (diff) | |
| download | aoc23-6c8982230b9402cc2e705a70e5dcc61b0b9187ea.tar.gz aoc23-6c8982230b9402cc2e705a70e5dcc61b0b9187ea.zip | |
day18
| -rw-r--r-- | day18/example.txt | 14 | ||||
| -rw-r--r-- | day18/solution.zig | 123 |
2 files changed, 137 insertions, 0 deletions
diff --git a/day18/example.txt b/day18/example.txt new file mode 100644 index 0000000..fc7612e --- /dev/null +++ b/day18/example.txt | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | R 6 (#70c710) | ||
| 2 | D 5 (#0dc571) | ||
| 3 | L 2 (#5713f0) | ||
| 4 | D 2 (#d2c081) | ||
| 5 | R 2 (#59c680) | ||
| 6 | D 2 (#411b91) | ||
| 7 | L 5 (#8ceee2) | ||
| 8 | U 2 (#caa173) | ||
| 9 | L 1 (#1b58a2) | ||
| 10 | U 2 (#caa171) | ||
| 11 | R 2 (#7807d2) | ||
| 12 | U 3 (#a77fa3) | ||
| 13 | L 2 (#015232) | ||
| 14 | U 2 (#7a21e3) | ||
diff --git a/day18/solution.zig b/day18/solution.zig new file mode 100644 index 0000000..11da2a1 --- /dev/null +++ b/day18/solution.zig | |||
| @@ -0,0 +1,123 @@ | |||
| 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("./example.txt"), &std.ascii.whitespace); | ||
| 9 | var gpa = std.heap.GeneralPurposeAllocator(.{}){}; | ||
| 10 | const allocator = gpa.allocator(); | ||
| 11 | |||
| 12 | const Direction = [_][2]u64{ | ||
| 13 | [_]i64{ -1, 0 }, | ||
| 14 | [_]i64{ 0, 1 }, | ||
| 15 | [_]i64{ 1, 0 }, | ||
| 16 | [_]i64{ 0, -1 }, | ||
| 17 | }; | ||
| 18 | |||
| 19 | const Move = struct { | ||
| 20 | dir: usize, | ||
| 21 | dist: isize, | ||
| 22 | color: []const u8, | ||
| 23 | }; | ||
| 24 | |||
| 25 | fn abs(a: i64, b: i64) u64 { | ||
| 26 | return @as(u64, @bitCast(@max(a, b) - @min(a, b))); | ||
| 27 | } | ||
| 28 | |||
| 29 | fn evaluate(moves: []const Move) !u64 { | ||
| 30 | var polygon = ArrayList([2]i64).init(allocator); | ||
| 31 | defer polygon.deinit(); | ||
| 32 | |||
| 33 | var curr = [_]i64{ 0, 0 }; | ||
| 34 | var bl: u64 = 0; | ||
| 35 | |||
| 36 | for (moves) |m| { | ||
| 37 | const next = switch (m.dir) { | ||
| 38 | 'U' => .{ | ||
| 39 | curr[0] - m.dist, | ||
| 40 | curr[1], | ||
| 41 | }, | ||
| 42 | 'R' => .{ | ||
| 43 | curr[0], | ||
| 44 | curr[1] + m.dist, | ||
| 45 | }, | ||
| 46 | 'D' => .{ | ||
| 47 | curr[0] + m.dist, | ||
| 48 | curr[1], | ||
| 49 | }, | ||
| 50 | 'L' => .{ | ||
| 51 | curr[0], | ||
| 52 | curr[1] - m.dist, | ||
| 53 | }, | ||
| 54 | else => unreachable, | ||
| 55 | }; | ||
| 56 | |||
| 57 | bl += abs(curr[0], next[0]) + abs(curr[1], next[1]); | ||
| 58 | try polygon.append(next); | ||
| 59 | curr = next; | ||
| 60 | } | ||
| 61 | |||
| 62 | const points = polygon.items; | ||
| 63 | const nPoints = points.len; | ||
| 64 | var a2: i64 = 0; | ||
| 65 | |||
| 66 | for (points, 1..) |f, j| { | ||
| 67 | const s = points[j % nPoints]; | ||
| 68 | |||
| 69 | a2 += f[0] * s[1] - f[1] * s[0]; | ||
| 70 | } | ||
| 71 | |||
| 72 | const a: usize = @bitCast(@divTrunc(if (a2 > 0) a2 else -a2, 2)); | ||
| 73 | |||
| 74 | return a + 1 + bl / 2; | ||
| 75 | } | ||
| 76 | |||
| 77 | pub fn solve(moves: []const Move) !void { | ||
| 78 | const part1 = try evaluate(moves); | ||
| 79 | |||
| 80 | print("{d}\n", .{part1}); | ||
| 81 | |||
| 82 | var movespt2 = ArrayList(Move).init(allocator); | ||
| 83 | defer movespt2.deinit(); | ||
| 84 | |||
| 85 | for (moves) |m| { | ||
| 86 | const dist = try std.fmt.parseInt(i64, m.color[0..5], 16); | ||
| 87 | const dir: u8 = switch (m.color[5]) { | ||
| 88 | '0' => 'R', | ||
| 89 | '1' => 'D', | ||
| 90 | '2' => 'L', | ||
| 91 | '3' => 'U', | ||
| 92 | else => unreachable, | ||
| 93 | }; | ||
| 94 | try movespt2.append(Move{ | ||
| 95 | .dist = dist, | ||
| 96 | .dir = dir, | ||
| 97 | .color = m.color, | ||
| 98 | }); | ||
| 99 | } | ||
| 100 | |||
| 101 | const part2 = try evaluate(movespt2.items); | ||
| 102 | |||
| 103 | print("{d}\n", .{part2}); | ||
| 104 | } | ||
| 105 | |||
| 106 | pub fn main() !void { | ||
| 107 | var splitLines = mem.splitScalar(u8, fin, '\n'); | ||
| 108 | var moves = ArrayList(Move).init(allocator); | ||
| 109 | |||
| 110 | while (splitLines.next()) |line| { | ||
| 111 | var toks = mem.tokenizeAny(u8, line, " (#)"); | ||
| 112 | const dir = toks.next().?[0]; | ||
| 113 | const dist = try std.fmt.parseInt(i64, toks.next().?, 10); | ||
| 114 | const color = toks.next().?; | ||
| 115 | |||
| 116 | try moves.append(Move{ | ||
| 117 | .dir = dir, | ||
| 118 | .dist = dist, | ||
| 119 | .color = color, | ||
| 120 | }); | ||
| 121 | } | ||
| 122 | try solve(moves.items); | ||
| 123 | } | ||
