11use crate :: solutions:: Solution ;
2+ use crate :: utils:: range:: Range ;
23use itertools:: Itertools ;
4+ use std:: collections:: VecDeque ;
35use std:: ops:: RangeInclusive ;
46
57pub struct Day05 ;
@@ -15,14 +17,9 @@ impl Solution for Day05 {
1517 }
1618
1719 fn part_two ( & self , input : & str ) -> String {
18- let ( ranges, _ ) = self . parse ( input) ;
20+ let ranges = self . parse_ranges ( input) ;
1921
20- ranges
21- . iter ( )
22- . flat_map ( |range| range. clone ( ) )
23- . unique ( )
24- . count ( )
25- . to_string ( )
22+ self . unique_ids ( ranges. into_iter ( ) ) . to_string ( )
2623 }
2724}
2825
@@ -49,12 +46,59 @@ impl Day05 {
4946
5047 ( ranges, ids)
5148 }
49+
50+ fn parse_ranges ( & self , input : & str ) -> Vec < Range > {
51+ let ( ranges_str, _) = input. split_once ( "\n \n " ) . unwrap ( ) ;
52+
53+ ranges_str
54+ . lines ( )
55+ . map ( |line| {
56+ let ( start, end) = line. split_once ( "-" ) . unwrap ( ) ;
57+
58+ let start = start. parse :: < isize > ( ) . unwrap ( ) ;
59+ let end = end. parse :: < isize > ( ) . unwrap ( ) ;
60+
61+ Range :: new ( start, end) . unwrap ( )
62+ } )
63+ . collect_vec ( )
64+ }
65+
66+ fn unique_ids ( & self , ranges : impl Iterator < Item = Range > ) -> isize {
67+ let mut queue = VecDeque :: from_iter ( ranges) ;
68+ let mut result: Vec < Range > = Vec :: new ( ) ;
69+
70+ while let Some ( range) = queue. pop_front ( ) {
71+ result. push ( range) ;
72+ // println!(" ==== {} ==== ", range);
73+
74+ for ( k, other) in queue. clone ( ) . iter ( ) . enumerate ( ) {
75+ if range. collide ( other) {
76+ queue. remove ( k) ;
77+
78+ let intersect = range. intersect ( other) . unwrap ( ) ;
79+ let lefts = other. diff ( & intersect) ;
80+
81+ // println!("{} collide: {} - {:?}", range, other, lefts);
82+
83+ for left in lefts {
84+ queue. push_back ( left) ;
85+ }
86+ }
87+ }
88+ }
89+
90+ // println!("{:?}", result);
91+
92+ result. iter ( ) . map ( |range| range. len ( ) ) . sum :: < isize > ( )
93+ }
5294}
5395
5496#[ cfg( test) ]
5597mod tests {
5698 use crate :: solutions:: year2025:: day05:: Day05 ;
5799 use crate :: solutions:: Solution ;
100+ use crate :: utils:: range:: Range ;
101+ use std:: ops:: RangeInclusive ;
58102
59103 const EXAMPLE : & str = r#"3-5
6010410-14
@@ -77,4 +121,18 @@ mod tests {
77121 fn part_two_example_test ( ) {
78122 assert_eq ! ( "14" , Day05 . part_two( EXAMPLE ) ) ;
79123 }
124+
125+ #[ test]
126+ fn unique_ids ( ) {
127+ assert_eq ! ( 8 , run_unique_ids( vec![ 3 ..=5 , 10 ..=14 ] ) ) ;
128+ assert_eq ! ( 5 , run_unique_ids( vec![ 3 ..=5 , 1 ..=4 ] ) ) ;
129+ assert_eq ! ( 6 , run_unique_ids( vec![ 3 ..=7 , 6 ..=8 ] ) ) ;
130+ assert_eq ! ( 7 , run_unique_ids( vec![ 3 ..=7 , 2 ..=8 ] ) ) ;
131+ }
132+
133+ fn run_unique_ids ( vec : Vec < RangeInclusive < isize > > ) -> isize {
134+ let ranges = vec. into_iter ( ) . map ( Range :: from) ;
135+
136+ Day05 . unique_ids ( ranges)
137+ }
80138}
0 commit comments