aoc/year2016/
day20.rs

1//! # Firewall Rules
2use crate::util::iter::*;
3use crate::util::parse::*;
4
5type Range = [u64; 2];
6
7/// The trick to merge ranges efficiently is to sort by the *starting* index.
8pub fn parse(input: &str) -> Vec<Range> {
9    let mut ranges: Vec<_> = input.iter_unsigned().chunk::<2>().collect();
10    ranges.sort_unstable_by_key(|r| r[0]);
11    ranges
12}
13
14pub fn part1(input: &[Range]) -> u64 {
15    let mut index = 0;
16
17    for &[start, end] in input {
18        if index < start {
19            return index;
20        }
21        // Ends are not sorted so only increase.
22        index = index.max(end + 1);
23    }
24
25    unreachable!()
26}
27
28pub fn part2(input: &[Range]) -> u64 {
29    let mut index = 0;
30    let mut total = 0;
31
32    for &[start, end] in input {
33        if index < start {
34            total += start - index;
35        }
36        // Ends are not sorted so only increase.
37        index = index.max(end + 1);
38    }
39
40    total
41}