Skip to content

Commit

Permalink
2024 day 3
Browse files Browse the repository at this point in the history
  • Loading branch information
agagniere committed Dec 3, 2024
1 parent 1ac888a commit 182c9bc
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
*.o
__pycache__
*.txt
.zig-cache
zig-out
8 changes: 0 additions & 8 deletions 2024/01/utils.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,3 @@ fn LineIterator(comptime size: usize, comptime readerType: type, comptime delimi
pub fn lineIterator(reader: anytype) LineIterator(2048, @TypeOf(reader), '\n') {
return .{ .reader = reader };
}

pub fn lineIteratorSize(comptime size: usize, reader: anytype) LineIterator(size, @TypeOf(reader), '\n') {
return .{ .reader = reader };
}

pub fn lineIteratorCustom(comptime size: usize, comptime delimiter: u8, reader: anytype) LineIterator(size, @TypeOf(reader), delimiter) {
return .{ .reader = reader };
}
8 changes: 0 additions & 8 deletions 2024/02/utils.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,3 @@ fn LineIterator(comptime size: usize, comptime readerType: type, comptime delimi
pub fn lineIterator(reader: anytype) LineIterator(2048, @TypeOf(reader), '\n') {
return .{ .reader = reader };
}

pub fn lineIteratorSize(comptime size: usize, reader: anytype) LineIterator(size, @TypeOf(reader), '\n') {
return .{ .reader = reader };
}

pub fn lineIteratorCustom(comptime size: usize, comptime delimiter: u8, reader: anytype) LineIterator(size, @TypeOf(reader), delimiter) {
return .{ .reader = reader };
}
41 changes: 41 additions & 0 deletions 2024/03/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const std = @import("std");

pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

const utils = b.dependency("utils", .{ .target = target, .optimize = optimize }).module("utils");

const exe = b.addExecutable(.{
.name = "day3",
.root_source_file = b.path("solve.zig"),
.target = target,
.optimize = optimize,
});

exe.root_module.addImport("utils", utils);
b.installArtifact(exe);

{ // Run
const run_step = b.step("run", "Run the app");
const run_cmd = b.addRunArtifact(exe);

run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
run_step.dependOn(&run_cmd.step);
}
{ // Test
const test_step = b.step("test", "Run unit tests");
const unit_tests = b.addTest(.{
.root_source_file = b.path("solve.zig"),
.target = target,
.optimize = optimize,
});
const run_unit_tests = b.addRunArtifact(unit_tests);

unit_tests.root_module.addImport("utils", utils);
test_step.dependOn(&run_unit_tests.step);
}
}
11 changes: 11 additions & 0 deletions 2024/03/build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.{
.name = "day03",
.version = "0.1.0",
.dependencies = .{
.utils = .{
.url = "../utils",
.hash = "122059863bba3b73097c2905eacfa772e5c9ad7cd6616270b08dfdf41e3d81900420",
},
},
.paths = .{ "build.zig", "build.zig.zon", "solve.zig" },
}
6 changes: 6 additions & 0 deletions 2024/03/python.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from utils import lines
import re
from math import prod

parse = re.compile(r'mul\((\d+)[,](\d+)\)')
print(sum(sum(prod(map(int, m.groups())) for m in parse.finditer(line)) for line in lines()))
101 changes: 101 additions & 0 deletions 2024/03/solve.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
const std = @import("std");
const utils = @import("utils");

pub fn scan(input: []const u8) [2]u64 {
var total: u64 = 0;
var branched: u64 = 0;
var enabled: bool = true;
var state: enum { none, m, u, l, paren, term1, comma, term2, d, o, n, quote, t, dop, dontp } = .none;
var left: u64 = 0;
var right: u64 = 0;

for (input) |c| {
switch (state) {
.none => {
if (c == 'm')
state = .m;
if (c == 'd')
state = .d;
},

.m => state = if (c == 'u') .u else .none,
.u => state = if (c == 'l') .l else .none,
.l => state = if (c == '(') .paren else .none,

.paren => if (std.ascii.isDigit(c)) {
left = c - '0';
state = .term1;
} else {
state = .none;
},

.term1 => if (std.ascii.isDigit(c)) {
left = left * 10 + (c - '0');
} else if (c == ',') {
state = .comma;
} else {
state = .none;
},

.comma => if (std.ascii.isDigit(c)) {
right = c - '0';
state = .term2;
} else {
state = .none;
},

.term2 => if (std.ascii.isDigit(c)) {
right = right * 10 + (c - '0');
} else if (c == ')') {
total += left * right;
if (enabled)
branched += left * right;
state = .none;
} else {
state = .none;
},

.d => state = if (c == 'o') .o else .none,
.o => state = if (c == '(') .dop else if (c == 'n') .n else .none,
.n => state = if (c == '\'') .quote else .none,
.quote => state = if (c == 't') .t else .none,
.t => state = if (c == '(') .dontp else .none,

.dop => {
if (c == ')') enabled = true;
state = .none;
},
.dontp => {
if (c == ')') enabled = false;
state = .none;
},
}
}
return .{ total, branched };
}

pub fn main() !void {
var stdin = std.io.bufferedReader(std.io.getStdIn().reader());
var lines = utils.lineIteratorSize(3100, stdin.reader());
var total: [2]u64 = .{ 0, 0 };

while (lines.next()) |line| {
const res = scan(line);
total[0] += res[0];
total[1] += res[1];
}
std.debug.print("Program output : {}\n", .{total[0]});
std.debug.print("Withg branching: {}\n", .{total[1]});
}

test "part1" {
const sample = "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))";

try std.testing.expectEqual(161, scan(sample)[0]);
}

test "part2" {
const sample = "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))";

try std.testing.expectEqual(48, scan(sample)[1]);
}
27 changes: 27 additions & 0 deletions 2024/utils/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const std = @import("std");

pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

const source_file = b.path("utils.zig");

_ = b.addModule("utils", .{
.root_source_file = source_file,
.target = target,
.optimize = optimize,
});

{ // Test
const test_step = b.step("test", "Run unit tests");

const unit_tests = b.addTest(.{
.root_source_file = source_file,
.target = target,
.optimize = optimize,
});

const run_unit_tests = b.addRunArtifact(unit_tests);
test_step.dependOn(&run_unit_tests.step);
}
}
5 changes: 5 additions & 0 deletions 2024/utils/build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.{
.name = "utils-2024",
.version = "0.0.1",
.paths = .{ "build.zig", "build.zig.zon", "utils.zig" },
}
32 changes: 32 additions & 0 deletions 2024/utils/utils.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const std = @import("std");

fn LineIterator(comptime size: usize, comptime readerType: type, comptime delimiter: u8) type {
return struct {
reader: readerType,
buffer: [size]u8 = undefined,

const Self = @This();

pub fn next(self: *Self) ?[]u8 {
return self.reader.readUntilDelimiterOrEof(&self.buffer, delimiter) catch {
return null;
};
}
};
}

/// Create an iterator from an infinite stream of bytes,
/// that yields each line encountered
pub fn lineIterator(reader: anytype) LineIterator(2048, @TypeOf(reader), '\n') {
return .{ .reader = reader };
}

/// Same as lineIterator but with a non default max line size
pub fn lineIteratorSize(comptime size: usize, reader: anytype) LineIterator(size, @TypeOf(reader), '\n') {
return .{ .reader = reader };
}

/// Same as lineIteratorSize but with a non default delimiter
pub fn lineIteratorCustom(comptime size: usize, comptime delimiter: u8, reader: anytype) LineIterator(size, @TypeOf(reader), delimiter) {
return .{ .reader = reader };
}

0 comments on commit 182c9bc

Please sign in to comment.