summaryrefslogtreecommitdiff
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
parent052730818acaf3fd9b234a62bd01054732786d8a (diff)
downloadaoc2024-bd982cf90112e274032385277906af3fae7efe24.tar.xz
aoc2024-bd982cf90112e274032385277906af3fae7efe24.zip
add solution day07
-rw-r--r--main.zig2
-rw-r--r--src/day07.zig109
2 files changed, 111 insertions, 0 deletions
diff --git a/main.zig b/main.zig
index 98a6d94..3018ab2 100644
--- a/main.zig
+++ b/main.zig
@@ -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});
+}