summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--build.zig10
-rw-r--r--build.zig.zon11
-rw-r--r--main.zig15
-rwxr-xr-xprepare11
-rwxr-xr-xrun3
-rw-r--r--src/day01.zig6
-rw-r--r--src/day02.zig6
-rw-r--r--src/day03.zig63
-rw-r--r--src/day04.zig136
10 files changed, 249 insertions, 13 deletions
diff --git a/.gitignore b/.gitignore
index bc5bffb..ddbe2f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
zig-out/
.zig-cache
+inputs
diff --git a/build.zig b/build.zig
index 3234a16..f338a2c 100644
--- a/build.zig
+++ b/build.zig
@@ -2,6 +2,14 @@ const std = @import("std");
const print = std.debug.print;
pub fn build(b: *std.Build) void {
- const exe = b.addExecutable(.{ .name = "day01", .root_source_file = b.path("main.zig"), .target = b.standardTargetOptions(.{}), .optimize = .ReleaseFast });
+ const target = b.standardTargetOptions(.{});
+ const optimize = b.standardOptimizeOption(.{});
+
+ var exe = b.addExecutable(.{ .name = "aoc2024", .root_source_file = b.path("main.zig"), .target = target, .optimize = optimize });
+
+ const mecha = b.dependency("mecha", .{});
+
+ exe.root_module.addImport("mecha", mecha.module("mecha"));
+
b.installArtifact(exe);
}
diff --git a/build.zig.zon b/build.zig.zon
new file mode 100644
index 0000000..73a38f7
--- /dev/null
+++ b/build.zig.zon
@@ -0,0 +1,11 @@
+.{
+ .name = "aoc2024",
+ .version = "0.0.1",
+ .dependencies = .{
+ .mecha = .{
+ .url = "https://github.com/Hejsil/mecha/archive/refs/tags/0.9.0.tar.gz",
+ .hash = "12206311fbaae8a0adc35e4835ddd9bcc1ff8fff756c9df40e19133f007fa05d3948",
+ },
+ },
+ .paths = .{"."},
+}
diff --git a/main.zig b/main.zig
index 4facde2..871eec2 100644
--- a/main.zig
+++ b/main.zig
@@ -3,8 +3,8 @@ const print = std.debug.print;
const day01 = @import("src/day01.zig");
const day02 = @import("src/day02.zig");
-
-const Day = enum { day01, day02 };
+const day03 = @import("src/day03.zig");
+const day04 = @import("src/day04.zig");
pub fn main() !void {
if (std.os.argv.len != 3) {
@@ -27,13 +27,16 @@ pub fn main() !void {
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
- const day = std.meta.stringToEnum(Day, args[1]) orelse {
- print("Not valid day or day not yet implemented\n: {s}", .{args[1]});
+ const day = std.fmt.parseInt(usize, args[1], 10) catch {
+ print("Not valid day format\n: {s}", .{args[1]});
return;
};
try switch (day) {
- .day01 => day01.solve(args[2], buffer, allocator),
- .day02 => day02.solve(args[2], buffer),
+ 1 => day01.solve(args[2], buffer, allocator),
+ 2 => day02.solve(args[2], buffer),
+ 3 => day03.solve(args[2], buffer, allocator),
+ 4 => day04.solve(args[2], buffer, allocator),
+ else => print("Day not yet implemented", .{}),
};
}
diff --git a/prepare b/prepare
new file mode 100755
index 0000000..c433c1b
--- /dev/null
+++ b/prepare
@@ -0,0 +1,11 @@
+#!/bin/sh
+set -e
+if [ -z "$(command -v zig)" ]; then
+ echo "Install zig v0.13.0"
+ exit 1
+fi
+if [[ "$(zig version)" != "0.13.1" ]]; then
+ echo "Zig version is not 0.13.0. Let's hope this compiles."
+fi
+zig build -Doptimize=ReleaseFast
+echo "Success"
diff --git a/run b/run
new file mode 100755
index 0000000..31e8c10
--- /dev/null
+++ b/run
@@ -0,0 +1,3 @@
+#!/bin/sh
+set -e
+./zig-out/bin/aoc2024 "${1}" "${2}" < "${3}"
diff --git a/src/day01.zig b/src/day01.zig
index 33b0a67..d92e756 100644
--- a/src/day01.zig
+++ b/src/day01.zig
@@ -8,7 +8,7 @@ pub fn solve(part: []u8, buffer: []u8, allocator: std.mem.Allocator) !void {
defer left.deinit();
defer right.deinit();
- if (std.mem.eql(u8, part, "part1")) {
+ if (std.mem.eql(u8, part, "1")) {
try part1(&lines, &left, &right, allocator);
} else {
try part2(&lines, &left, &right, allocator);
@@ -41,7 +41,7 @@ fn part1(lines: *std.mem.SplitIterator(u8, .scalar), left: *std.ArrayList(usize)
}
}
- print("Sum is {d}\n", .{sum});
+ print("{d}\n", .{sum});
}
fn part2(lines: *std.mem.SplitIterator(u8, .scalar), left: *std.ArrayList(usize), right: *std.ArrayList(usize), allocator: std.mem.Allocator) !void {
@@ -77,5 +77,5 @@ fn part2(lines: *std.mem.SplitIterator(u8, .scalar), left: *std.ArrayList(usize)
};
}
- print("Sum is {d}\n", .{sum});
+ print("{d}\n", .{sum});
}
diff --git a/src/day02.zig b/src/day02.zig
index cad2d9d..e87b234 100644
--- a/src/day02.zig
+++ b/src/day02.zig
@@ -4,7 +4,7 @@ const print = std.debug.print;
pub fn solve(part: []u8, buffer: []u8) !void {
var lines = std.mem.splitScalar(u8, buffer, '\n');
- if (std.mem.eql(u8, part, "part1")) {
+ if (std.mem.eql(u8, part, "1")) {
try part1(&lines);
} else {
try part2(&lines);
@@ -38,7 +38,7 @@ fn part1(lines: *std.mem.SplitIterator(u8, .scalar)) !void {
}
}
- print("Safe count: {d}\n", .{count});
+ print("{d}\n", .{count});
}
fn part2(lines: *std.mem.SplitIterator(u8, .scalar)) !void {
@@ -87,5 +87,5 @@ fn part2(lines: *std.mem.SplitIterator(u8, .scalar)) !void {
}
}
}
- print("Safe count: {d}\n", .{count});
+ print("{d}\n", .{count});
}
diff --git a/src/day03.zig b/src/day03.zig
new file mode 100644
index 0000000..0a5e27e
--- /dev/null
+++ b/src/day03.zig
@@ -0,0 +1,63 @@
+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 part1(buffer: []const u8, allocator: std.mem.Allocator) !void {
+ const mul = mecha.combine(.{ mecha.string("mul(").discard(), mecha.int(usize, .{}), mecha.ascii.char(',').discard(), mecha.int(usize, .{}), mecha.ascii.char(')').discard() });
+
+ var sum: usize = 0;
+ var rest = buffer;
+ while (rest.len > 0) {
+ const result = mul.parse(allocator, rest) catch {
+ rest = rest[1..];
+ continue;
+ };
+ sum += result.value[0] * result.value[1];
+ rest = result.rest;
+ }
+
+ print("{d}", .{sum});
+}
+
+// UGLY
+fn part2(buffer: []const u8, allocator: std.mem.Allocator) !void {
+ const mul = mecha.combine(.{ mecha.string("mul(").discard(), mecha.int(usize, .{}), mecha.ascii.char(',').discard(), mecha.int(usize, .{}), mecha.ascii.char(')').discard() });
+
+ const dont = mecha.string("don't()");
+ const do = mecha.string("do()");
+
+ var sum: usize = 0;
+ var rest = buffer;
+ var disabled = false;
+ while (rest.len > 0) {
+ if (disabled) {
+ _ = do.parse(allocator, rest) catch {
+ rest = rest[1..];
+ continue;
+ };
+ disabled = false;
+ } else {
+ const result = mul.parse(allocator, rest) catch {
+ const result = dont.parse(allocator, rest) catch {
+ rest = rest[1..];
+ continue;
+ };
+ rest = result.rest;
+ disabled = true;
+ continue;
+ };
+ sum += result.value[0] * result.value[1];
+ rest = result.rest;
+ }
+ }
+
+ print("{d}", .{sum});
+}
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});
+}