1diff --git a/src/day2.zig b/src/day2.zig 2new file mode 100644 3index 0000000000000000000000000000000000000000..54ded3d37f9fe656223e3120b2a6fb72457d51ba 4--- /dev/null 5+++ b/src/day2.zig 6@@ -0,0 +1,134 @@ 7+const std = @import("std"); 8+ 9+pub fn pt1(comptime input: []const u8) u64 { 10+ const r = input[0 .. input.len - 1]; 11+ var ranges = std.mem.splitScalar(u8, r, ','); 12+ 13+ var count: u64 = 0; 14+ while (ranges.next()) |l| { 15+ if (l.len == 0) { 16+ return count; 17+ } 18+ 19+ var range = parseRange(l); 20+ while (range.next()) |v| { 21+ if (isRange(v)) { 22+ count += v; 23+ } 24+ } 25+ } 26+ return count; 27+} 28+ 29+pub fn pt2(comptime input: []const u8) u64 { 30+ const r = input[0 .. input.len - 1]; 31+ var ranges = std.mem.splitScalar(u8, r, ','); 32+ 33+ var count: u64 = 0; 34+ while (ranges.next()) |l| { 35+ if (l.len == 0) { 36+ return count; 37+ } 38+ 39+ var range = parseRange(l); 40+ while (range.next()) |v| { 41+ if (isRangeN(v)) { 42+ count += v; 43+ } 44+ } 45+ } 46+ return count; 47+} 48+ 49+var buf: [20]u8 = undefined; 50+ 51+fn isRangeN(v: u64) bool { 52+ const str = std.fmt.bufPrint(&buf, "{d}", .{v}) catch unreachable; 53+ for (1..str.len) |s| { 54+ // We can't check if this batch can not evenly chunked. 55+ if (@mod(str.len, s) != 0) { 56+ continue; 57+ } 58+ 59+ const c = str.len / s; // size on the chunk 60+ const p = str[0..s]; // first chunk as reference for eql 61+ var m = true; // flag that says if something went wrong (if wrong set false) 62+ 63+ 64+ for (1..c) |i| { 65+ const sub_str = str[i * s .. ((1 + i) * s)]; 66+ if (!std.mem.eql(u8, p, sub_str)) { 67+ m = false; 68+ break; 69+ } 70+ } 71+ 72+ if (m) return true; 73+ } 74+ 75+ return false; 76+} 77+ 78+fn isRange(v: u64) bool { 79+ const str = std.fmt.bufPrint(&buf, "{d}", .{v}) catch unreachable; 80+ 81+ if ((str.len % 2) != 0) { 82+ return false; 83+ } 84+ 85+ const mid = str.len / 2; 86+ 87+ for (0..mid) |i| { 88+ if (str[i] != str[i + mid]) { 89+ return false; 90+ } 91+ } 92+ 93+ return true; 94+} 95+ 96+const Range = struct { 97+ from: u64 = 0, 98+ to: u64 = 0, 99+ index: u64 = 0, 100+ 101+ pub fn next(self: *Range) ?u64 { 102+ const to = self.from + self.index; 103+ if (to > self.to) { 104+ return null; 105+ } 106+ 107+ self.index += 1; 108+ return to; 109+ } 110+}; 111+ 112+fn parseRange(range_str: []const u8) Range { 113+ var range: Range = .{}; 114+ var iter = std.mem.splitScalar(u8, range_str, '-'); 115+ 116+ var i: u64 = 0; 117+ while (iter.next()) |v| { 118+ if (i == 0) { 119+ range.from = std.fmt.parseInt(u64, v, 10) catch unreachable; 120+ } else if (i == 1) { 121+ range.to = std.fmt.parseInt(u64, v, 10) catch unreachable; 122+ } else { 123+ break; 124+ } 125+ 126+ i += 1; 127+ } 128+ 129+ return range; 130+} 131+ 132+test "Day 2 part 1" { 133+ const res = pt1(@embedFile("./input/day2")); 134+ try std.testing.expect(res == 55916882972); 135+} 136+ 137+test "Day 2 part 2" { 138+ const res = pt2(@embedFile("./input/day2")); 139+ try std.testing.expect(res == 76169125915); 140+} 141diff --git a/src/input/day2 b/src/input/day2 142new file mode 100644 143index 0000000000000000000000000000000000000000..e25e1dfab5ef285fcab6de587bba923f671d1cd2 144Binary files /dev/null and b/src/input/day2 differ 145diff --git a/src/main.zig b/src/main.zig 146index 5e3e5db784a782f83dbbeb21cee134173fdc4a37..a4db764ce025c1f5602895b2bd39383d4d53333f 100644 147--- a/src/main.zig 148+++ b/src/main.zig 149@@ -1,19 +1,27 @@ 150 const std = @import("std"); 151 const day1 = @import("day1.zig"); 152+const day2 = @import("day2.zig"); 153 154 pub export fn main() void { 155- if (std.os.argv.len != 2) { 156- std.debug.print("Invalid day", .{}); 157- } 158+ for (1..std.os.argv.len) |i| { 159+ const day = std.mem.span(std.os.argv[i]); 160 161- const day = std.mem.span(std.os.argv[1]); 162+ if (std.mem.eql(u8, "day1", day)) { 163+ print(day1.pt1(@embedFile("./input/day1"))); 164+ print(day1.pt2(@embedFile("./input/day1"))); 165+ } else if (std.mem.eql(u8, "day2", day)) { 166+ print(day2.pt1(@embedFile("./input/day2"))); 167+ print(day2.pt2(@embedFile("./input/day2"))); 168+ } 169+ } 170+} 171 172- if (std.mem.eql(u8, "--day1", day)) { 173- const res1 = day1.pt1(@embedFile("./input/day1")); 174- std.debug.print("{d}\n", .{res1}); 175- const res2 = day1.pt2(@embedFile("./input/day1")); 176- std.debug.print("{d}\n", .{res2}); 177+fn print(res: anytype) void { 178+ const ArgsType = @TypeOf(res); 179+ const res_type_info = @typeInfo(ArgsType); 180+ if (res_type_info == .int) { 181+ std.debug.print("{d}\n", .{res}); 182 } else { 183- std.debug.print("Invalid day", .{}); 184+ @compileError("print not implemented for this type"); 185 } 186 }