@@ -8,12 +8,10 @@ pub fn parse_input(input: &str) -> Input {
88 let mut fresh_ranges = vec ! [ ] ;
99 let mut ingredients = vec ! [ ] ;
1010
11- for line in input. lines ( ) . filter ( |& line| line. len ( ) > 0 ) {
12- if let Some ( hyphen) = line. find ( |c| c == '-' ) {
13- fresh_ranges. push ( (
14- line[ 0 ..hyphen] . parse ( ) . unwrap ( ) ,
15- line[ ( hyphen + 1 ) ..] . parse ( ) . unwrap ( ) ,
16- ) ) ;
11+ for line in input. lines ( ) . filter ( |& line| !line. is_empty ( ) ) {
12+ if let Some ( hyphen) = line. find ( '-' ) {
13+ let range = line. split_at ( hyphen) ;
14+ fresh_ranges. push ( ( range. 0 . parse ( ) . unwrap ( ) , ( range. 1 [ 1 ..] ) . parse ( ) . unwrap ( ) ) ) ;
1715 } else {
1816 ingredients. push ( line. parse ( ) . unwrap ( ) ) ;
1917 }
@@ -38,8 +36,45 @@ pub fn part1(input: &Input) -> usize {
3836 . count ( )
3937}
4038
41- pub fn part2 ( input : & Input ) -> & str {
42- "unimplemented"
39+ pub fn part2 ( input : & Input ) -> u64 {
40+ let ranges = & input. fresh_ranges ;
41+ // track an array of unfresh regions an ranges starting with all integers and split as fresh ranges known
42+ // i don't know why but i thought this would be easier than tracking fresh explicitly?
43+ let mut unfresh: Vec < ( u64 , u64 ) > = vec ! [ ( 0 , u64 :: MAX ) ] ;
44+ for & ( low, high) in ranges {
45+ unfresh = unfresh
46+ . into_iter ( )
47+ . flat_map ( |( start, end) | {
48+ if low < start {
49+ if high > end {
50+ vec ! [ ]
51+ } else if high >= start {
52+ vec ! [ ( high + 1 , end) ]
53+ } else {
54+ vec ! [ ( start, end) ]
55+ }
56+ } else if low == start {
57+ if high < end {
58+ vec ! [ ( high + 1 , end) ]
59+ } else {
60+ vec ! [ ]
61+ }
62+ } else if low < end {
63+ if high < end {
64+ vec ! [ ( start, low - 1 ) , ( high + 1 , end) ]
65+ } else {
66+ vec ! [ ( start, low - 1 ) ]
67+ }
68+ } else if low == end {
69+ vec ! [ ( start, low - 1 ) ]
70+ } else {
71+ vec ! [ ( start, end) ]
72+ }
73+ } )
74+ . collect ( ) ;
75+ }
76+
77+ u64:: MAX - unfresh. iter ( ) . map ( |r| r. 1 - r. 0 + 1 ) . sum :: < u64 > ( ) + 1
4378}
4479
4580#[ test]
@@ -59,4 +94,5 @@ fn test() {
5994" ;
6095 let input = parse_input ( test_input) ;
6196 assert_eq ! ( 3 , part1( & input) ) ;
97+ assert_eq ! ( 14 , part2( & input) ) ;
6298}
0 commit comments