diff options
author | Xander Bil <xander@biltopia.org> | 2024-12-04 23:58:20 +0100 |
---|---|---|
committer | Xander Bil <xander@biltopia.org> | 2024-12-04 23:58:20 +0100 |
commit | 7b47337e40672c4c5f12a2773d3888c17237f36a (patch) | |
tree | 734e104dacaeb4708912449aac28a074f225acc5 /src/day04.zig | |
parent | 1c2490f5f2c9419ddb5035fc3a8967beef691e6c (diff) | |
download | aoc2024-7b47337e40672c4c5f12a2773d3888c17237f36a.tar.xz aoc2024-7b47337e40672c4c5f12a2773d3888c17237f36a.zip |
solutions day3 and 4
Diffstat (limited to 'src/day04.zig')
-rw-r--r-- | src/day04.zig | 136 |
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}); +} |