Solved day 7. A bit of recursion!
Signed-off-by: jmug <u.g.a.mariano@gmail.com>
This commit is contained in:
parent
c5a1797ded
commit
1c1d15561c
3 changed files with 932 additions and 0 deletions
73
src/day07.zig
Normal file
73
src/day07.zig
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
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});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue