const std = @import("std"); pub fn day2pt1(ranges: []const u8) !usize { var i = std.mem.splitScalar(u8, ranges, ','); var sum: usize = 0; while (i.next()) |range| { var j = std.mem.splitScalar(u8, range, '-'); const range_start = try std.fmt.parseInt(usize, j.next().?, 10); const range_end = try std.fmt.parseInt(usize, j.next().?, 10); var k = range_start; const max_len = 32; var buf: [max_len]u8 = undefined; while (k <= range_end) { const current_id = try std.fmt.bufPrint(&buf, "{d}", .{k}); if (current_id.len % 2 == 0) { const half = current_id.len / 2; if (std.mem.eql(u8, current_id[0..half], current_id[half..current_id.len])) { sum += k; } } k += 1; } } return sum; } pub fn day2pt2(ranges: []const u8) !usize { var i = std.mem.splitScalar(u8, ranges, ','); var sum: usize = 0; while (i.next()) |range| { var j = std.mem.splitScalar(u8, range, '-'); const range_start = try std.fmt.parseInt(usize, j.next().?, 10); const range_end = try std.fmt.parseInt(usize, j.next().?, 10); var k = range_start; const max_len = 32; var buf: [max_len]u8 = undefined; while (k <= range_end) { const current_id = try std.fmt.bufPrint(&buf, "{d}", .{k}); const len = current_id.len; var found = false; // Try all possible substring lengths that divide the length - should be made more efficient (>人<;) for (1..len / 2 + 1) |sub_len| { if (len % sub_len != 0) continue; const repeats = len / sub_len; if (repeats < 2) continue; const sub = current_id[0..sub_len]; var valid = true; for (1..repeats) |r| { if (!std.mem.eql(u8, sub, current_id[r * sub_len .. (r + 1) * sub_len])) { valid = false; break; } } if (valid) { found = true; break; } } if (found) { sum += k; } k += 1; } } return sum; } test "Day 2 example testing" { const example_input = "11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124"; try std.testing.expectEqual(try day2pt1(example_input), 1227775554); try std.testing.expectEqual(try day2pt2(example_input), 4174379265); }