summaryrefslogtreecommitdiff
path: root/day2/zig/src/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'day2/zig/src/main.zig')
-rw-r--r--day2/zig/src/main.zig76
1 files changed, 76 insertions, 0 deletions
diff --git a/day2/zig/src/main.zig b/day2/zig/src/main.zig
new file mode 100644
index 0000000..3f68491
--- /dev/null
+++ b/day2/zig/src/main.zig
@@ -0,0 +1,76 @@
+const std = @import("std");
+const mem = std.mem;
+const math = std.math;
+
+pub fn main() !void {
+ const input: []const u8 = @embedFile("input.txt");
+ const part1, const part2 = try problem(input);
+ std.debug.print("Part 1: {}\n", .{part1});
+ std.debug.print("Part 2: {}\n", .{part2});
+}
+
+fn problem(input: []const u8) !struct { u64, u64 } {
+ var lines: mem.TokenIterator(u8, .scalar) = mem.tokenizeScalar(u8, input[0..input.len - 1], ',');
+ var part1: u64 = 0;
+ var part2: u64 = 0;
+ part2 += 0;
+ while (lines.next()) |line| {
+ var from: u64, const to = try parseline(line);
+ while (from <= to) : (from += 1) {
+ if (try invalidate(from)) part1 += from;
+ if (try invalidate2(from)) part2 += from;
+ }
+
+ }
+ return .{ part1, part2 };
+}
+
+fn invalidate2(num: u64) !bool {
+ var multiplier: u64 = 10;
+ var buf: [64]u8 = undefined;
+ var num1 = @divTrunc(num, multiplier);
+ var num2 = @rem(num, multiplier);
+ const len = (try std.fmt.bufPrint(&buf, "{d}", .{num})).len;
+ while (num1 > 0) : ({multiplier *= 10; num1 = @divTrunc(num, multiplier); num2 = @rem(num, multiplier);}) {
+ const len1 = (try std.fmt.bufPrint(&buf, "{d}", .{num1})).len;
+ const len2 = (try std.fmt.bufPrint(&buf, "{d}", .{num2})).len;
+ if (len1 + len2 != len) continue;
+ if (num1 < num2) continue;
+ if (num2 == 0) continue;
+ const diff = @divTrunc(num1 - num2, len2);
+ std.debug.print("num1 = {d}\ndiff = {d}\n", .{num1, diff});
+ if (@rem(diff, multiplier) == num2) return true;
+ if (num1 == num2) return true;
+ }
+ return false;
+}
+
+fn invalidate(num: u64) !bool {
+ var multiplier: u64 = 10;
+ var buf: [64]u8 = undefined;
+ const len = (try std.fmt.bufPrint(&buf, "{d}", .{num})).len;
+ while (@divTrunc(num, multiplier) > 0) : (multiplier *= 10) {
+ const len1 = (try std.fmt.bufPrint(&buf, "{d}", .{@divTrunc(num, multiplier)})).len;
+ const len2 = (try std.fmt.bufPrint(&buf, "{d}", .{@rem(num, multiplier)})).len;
+ if (len1 + len2 != len) continue;
+ if (@divTrunc(num, multiplier) == @rem(num, multiplier)) return true;
+ }
+ return false;
+}
+
+fn parseline(l: []const u8) !struct { u64, u64 } {
+ var split = mem.splitScalar(u8, l, '-');
+ const from = try std.fmt.parseInt(u64, split.next().?, 10);
+ const to = try std.fmt.parseInt(u64, split.next().?, 10);
+ return .{ from, to };
+}
+
+
+test "Sample Input" {
+ const input: []const u8 = @embedFile("input_sample.txt");
+ const part1, const part2 = try problem(input);
+ std.debug.print("Part 1: {}\n", .{part1});
+ std.debug.print("Part 2: {}\n", .{part2});
+ try std.testing.expectEqual(1227775554, part1);
+ try std.testing.expectEqual(4174379265, part2);
+}