AOC2024/src/day07.zig
jmug 1c1d15561c Solved day 7. A bit of recursion!
Signed-off-by: jmug <u.g.a.mariano@gmail.com>
2024-12-07 20:19:00 +00:00

73 lines
2.3 KiB
Zig

const std = @import("std");
const print = std.debug.print;
const fmt = std.fmt;
const args = @import("lib/args.zig");
const files = @import("lib/files.zig");
fn isEquationValid(operands: []u64, acc: u64, target: u64) bool {
if (operands.len == 0) {
return acc == target;
}
if (acc > target) {
return false;
}
return isEquationValid(operands[1..], acc * operands[0], target) or
isEquationValid(operands[1..], acc + operands[0], target);
}
fn concatIntegers(a: u64, b: u64) u64 {
return (a * std.math.pow(u64, 10, std.math.log10(b) + 1)) + b;
}
fn isEquationValidPart2(operands: []u64, acc: u64, target: u64) bool {
if (operands.len == 0) {
return acc == target;
}
if (acc > target) {
return false;
}
return isEquationValidPart2(operands[1..], acc * operands[0], target) or
isEquationValidPart2(operands[1..], concatIntegers(acc, operands[0]), target) or
isEquationValidPart2(operands[1..], acc + operands[0], target);
}
// equationValue takes an equation in string
// form and returns its calibration value
// if it can be made valid, otherwise, it
// returns null.
fn equationValue(buf: []u8) !?u64 {
var target: u64 = undefined;
var operands_buf: [16]u64 = undefined;
var operands_count: usize = 0;
var ptr: usize = 0;
while (buf[ptr] != ':') : (ptr += 1) {}
target = try fmt.parseUnsigned(u64, buf[0..ptr], 10);
// Skip colon and space.
ptr += 2;
while (ptr < buf.len) {
defer operands_count += 1;
const start = ptr;
while (ptr < buf.len and buf[ptr] != ' ') : (ptr += 1) {}
operands_buf[operands_count] = try fmt.parseUnsigned(u64, buf[start..ptr], 10);
ptr += 1; // Skip the space.
}
return if (isEquationValidPart2(operands_buf[0..operands_count], 0, target)) target else 0;
}
pub fn main() !void {
const input_path = args.getFirstArg();
const input = try files.openForReading(input_path);
defer input.close();
var calibration: u64 = 0;
var line_buf: [64]u8 = undefined;
while (files.readLine(input, &line_buf)) |line| {
calibration += (try equationValue(line)) orelse 0;
} else |err| {
print("done reading input file with error: {any}\n", .{err});
}
print("Calibration value: {d}\n", .{calibration});
}