1- use std:: { mem , ops:: RangeInclusive } ;
1+ use std:: ops:: RangeInclusive ;
22
33use common:: { Answer , solution} ;
44
55solution ! ( "Cafeteria" , 5 ) ;
66
7- type Range = RangeInclusive < u64 > ;
8-
97fn part_a ( input : & str ) -> Answer {
108 let ( ranges, nums) = parse ( input) ;
11- let count = nums. iter ( ) . filter ( |x| ranges. contains ( x) ) . count ( ) ;
12- count. into ( )
9+ nums. iter ( )
10+ . filter ( |n| ranges. iter ( ) . any ( |r| r. contains ( n) ) )
11+ . count ( )
12+ . into ( )
1313}
1414
1515fn part_b ( input : & str ) -> Answer {
16- let ( ranges, _) = parse ( input) ;
17- ranges. count ( ) . into ( )
16+ let ( mut ranges, _) = parse ( input) ;
17+ ranges. sort_by_key ( |x| * x. start ( ) ) ;
18+
19+ let ( mut out, mut max) = ( 0 , 0 ) ;
20+ for range in ranges {
21+ let ( start, end) = ( * range. start ( ) . max ( & max) , range. end ( ) + 1 ) ;
22+ out += end. saturating_sub ( start) ;
23+ max = max. max ( end) ;
24+ }
25+
26+ out. into ( )
1827}
1928
20- fn parse ( input : & str ) -> ( Ranges , Vec < u64 > ) {
29+ fn parse ( input : & str ) -> ( Vec < RangeInclusive < u64 > > , Vec < u64 > ) {
2130 let ( ranges, nums) = input. split_once ( "\n \n " ) . unwrap ( ) ;
2231
2332 let ranges = ( ranges. lines ( ) )
@@ -26,56 +35,11 @@ fn parse(input: &str) -> (Ranges, Vec<u64>) {
2635 first. parse ( ) . unwrap ( ) ..=last. parse ( ) . unwrap ( )
2736 } )
2837 . collect ( ) ;
29-
3038 let nums = nums. lines ( ) . map ( |x| x. parse ( ) . unwrap ( ) ) . collect ( ) ;
3139
3240 ( ranges, nums)
3341}
3442
35- #[ derive( Default , Debug ) ]
36- struct Ranges {
37- inner : Vec < Range > ,
38- }
39-
40- impl Ranges {
41- fn add ( & mut self , mut new : RangeInclusive < u64 > ) {
42- fn range_combine ( a : & Range , b : & Range ) -> Option < Range > {
43- ( a. start ( ) <= b. start ( ) && a. end ( ) >= b. start ( )
44- || b. start ( ) <= a. start ( ) && b. end ( ) >= a. start ( ) )
45- . then ( || ( * a. start ( ) . min ( b. start ( ) ) ) ..=( * a. end ( ) . max ( b. end ( ) ) ) )
46- }
47-
48- let mut i = 0 ;
49- while i < self . inner . len ( ) {
50- if let Some ( combination) = range_combine ( & self . inner [ i] , & new) {
51- self . inner . remove ( mem:: take ( & mut i) ) ;
52- new = combination;
53- continue ;
54- }
55-
56- i += 1 ;
57- }
58-
59- self . inner . push ( new) ;
60- }
61-
62- fn contains ( & self , val : & u64 ) -> bool {
63- self . inner . iter ( ) . any ( |x| x. contains ( val) )
64- }
65-
66- fn count ( & self ) -> u64 {
67- self . inner . iter ( ) . map ( |x| x. end ( ) - x. start ( ) + 1 ) . sum ( )
68- }
69- }
70-
71- impl FromIterator < Range > for Ranges {
72- fn from_iter < T : IntoIterator < Item = Range > > ( iter : T ) -> Self {
73- let mut out = Ranges :: default ( ) ;
74- iter. into_iter ( ) . for_each ( |item| out. add ( item) ) ;
75- out
76- }
77- }
78-
7943#[ cfg( test) ]
8044mod test {
8145 use indoc:: indoc;
0 commit comments