const std = @import("std"); const Allocator = std.mem.Allocator; pub fn run(_: Allocator, input: []u8) !struct { u64, u64 } { var ranges = std.mem.tokenizeScalar(u8, std.mem.trimEnd(u8, input, "\n"), ','); var answer1: u64 = 0; var answer2: u64 = 0; while (ranges.next()) |range_str| { var range = std.mem.tokenizeScalar(u8, range_str, '-'); const low = try std.fmt.parseInt(u64, range.next().?, 10); const high = try std.fmt.parseInt(u64, range.next().?, 10); var buf: [32]u8 = undefined; for (low..high + 1) |num| { const num_str = try std.fmt.bufPrint(&buf, "{d}", .{num}); const middle = num_str.len / 2; if (std.mem.eql(u8, num_str[0..middle], num_str[middle..])) { answer1 += num; answer2 += num; continue; } for (1..middle + 1) |chunk_len| { const repeating_str = num_str[0..chunk_len]; var is_repeating = true; var i = chunk_len; while (i + chunk_len <= num_str.len) : (i += chunk_len) { if (num_str.len % chunk_len != 0) { is_repeating = false; break; } if (!std.mem.eql(u8, repeating_str, num_str[i .. i + chunk_len])) { is_repeating = false; break; } } if (is_repeating) { answer2 += num; break; } } } } return .{ answer1, answer2 }; }