use itertools::Itertools; use std::fs::File; use std::io::{BufRead, BufReader, Lines}; // BOILERPLATE type InputIter = Lines>; fn get_input() -> InputIter { let f = File::open("input").unwrap(); let br = BufReader::new(f); br.lines() } fn main() { println!("Problem 1 solution: {}", problem1(get_input())); println!("Problem 2 solution: {}", problem2(get_input())); } // PARSE #[derive(Debug)] struct SpringRow { springs: Vec, spans: Vec, } impl From<&str> for SpringRow { fn from(s: &str) -> Self { let (springs_s, spans_s) = s.split_once(' ').unwrap(); SpringRow { springs: springs_s.chars().collect(), spans: spans_s.split(',').map(|x| x.parse().unwrap()).collect(), } } } impl SpringRow { fn possible_arrangements(&self) -> u64 { let mut permutations = vec![self.springs.clone()]; while let Some(cur) = permutations.iter().position(|perm| perm.contains(&'?')) { let perm = permutations.remove(cur); let rep_pos = perm.iter().position(|c| *c == '?').unwrap(); let mut new_elem = perm.clone(); new_elem[rep_pos] = '.'; permutations.push(new_elem.clone()); new_elem[rep_pos] = '#'; permutations.push(new_elem); } permutations .iter() .filter_map(|perm| { let groups: Vec = perm .iter() .group_by(|c| **c == '#') .into_iter() .filter_map(|(key, group)| if key { Some(group.count()) } else { None }) .collect(); if groups == self.spans { Some(()) } else { None } }) .count() as u64 } } // PROBLEM 1 solution fn problem1(input: Lines) -> u64 { let rows: Vec = input .map(|row| SpringRow::from(row.unwrap().as_str())) .collect(); rows.iter().map(|row| row.possible_arrangements()).sum() } // PROBLEM 2 solution fn problem2(input: Lines) -> u64 { 0 } #[cfg(test)] mod tests { use crate::*; use std::io::Cursor; const EXAMPLE: &str = &"???.### 1,1,3 .??..??...?##. 1,1,3 ?#?#?#?#?#?#?#? 1,3,1,6 ????.#...#... 4,1,1 ????.######..#####. 1,6,5 ?###???????? 3,2,1"; #[test] fn problem1_example() { let c = Cursor::new(EXAMPLE); assert_eq!(problem1(c.lines()), 21); } #[test] fn problem2_example() { let c = Cursor::new(EXAMPLE); assert_eq!(problem2(c.lines()), 0); } }