diff options
author | Xander Bil <xander@biltopia.org> | 2024-12-07 21:39:58 +0100 |
---|---|---|
committer | Xander Bil <xander@biltopia.org> | 2024-12-07 21:39:58 +0100 |
commit | bd982cf90112e274032385277906af3fae7efe24 (patch) | |
tree | 7b622b2654ce8d6ec7214f1605d0be85b748663d | |
parent | 052730818acaf3fd9b234a62bd01054732786d8a (diff) | |
download | aoc2024-bd982cf90112e274032385277906af3fae7efe24.tar.xz aoc2024-bd982cf90112e274032385277906af3fae7efe24.zip |
add solution day07
-rw-r--r-- | main.zig | 2 | ||||
-rw-r--r-- | src/day07.zig | 109 |
2 files changed, 111 insertions, 0 deletions
@@ -7,6 +7,7 @@ const day03 = @import("src/day03.zig"); const day04 = @import("src/day04.zig"); const day05 = @import("src/day05.zig"); const day06 = @import("src/day06.zig"); +const day07 = @import("src/day07.zig"); pub fn main() !void { if (std.os.argv.len != 3) { @@ -41,6 +42,7 @@ pub fn main() !void { 4 => day04.solve(args[2], buffer, allocator), 5 => day05.solve(args[2], buffer, allocator), 6 => day06.solve(args[2], buffer, allocator), + 7 => day07.solve(args[2], buffer, allocator), else => print("Day not yet implemented", .{}), }; } diff --git a/src/day07.zig b/src/day07.zig new file mode 100644 index 0000000..f06e08d --- /dev/null +++ b/src/day07.zig @@ -0,0 +1,109 @@ +const std = @import("std"); +const mecha = @import("mecha"); +const print = std.debug.print; + +pub fn solve(part: []u8, buffer: []u8, allocator: std.mem.Allocator) !void { + if (std.mem.eql(u8, part, "1")) { + try part1(buffer, allocator); + } else { + try part2(buffer, allocator); + } +} + +fn evaluate(test_value: usize, numbers: []const usize, index: usize) bool { + if (index == 0) { + return test_value == numbers[0]; + } + + const number = numbers[index]; + + const division: usize = test_value / number; + + if (division * number == test_value) { + const b = evaluate(division, numbers, index - 1); + if (!b and test_value >= number and (test_value - number) % number == 0) return evaluate(test_value - number, numbers, index - 1); + return b; + } else if (test_value >= number) { + return evaluate(test_value - number, numbers, index - 1); + } + + return false; +} + +fn part1(buffer: []const u8, allocator: std.mem.Allocator) !void { + const parser = mecha.combine(.{ mecha.int(usize, .{}), mecha.string(": ").discard(), mecha.many(mecha.int(usize, .{}), .{ .separator = mecha.string(" ").discard() }) }); + var lines = std.mem.splitScalar(u8, buffer, '\n'); + + var total: usize = 0; + while (lines.next()) |line| { + if (line.len == 0) break; + + const parsed = try parser.parse(allocator, line); + const test_value = parsed.value[0]; + const numbers: []const usize = parsed.value[1]; + + if (evaluate(test_value, numbers, numbers.len - 1)) { + total += parsed.value[0]; + } + allocator.free(numbers); + } + print("{d}\n", .{total}); +} + +//----------------------------------------------PART 2-------------------------------------------------------- + +fn magnitude(int2: usize) usize { + var count: usize = 0; + var temp = int2; + while (temp > 0) { + temp /= 10; + count += 1; + } + return std.math.pow(usize, 10, count); +} + +fn evaluate2(test_value: usize, numbers: []usize, index: usize) bool { + if (index == 0) { + return test_value == numbers[0]; + } + + const number = numbers[index]; + + const division: usize = test_value / number; + + if (division * number == test_value) { + const b = evaluate2(division, numbers, index - 1); + if (b) { + return true; + } else if (test_value >= number and (test_value - number) % number == 0 and evaluate2(test_value - number, numbers, index - 1)) return true; + } else if (test_value >= number and evaluate2(test_value - number, numbers, index - 1)) { + return true; + } + + const base = magnitude(number); + if (test_value % base == number) { + return evaluate2(test_value / base, numbers, index - 1); + } + + return false; +} + +fn part2(buffer: []const u8, allocator: std.mem.Allocator) !void { + const parser = mecha.combine(.{ mecha.int(usize, .{}), mecha.string(": ").discard(), mecha.many(mecha.int(usize, .{}), .{ .separator = mecha.string(" ").discard() }) }); + var lines = std.mem.splitScalar(u8, buffer, '\n'); + + var total: usize = 0; + while (lines.next()) |line| { + if (line.len == 0) break; + + const parsed = try parser.parse(allocator, line); + const test_value = parsed.value[0]; + const numbers: []usize = parsed.value[1]; + + if (evaluate2(test_value, numbers, numbers.len - 1)) { + total += parsed.value[0]; + } + allocator.free(numbers); + } + print("{d}\n", .{total}); +} |