const std = @import("std"); const Range = struct { start: u64, end: u64 }; pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); var stdin_buffer: [1024]u8 = undefined; var stdin_reader = std.fs.File.stdin().reader(&stdin_buffer); const stdin = &stdin_reader.interface; const allocator = gpa.allocator(); var ranges = try std.ArrayList(Range).initCapacity(allocator, 1); defer ranges.deinit(allocator); var numbers = try std.ArrayList(u64).initCapacity(allocator, 1); defer numbers.deinit(allocator); var reading_ranges = true; while (try stdin.takeDelimiter('\n')) |line| { const line_trimmed = std.mem.trim(u8, line, "\n"); if (line.len == 0) { reading_ranges = false; continue; } if (reading_ranges) { var it = std.mem.splitScalar(u8, line_trimmed, '-'); const start = try std.fmt.parseInt(u64, it.next().?, 10); const end = try std.fmt.parseInt(u64, it.next().?, 10); const range = Range{ .start = start, .end = end }; try ranges.append(allocator, range); } else { const number = try std.fmt.parseInt(u64, line_trimmed, 10); try numbers.append(allocator, number); } } var task1: u64 = 0; for (numbers.items) |number| { var spoiled = true; for (ranges.items) |range| { if (number <= range.end and number >= range.start) { spoiled = false; break; } } if (!spoiled) { task1 += 1; } } var merged = true; while (merged) { merged = false; for (ranges.items, 0..) |range1, i| { for (ranges.items[i + 1 ..], i + 1..) |range2, j| { // Non-overlapping if (range1.end < range2.start or range1.start > range2.end) { continue; } // Calculate new range const start = @min(range1.start, range2.start); const end = @max(range1.end, range2.end); ranges.items[i].start = start; ranges.items[i].end = end; _ = ranges.orderedRemove(j); merged = true; break; } if (merged) { break; } } } var task2: u64 = 0; for (ranges.items) |range| { task2 += range.end - range.start + 1; } std.debug.print("{d}\n", .{task1}); std.debug.print("{d}\n", .{task2}); }