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 }