diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | build.zig | 10 | ||||
-rw-r--r-- | build.zig.zon | 11 | ||||
-rw-r--r-- | main.zig | 15 | ||||
-rwxr-xr-x | prepare | 11 | ||||
-rwxr-xr-x | run | 3 | ||||
-rw-r--r-- | src/day01.zig | 6 | ||||
-rw-r--r-- | src/day02.zig | 6 | ||||
-rw-r--r-- | src/day03.zig | 63 | ||||
-rw-r--r-- | src/day04.zig | 136 |
10 files changed, 249 insertions, 13 deletions
@@ -1,2 +1,3 @@ zig-out/ .zig-cache +inputs @@ -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 = .{"."}, +} @@ -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", .{}), }; } @@ -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" @@ -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}); +} |