diff options
Diffstat (limited to 'day2/zig/src/main.zig')
| -rw-r--r-- | day2/zig/src/main.zig | 76 |
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); +} |
