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}); } }