summaryrefslogtreecommitdiff
path: root/src/day04.zig
diff options
context:
space:
mode:
authorXander Bil <xander@biltopia.org>2024-12-04 23:58:20 +0100
committerXander Bil <xander@biltopia.org>2024-12-04 23:58:20 +0100
commit7b47337e40672c4c5f12a2773d3888c17237f36a (patch)
tree734e104dacaeb4708912449aac28a074f225acc5 /src/day04.zig
parent1c2490f5f2c9419ddb5035fc3a8967beef691e6c (diff)
downloadaoc2024-7b47337e40672c4c5f12a2773d3888c17237f36a.tar.xz
aoc2024-7b47337e40672c4c5f12a2773d3888c17237f36a.zip
solutions day3 and 4
Diffstat (limited to 'src/day04.zig')
-rw-r--r--src/day04.zig136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/day04.zig b/src/day04.zig
new file mode 100644
index 0000000..ba6aaf8
--- /dev/null
+++ b/src/day04.zig
@@ -0,0 +1,136 @@
+const std = @import("std");
+const mecha = @import("mecha");
+const print = std.debug.print;
+
+pub fn solve(part: []u8, buffer: []u8, allocator: std.mem.Allocator) !void {
+ if (std.mem.eql(u8, part, "1")) {
+ try part1(buffer, allocator);
+ } else {
+ try part2(buffer, allocator);
+ }
+}
+
+fn amount(line: []const u8, allocator: std.mem.Allocator) usize {
+ const match = mecha.oneOf(.{ mecha.string("XMAS"), mecha.string("SAMX") });
+
+ var rest = line;
+ var output: usize = 0;
+ while (rest.len > 0) {
+ _ = match.parse(allocator, rest) catch {
+ rest = rest[1..];
+ continue;
+ };
+ rest = rest[3..];
+ output += 1;
+ }
+ return output;
+}
+
+fn diagonal(list: []const []const u8, startr: usize, startc: usize, dirr: i32, dirc: i32, allocator: std.mem.Allocator) !usize {
+ var line = std.ArrayList(u8).init(allocator);
+ defer line.deinit();
+
+ const rows: i32 = @intCast(list.len);
+ const width: i32 = @intCast(list[0].len);
+
+ var r: i32 = @intCast(startr);
+ var c: i32 = @intCast(startc);
+ while (r >= 0 and c >= 0 and r < rows and c < width) {
+ try line.append(list[@intCast(r)][@intCast(c)]);
+
+ r += dirr;
+ c += dirc;
+ }
+ return amount(line.items, allocator);
+}
+
+fn part1(buffer: []const u8, allocator: std.mem.Allocator) !void {
+ var lines = std.mem.splitScalar(u8, buffer, '\n');
+
+ var list = std.ArrayList([]const u8).init(allocator);
+ defer list.deinit();
+
+ var sum: usize = 0;
+
+ while (lines.next()) |line| {
+ if (line.len > 0) {
+ try list.append(line);
+ sum += amount(line, allocator); // HORIZONTAL
+ }
+ }
+
+ for (0..list.items.len) |r| {
+ sum += try diagonal(list.items, r, 0, -1, 1, allocator); // UP-RIGHT
+ sum += try diagonal(list.items, r, 0, 1, 1, allocator); // DOWN-RIGHT
+ }
+
+ for (1..list.items[0].len) |c| {
+ sum += try diagonal(list.items, 0, c, 1, 1, allocator); // DOWN-RIGHT
+ sum += try diagonal(list.items, list.items.len - 1, c, -1, 1, allocator); // UP-RIGHT
+ }
+
+ for (0..list.items[0].len) |c| { // VERTICAL
+ sum += try diagonal(list.items, 0, c, 1, 0, allocator);
+ }
+
+ print("{d}\n", .{sum});
+}
+
+//------------------------------PART 2---------------------------------------
+
+fn diagonal2(list: []const []const u8, startr: usize, startc: usize, dirr: i32, dirc: i32, allocator: std.mem.Allocator, hashmap: anytype) !usize {
+ var line = std.ArrayList(u8).init(allocator);
+ defer line.deinit();
+
+ const rows: i32 = @intCast(list.len);
+ const width: i32 = @intCast(list[0].len);
+ var output: usize = 0;
+
+ var r: i32 = @intCast(startr);
+ var c: i32 = @intCast(startc);
+ while (r >= 0 and c >= 0 and r < rows and c < width) {
+ try line.append(list[@intCast(r)][@intCast(c)]);
+
+ if (line.items.len >= 3 and (std.mem.eql(u8, line.items[line.items.len - 3 ..], "MAS") or std.mem.eql(u8, line.items[line.items.len - 3 ..], "SAM"))) {
+ if (hashmap.contains((r - dirr) * rows + (c - dirc))) {
+ output += 1;
+ } else {
+ try hashmap.put((r - dirr) * rows + (c - dirc), 1);
+ }
+ }
+
+ r += dirr;
+ c += dirc;
+ }
+ return output;
+}
+
+fn part2(buffer: []const u8, allocator: std.mem.Allocator) !void {
+ var map = std.AutoHashMap(i32, usize).init(allocator);
+ defer map.deinit();
+
+ var lines = std.mem.splitScalar(u8, buffer, '\n');
+
+ var list = std.ArrayList([]const u8).init(allocator);
+ defer list.deinit();
+
+ var sum: usize = 0;
+
+ while (lines.next()) |line| {
+ if (line.len > 0) {
+ try list.append(line);
+ }
+ }
+
+ for (0..list.items.len) |r| {
+ sum += try diagonal2(list.items, r, 0, -1, 1, allocator, &map); // UP-RIGHT
+ sum += try diagonal2(list.items, r, 0, 1, 1, allocator, &map); // DOWN-RIGHT
+ }
+
+ for (1..list.items[0].len) |c| {
+ sum += try diagonal2(list.items, 0, c, 1, 1, allocator, &map); // DOWN-RIGHT
+ sum += try diagonal2(list.items, list.items.len - 1, c, -1, 1, allocator, &map); // UP-RIGHT
+ }
+
+ print("{d}\n", .{sum});
+}