@@ -38,10 +38,49 @@ pub fn react(polymer: &str) -> String {
3838 result
3939}
4040
41+ pub fn react_2 ( polymer : & str ) -> String {
42+ let mut result = polymer. to_owned ( ) ;
43+ let mut changed = true ;
44+
45+ while changed {
46+ changed = false ;
47+
48+ let chars_count = result. chars ( ) . count ( ) ;
49+
50+ let mut new_result = "" . to_owned ( ) ;
51+ let mut i = 0 ;
52+
53+ while i < chars_count {
54+ if i < chars_count - 1
55+ && should_react (
56+ result[ i..=i] . chars ( ) . next ( ) . unwrap ( ) ,
57+ result[ i + 1 ..=i + 1 ] . chars ( ) . next ( ) . unwrap ( ) ,
58+ )
59+ {
60+ changed = true ;
61+ i += 2 ;
62+ } else {
63+ new_result. push_str ( & result[ i..=i] ) ;
64+ i += 1 ;
65+ }
66+ }
67+ result = new_result;
68+ }
69+ result
70+ }
71+
72+ // react_3: use vector of chars all the way?
73+
4174fn remove_units ( polymer : & str , c : char ) -> String {
4275 polymer. replace ( [ c, switch_case ( c) ] , "" )
4376}
4477
78+ fn should_react ( a : char , b : char ) -> bool {
79+ a. to_ascii_lowercase ( ) == b. to_ascii_lowercase ( )
80+ && ( ( a. is_ascii_lowercase ( ) && b. is_ascii_uppercase ( ) )
81+ || ( a. is_ascii_uppercase ( ) && b. is_ascii_lowercase ( ) ) )
82+ }
83+
4584fn switch_case ( c : char ) -> char {
4685 if c. is_ascii_uppercase ( ) {
4786 c. to_ascii_lowercase ( )
@@ -68,6 +107,19 @@ mod tests {
68107 assert_eq ! ( react( "dabAcCaCBAcCcaDA" ) , "dabCBAcaDA" ) ;
69108 }
70109
110+ #[ test]
111+ fn react_2_examples ( ) {
112+ assert_eq ! ( react_2( "aA" ) , "" ) ;
113+ assert_eq ! ( react_2( "abBA" ) , "" ) ;
114+ assert_eq ! ( react_2( "abAB" ) , "abAB" ) ;
115+ assert_eq ! ( react_2( "aabAAB" ) , "aabAAB" ) ;
116+ }
117+
118+ #[ test]
119+ fn react_2_larger_example ( ) {
120+ assert_eq ! ( react_2( "dabAcCaCBAcCcaDA" ) , "dabCBAcaDA" ) ;
121+ }
122+
71123 #[ test]
72124 fn part_2_examples ( ) {
73125 assert_eq ! ( remove_units( "dabAcCaCBAcCcaDA" , 'a' ) , "dbcCCBcCcD" ) ;
0 commit comments