diff --git a/src/bin/day12.rs b/src/bin/day12.rs index 1302f95..2e11548 100644 --- a/src/bin/day12.rs +++ b/src/bin/day12.rs @@ -30,11 +30,7 @@ impl FromStr for Row { } #[memoize] -fn arrangements( - mut map: VecDeque, - mut damaged: VecDeque, - mut in_damaged: bool, -) -> usize { +fn arrangements(map: VecDeque, damaged: VecDeque, in_damaged: bool) -> usize { // all damaged have been placed if damaged.is_empty() { return if map.iter().all(|&c| c == '.' || c == '?') { @@ -44,6 +40,10 @@ fn arrangements( }; } + let mut map = map.clone(); + let mut damaged = damaged.clone(); + let mut in_damaged = in_damaged; + // skip the functional while let Some('.') = map.front() { if in_damaged { @@ -60,43 +60,38 @@ fn arrangements( match map[0] { '?' => { - map[0] = '#'; - let as_non_functional = arrangements(map.clone(), damaged.clone(), true); - map[0] = '.'; let as_functional = if !in_damaged { - arrangements(map, damaged, false) + arrangements(map.clone(), damaged.clone(), false) } else { 0 }; + map[0] = '#'; + let as_non_functional = arrangements(map, damaged, true); + as_functional + as_non_functional } '#' if damaged.is_empty() => 0, '#' => { damaged[0] -= 1; + map.pop_front(); + if damaged[0] == 0 { - if 1 < map.len() && map[1] == '#' { + damaged.pop_front(); + + if let Some(&'#') = map.front() { 0 - } else if 1 < map.len() { - map[1] = '.'; - arrangements( - map.iter().cloned().skip(1).collect(), - damaged.iter().cloned().skip(1).collect(), - false, - ) + } else if !map.is_empty() { + map[0] = '.'; + arrangements(map, damaged, false) } else { - let result = arrangements( - map.iter().cloned().skip(2).collect(), - damaged.iter().cloned().skip(1).collect(), - false, - ); - result + map.pop_front(); + arrangements(map, damaged, false) } } else { - let result = arrangements(map.iter().cloned().skip(1).collect(), damaged, true); - result + arrangements(map, damaged, true) } } _ => unreachable!(),