RosettaCodeData/Task/Nonoblock/Rust/nonoblock.rust

80 lines
2.1 KiB
Plaintext

struct Nonoblock {
width: usize,
config: Vec<usize>,
spaces: Vec<usize>,
}
impl Nonoblock {
pub fn new(width: usize, config: Vec<usize>) -> Nonoblock {
Nonoblock {
width: width,
config: config,
spaces: Vec::new(),
}
}
pub fn solve(&mut self) -> Vec<Vec<i32>> {
let mut output: Vec<Vec<i32>> = 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::<usize>() + self.config.iter().sum::<usize>() <= 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::<usize>() + self.config.iter().sum::<usize>() > 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!();
}
}