aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOrfeas <38209077+0xfea5@users.noreply.github.com>2023-12-14 08:15:50 +0200
committerOrfeas <38209077+0xfea5@users.noreply.github.com>2025-10-28 23:20:45 +0200
commit6bf274c5fd2a69cb161e577e5fc1ee612e01215e (patch)
treeff6bc48ede26c3fb46a7bd7668e458fbf238e212
parentday12 (diff)
downloadaoc23-6bf274c5fd2a69cb161e577e5fc1ee612e01215e.tar.gz
aoc23-6bf274c5fd2a69cb161e577e5fc1ee612e01215e.zip
day13
-rw-r--r--day13/example.txt15
-rw-r--r--day13/solution.zig113
2 files changed, 128 insertions, 0 deletions
diff --git a/day13/example.txt b/day13/example.txt
new file mode 100644
index 0000000..3b6b5cc
--- /dev/null
+++ b/day13/example.txt
@@ -0,0 +1,15 @@
1#.##..##.
2..#.##.#.
3##......#
4##......#
5..#.##.#.
6..##..##.
7#.#.##.#.
8
9#...##..#
10#....#..#
11..##..###
12#####.##.
13#####.##.
14..##..###
15#....#..#
diff --git a/day13/solution.zig b/day13/solution.zig
new file mode 100644
index 0000000..e3139fc
--- /dev/null
+++ b/day13/solution.zig
@@ -0,0 +1,113 @@
1const std = @import("std");
2const print = std.debug.print;
3const assert = std.debug.assert;
4const ArrayList = std.ArrayList;
5const HashMap = std.HashMap;
6const mem = std.mem;
7
8const fin = mem.trim(u8, @embedFile("./input.txt"), &std.ascii.whitespace);
9var gpa = std.heap.GeneralPurposeAllocator(.{}){};
10const allocator = gpa.allocator();
11
12const Map = []const []const u8;
13
14fn cnt_diff(lhs: []const u8, rhs: []const u8) i64 {
15 var cnt: i64 = 0;
16
17 for (lhs, rhs) |l, b| {
18 if (l != b) {
19 cnt += 1;
20 }
21 }
22
23 return cnt;
24}
25
26fn check_eql(map: Map, i_: usize, j_: usize, tolerance_: i64) bool {
27 var i = i_;
28 var j = j_;
29 var tolerance = tolerance_;
30
31 while (i >= 0 and j < map.len) : ({
32 i = if (i > 0) i - 1 else break;
33 j += 1;
34 }) {
35 tolerance -= cnt_diff(map[i], map[j]);
36 if (tolerance < 0) {
37 return false;
38 }
39 }
40
41 return tolerance == 0;
42}
43
44fn transpose(map: Map) Map {
45 var transposed = allocator.alloc([]u8, map[0].len) catch unreachable;
46
47 for (transposed) |*trow| {
48 trow.* = allocator.alloc(u8, map.len) catch unreachable;
49 }
50
51 for (map, 0..) |row, i| {
52 for (row, 0..) |c, j| {
53 transposed[j][i] = c;
54 }
55 }
56
57 return transposed;
58}
59
60fn evaluate(map: Map, tolerance: i64) u64 {
61 const h = map.len;
62 const w = map[0].len;
63
64 // per row
65 for (0..h - 1, 1..) |i, j| {
66 if (check_eql(map, i, j, tolerance)) {
67 return 100 * j;
68 }
69 }
70
71 // per column
72 const transposed = transpose(map);
73 for (0..w - 1, 1..) |i, j| {
74 if (check_eql(transposed, i, j, tolerance)) {
75 return j;
76 }
77 }
78
79 unreachable;
80}
81
82pub fn solve(maps: []const Map) void {
83 var part1: u64 = 0;
84
85 for (maps) |map| {
86 part1 += evaluate(map, 0);
87 }
88 print("{d}\n", .{part1});
89
90 var part2: u64 = 0;
91
92 for (maps) |map| {
93 part2 += evaluate(map, 1);
94 }
95
96 print("{d}\n", .{part2});
97}
98
99pub fn main() !void {
100 var splitMirros = mem.splitSequence(u8, fin, "\n\n");
101 var maps = ArrayList([]const []const u8).init(allocator);
102
103 while (splitMirros.next()) |mirror| {
104 var splitLines = mem.splitScalar(u8, mirror, '\n');
105
106 var map = ArrayList([]const u8).init(allocator);
107 while (splitLines.next()) |line| {
108 try map.append(line);
109 }
110 try maps.append(map.items);
111 }
112 solve(maps.items);
113}