@@ -47,39 +47,43 @@ pub fn part1(input: &Input) -> u64 {
47
47
pub fn part2 ( input : & Input ) -> u64 {
48
48
let mut current = & mut Vec :: new ( ) ;
49
49
let mut next = & mut Vec :: new ( ) ;
50
+ let next_stage = & mut Vec :: new ( ) ;
50
51
51
52
// Convert input pairs to ranges.
52
53
for [ start, length] in input. seeds . iter ( ) . copied ( ) . chunk :: < 2 > ( ) {
53
54
current. push ( [ start, start + length] ) ;
54
55
}
55
56
56
57
for stage in & input. stages {
57
- ' outer: for & [ s1, e1] in current. iter ( ) {
58
- // Split ranges that overlap into 1, 2 or 3 new ranges.
59
- // Assumes that seed ranges will only overlap with a single range in each stage.
60
- for & [ dest, s2, e2] in stage {
58
+ for & [ dest, s2, e2] in stage {
59
+ while let Some ( [ s1, e1] ) = current. pop ( ) {
60
+ // Split ranges that overlap into 1, 2 or 3 new ranges.
61
61
// x1 and x2 are the possible overlap.
62
62
let x1 = s1. max ( s2) ;
63
63
let x2 = e1. min ( e2) ;
64
64
65
- if x1 < x2 {
65
+ if x1 >= x2 {
66
+ // No overlap.
67
+ next. push ( [ s1, e1] ) ;
68
+ } else {
69
+ // Move overlap to new destination. Only compare with next range.
70
+ next_stage. push ( [ x1 - s2 + dest, x2 - s2 + dest] ) ;
71
+
72
+ // Check remnants with remaining ranges.
66
73
if s1 < x1 {
67
74
next. push ( [ s1, x1] ) ;
68
75
}
69
76
if x2 < e1 {
70
77
next. push ( [ x2, e1] ) ;
71
78
}
72
- // Move overlap to new destination.
73
- next. push ( [ x1 - s2 + dest, x2 - s2 + dest] ) ;
74
- continue ' outer;
75
79
}
76
80
}
77
- // No intersection with any range so pass to next stage unchanged.
78
- next. push ( [ s1 , e1 ] ) ;
81
+
82
+ ( current , next) = ( next , current ) ;
79
83
}
80
84
81
- ( current , next ) = ( next, current ) ;
82
- next . clear ( ) ;
85
+ // Combine elements for the next stage.
86
+ current . append ( next_stage ) ;
83
87
}
84
88
85
89
current. iter ( ) . map ( |r| r[ 0 ] ) . min ( ) . unwrap ( )
0 commit comments