summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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});
+}