struct Nonoblock { width: usize, config: Vec, spaces: Vec, } impl Nonoblock { pub fn new(width: usize, config: Vec) -> Nonoblock { Nonoblock { width: width, config: config, spaces: Vec::new(), } } pub fn solve(&mut self) -> Vec> { let mut output: Vec> = Vec::new(); self.spaces = (0..self.config.len()).fold(Vec::new(), |mut s, i| { s.push(match i { 0 => 0, _ => 1, }); s }); if self.spaces.iter().sum::() + self.config.iter().sum::() <= self.width { 'finished: loop { match self.spaces.iter().enumerate().fold((0, vec![0; self.width]), |mut a, (i, s)| { (0..self.config[i]).for_each(|j| a.1[a.0 + j + *s] = 1 + i as i32); return (a.0 + self.config[i] + *s, a.1); }) { (_, out) => output.push(out), } let mut i: usize = 1; 'calc: loop { let len = self.spaces.len(); if i > len { break 'finished; } else { self.spaces[len - i] += 1 } if self.spaces.iter().sum::() + self.config.iter().sum::() > self.width { self.spaces[len - i] = 1; i += 1; } else { break 'calc; } } } } output } } fn main() { let mut blocks = [ Nonoblock::new(5, vec![2, 1]), Nonoblock::new(5, vec![]), Nonoblock::new(10, vec![8]), Nonoblock::new(15, vec![2, 3, 2, 3]), Nonoblock::new(5, vec![2, 3]), ]; for block in blocks.iter_mut() { println!("{} cells and {:?} blocks", block.width, block.config); println!("{}",(0..block.width).fold(String::from("="), |a, _| a + "==")); let solutions = block.solve(); if solutions.len() > 0 { for solution in solutions.iter() { println!("{}", solution.iter().fold(String::from("|"), |s, f| s + &match f { i if *i > 0 => (('A' as u8 + ((*i - 1) as u8) % 26) as char).to_string(), _ => String::from("_"), }+ "|")); } } else { println!("No solutions. "); } println!(); } }