aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOrfeas <38209077+0xfea5@users.noreply.github.com>2023-12-15 02:13:13 +0200
committerOrfeas <38209077+0xfea5@users.noreply.github.com>2025-10-28 23:20:45 +0200
commit88505114b052c220454cb6211abd8dcff2ce5323 (patch)
treea92e2b4a1b2d923ce2bacbe3c2093fb695c170fb
parentday13 (diff)
downloadaoc23-88505114b052c220454cb6211abd8dcff2ce5323.tar.gz
aoc23-88505114b052c220454cb6211abd8dcff2ce5323.zip
day14
-rw-r--r--day13/solution.zig32
-rw-r--r--day14/example.txt10
-rw-r--r--day14/solution.zig181
3 files changed, 207 insertions, 16 deletions
diff --git a/day13/solution.zig b/day13/solution.zig
index e3139fc..3b83d0e 100644
--- a/day13/solution.zig
+++ b/day13/solution.zig
@@ -23,6 +23,22 @@ fn cnt_diff(lhs: []const u8, rhs: []const u8) i64 {
23 return cnt; 23 return cnt;
24} 24}
25 25
26fn transpose(map: Map) Map {
27 var transposed = allocator.alloc([]u8, map[0].len) catch unreachable;
28
29 for (transposed) |*trow| {
30 trow.* = allocator.alloc(u8, map.len) catch unreachable;
31 }
32
33 for (map, 0..) |row, i| {
34 for (row, 0..) |c, j| {
35 transposed[j][i] = c;
36 }
37 }
38
39 return transposed;
40}
41
26fn check_eql(map: Map, i_: usize, j_: usize, tolerance_: i64) bool { 42fn check_eql(map: Map, i_: usize, j_: usize, tolerance_: i64) bool {
27 var i = i_; 43 var i = i_;
28 var j = j_; 44 var j = j_;
@@ -41,22 +57,6 @@ fn check_eql(map: Map, i_: usize, j_: usize, tolerance_: i64) bool {
41 return tolerance == 0; 57 return tolerance == 0;
42} 58}
43 59
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 { 60fn evaluate(map: Map, tolerance: i64) u64 {
61 const h = map.len; 61 const h = map.len;
62 const w = map[0].len; 62 const w = map[0].len;
diff --git a/day14/example.txt b/day14/example.txt
new file mode 100644
index 0000000..5a24dce
--- /dev/null
+++ b/day14/example.txt
@@ -0,0 +1,10 @@
1O....#....
2O.OO#....#
3.....##...
4OO.#O....O
5.O.....O#.
6O.#..O.#.#
7..O..#O..O
8.......O..
9#....###..
10#OO..#....
diff --git a/day14/solution.zig b/day14/solution.zig
new file mode 100644
index 0000000..5509bdc
--- /dev/null
+++ b/day14/solution.zig
@@ -0,0 +1,181 @@
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 []u8;
13
14fn column_wise(map: Map, begin: isize, end: isize, step: isize) u64 {
15 const h = map.len;
16 const w = map[0].len;
17 var ans: u64 = 0;
18
19 for (0..w) |j| {
20 var next_free = begin;
21 var i = begin;
22 while (i != end) : (i += step) {
23 switch (map[@bitCast(i)][j]) {
24 '.' => {},
25 'O' => {
26 ans += h - @as(u64, @bitCast(next_free));
27 map[@bitCast(i)][j] = '.';
28 map[@bitCast(next_free)][j] = 'O';
29 next_free += step;
30 },
31 '#' => {
32 next_free = i + step;
33 },
34 else => unreachable,
35 }
36 }
37 }
38
39 return ans;
40}
41
42fn row_wise(map: Map, begin: isize, end: isize, step: isize) u64 {
43 const h = map.len;
44 var ans: u64 = 0;
45
46 for (0..h) |i| {
47 var next_free = begin;
48 var j = begin;
49 while (j != end) : (j += step) {
50 switch (map[i][@bitCast(j)]) {
51 '.' => {},
52 'O' => {
53 ans += h - i;
54 map[i][@bitCast(j)] = '.';
55 map[i][@bitCast(next_free)] = 'O';
56 next_free += step;
57 },
58 '#' => {
59 next_free = j + step;
60 },
61 else => unreachable,
62 }
63 }
64 }
65
66 return ans;
67}
68
69fn north(map: Map) u64 {
70 const h = map.len;
71 return column_wise(map, 0, @bitCast(h), 1);
72}
73
74fn west(map: Map) u64 {
75 const w = map[0].len;
76 return row_wise(map, 0, @bitCast(w), 1);
77}
78
79fn south(map: Map) u64 {
80 const h = map.len;
81 return column_wise(map, @bitCast(h - 1), -1, -1);
82}
83
84fn east(map: Map) u64 {
85 const w = map[0].len;
86 return row_wise(map, @bitCast(w - 1), -1, -1);
87}
88
89fn round(map: Map) u64 {
90 _ = north(map);
91 _ = west(map);
92 _ = south(map);
93 return east(map);
94}
95
96const MapCtx = struct {
97 pub fn hash(_: @This(), map: []const []u8) u64 {
98 var h: u64 = 0;
99
100 for (map, 0..) |row, i| {
101 for (row, 0..) |c, j| {
102 if (c == 'O') {
103 h ^= @shlExact(i, 16) | (j);
104 }
105 }
106 }
107 h *= 1231231557;
108 h ^= (h >> 32);
109 return h;
110 }
111
112 pub fn eql(_: @This(), lhs: []const []u8, rhs: []const []u8) bool {
113 for (lhs, rhs) |l, r| {
114 if (!mem.eql(u8, l, r)) {
115 return false;
116 }
117 }
118
119 return true;
120 }
121};
122
123fn mapdup(map: []const []const u8) Map {
124 const h = map.len;
125 const w = map[0].len;
126 const new = allocator.alloc([]u8, h) catch unreachable;
127
128 for (new, map) |*row, srcrow| {
129 row.* = allocator.alloc(u8, w) catch unreachable;
130 @memcpy(row.*, srcrow);
131 }
132
133 return new;
134}
135
136fn part1(map: []const []const u8) void {
137 const ans = north(mapdup(map));
138
139 print("{d}\n", .{ans});
140}
141
142fn part2(map_: []const []const u8) void {
143 var ans: u64 = 0;
144 var visited = HashMap(Map, u64, MapCtx, 80).init(allocator);
145 const map = mapdup(map_);
146 const reps = 1_000_000_000;
147 var upto: u64 = 0;
148
149 for (0..reps) |p| {
150 ans = round(map);
151 if (visited.get(map)) |s| {
152 const start = s;
153 const period = p - s;
154 upto = (reps - start - 1) % period;
155 break;
156 }
157 visited.put(mapdup(map), p) catch unreachable;
158 }
159
160 for (0..upto) |_| {
161 ans = round(map);
162 }
163
164 print("{d}\n", .{ans});
165}
166
167pub fn solve(map: []const []const u8) void {
168 part1(map);
169 part2(map);
170}
171
172pub fn main() !void {
173 var splitLines = mem.splitScalar(u8, fin, '\n');
174 var map = ArrayList([]const u8).init(allocator);
175
176 while (splitLines.next()) |line| {
177 try map.append(line);
178 }
179
180 solve(map.items);
181}