diff --git a/day07.zig b/day07.zig new file mode 100644 index 0000000..e487e2e --- /dev/null +++ b/day07.zig @@ -0,0 +1,98 @@ +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}); + } +}