aoc2024/day07.zig

99 lines
2.7 KiB
Zig
Raw Normal View History

const std = @import("std");
const input = @embedFile("day07");
const Equation = struct {
result: u64,
values: std.ArrayList(u32)
};
var puzzle: std.ArrayList(Equation) = undefined;
pub fn main () !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
switch (gpa.deinit()) {
.leak => @panic("leaked memory"),
else => {},
}
}
const gpa_alloc = gpa.allocator();
var arena = std.heap.ArenaAllocator.init(gpa_alloc);
defer arena.deinit();
const alloc = arena.allocator();
try parse_puzzle(alloc);
var result1: u64 = 0;
var result2: u64 = 0;
for(0..puzzle.items.len) |eqi| {
const eq = puzzle.items[eqi];
const val = eq.values.items[0];
const val_cnt = eq.values.items.len;
if(part1(eqi, 1, val_cnt, val)) {
result1 += eq.result;
}
if(part2(eqi, 1, val_cnt, val)) {
result2 += eq.result;
}
}
const out = std.io.getStdOut().writer();
try out.print("Result 1: {d}\n", .{result1});
try out.print("Result 2: {d}\n", .{result2});
}
fn part1(eqi: usize, vali: usize, endi: usize, cur: u64) bool {
const eq = puzzle.items[eqi];
if(cur>eq.result) return false;
if(vali==endi and cur==eq.result) return true;
if(vali==endi) return false;
const val = eq.values.items[vali];
return part1(eqi, vali+1, endi, cur+val)
or part1(eqi, vali+1, endi, cur*val);
}
inline fn concat(a: u64, b: u32) u64 {
var buf: [20]u8 = undefined;
const str = std.fmt.bufPrint(&buf, "{d}{d}", .{a,b}) catch @panic("lol");
return std.fmt.parseInt(u64, str, 10) catch @panic("lol");
}
fn part2(eqi: usize, vali: usize, endi: usize, cur: u64) bool {
const eq = puzzle.items[eqi];
if(cur>eq.result) return false;
if(vali==endi and cur==eq.result) return true;
if(vali==endi) return false;
const val = eq.values.items[vali];
return part2(eqi, vali+1, endi, cur+val)
or part2(eqi, vali+1, endi, cur*val)
or part2(eqi, vali+1, endi, concat(cur,val));
}
fn parse_puzzle(alloc: std.mem.Allocator) !void {
puzzle = std.ArrayList(Equation).init(alloc);
errdefer puzzle.deinit();
var line_it = std.mem.tokenizeScalar(u8, input, '\n');
while(line_it.next()) |line| {
var res_it = std.mem.tokenizeScalar(u8, line, ':');
const result: u64 = try std.fmt.parseInt(u64, res_it.next().?, 10);
var values = std.ArrayList(u32).init(alloc);
errdefer values.deinit();
var val_it = std.mem.tokenizeScalar(u8, res_it.next().?, ' ');
while(val_it.next()) |val| {
try values.append(try std.fmt.parseInt(u32, val, 10));
}
try puzzle.append(.{.result=result, .values=values});
}
}