summaryrefslogtreecommitdiff
path: root/src/day07.zig
diff options
context:
space:
mode:
authorXander Bil <xander@biltopia.org>2024-12-07 21:39:58 +0100
committerXander Bil <xander@biltopia.org>2024-12-07 21:39:58 +0100
commitbd982cf90112e274032385277906af3fae7efe24 (patch)
tree7b622b2654ce8d6ec7214f1605d0be85b748663d /src/day07.zig
parent052730818acaf3fd9b234a62bd01054732786d8a (diff)
downloadaoc2024-bd982cf90112e274032385277906af3fae7efe24.tar.xz
aoc2024-bd982cf90112e274032385277906af3fae7efe24.zip
add solution day07
Diffstat (limited to 'src/day07.zig')
-rw-r--r--src/day07.zig109
1 files changed, 109 insertions, 0 deletions
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});
+}