const std = @import("std"); const Io = std.Io; const shared = @import("shared.zig"); const print = shared.print; var buf: [4096]u8 = undefined; fn repeatCountFromStart(needle: []const u8, haystack: []const u8) usize { var off: usize = 0; var count: usize = 0; while (off + needle.len <= haystack.len and std.mem.eql(u8, needle, haystack[off .. off + needle.len])) { count += 1; off += needle.len; } return count; } pub fn main(init: std.process.Init) !void { try shared.sharedInit(init); const allocator: std.mem.Allocator = init.arena.allocator(); const bytes = shared.loadBytesArg(allocator); var tok = std.mem.tokenizeScalar(u8, bytes, ','); var part1: i64 = 0; var part2: i64 = 0; while (tok.next()) |next| { var splitIter = std.mem.splitAny(u8, next, "-"); var v: [2]i64 = .{ 0, 0 }; var i: usize = 0; while (splitIter.next()) |s| { v[i] = try std.fmt.parseInt(i64, s, 10); i += 1; if (i > 2) unreachable; } for (@intCast(v[0])..@intCast(v[1] + 1)) |j| { const s = try std.fmt.bufPrint(&buf, "{d}", .{j}); const left = s[0..(s.len >> 1)]; if (s.len % 2 == 0 and shared.countInstancesOf(s, left) == 2) { part1 += @intCast(j); } var h: usize = s.len + 1; while (h - 1 > 0) : (h -= 1) { const count = repeatCountFromStart(s[0 .. h - 1], s); if (count * (h - 1) == s.len and count != 1) { part2 += @intCast(j); break; } } } } print("part1 {d} part2 {d}", .{ part1, part2 }); }