1const std = @import("std");
2const Allocator = std.mem.Allocator;
3
4pub fn run(_: Allocator, input: []u8) !struct { u64, u64 } {
5 var ranges = std.mem.tokenizeScalar(u8, std.mem.trimEnd(u8, input, "\n"), ',');
6
7 var answer1: u64 = 0;
8 var answer2: u64 = 0;
9 while (ranges.next()) |range_str| {
10 var range = std.mem.tokenizeScalar(u8, range_str, '-');
11
12 const low = try std.fmt.parseInt(u64, range.next().?, 10);
13 const high = try std.fmt.parseInt(u64, range.next().?, 10);
14
15 var buf: [32]u8 = undefined;
16 for (low..high + 1) |num| {
17 const num_str = try std.fmt.bufPrint(&buf, "{d}", .{num});
18
19 const middle = num_str.len / 2;
20
21 if (std.mem.eql(u8, num_str[0..middle], num_str[middle..])) {
22 answer1 += num;
23 answer2 += num;
24 continue;
25 }
26
27 for (1..middle + 1) |chunk_len| {
28 const repeating_str = num_str[0..chunk_len];
29
30 var is_repeating = true;
31 var i = chunk_len;
32 while (i + chunk_len <= num_str.len) : (i += chunk_len) {
33 if (num_str.len % chunk_len != 0) {
34 is_repeating = false;
35 break;
36 }
37
38 if (!std.mem.eql(u8, repeating_str, num_str[i .. i + chunk_len])) {
39 is_repeating = false;
40 break;
41 }
42 }
43
44 if (is_repeating) {
45 answer2 += num;
46 break;
47 }
48 }
49 }
50 }
51
52 return .{ answer1, answer2 };
53}