#[cfg(test)]
mod tests {
use super::*;
#[test]
fn reset_gears_sets_all_gears_states_back_to_0() {
let mut gears = vec![Gear::new(3), Gear::new(3)];
assert_eq!(0, gears[0].state());
assert_eq!(0, gears[1].state());
gears[0].next();
gears[1].next();
assert_eq!(1, gears[0].state());
assert_eq!(1, gears[1].state());
reset_gears(&mut gears);
assert_eq!(0, gears[0].state());
assert_eq!(0, gears[1].state());
}
#[test]
fn get_gears_states_returns_all_states_in_vector() {
let gears = vec![Gear::new(3), Gear::new(3)];
assert_eq!(vec![0, 0], get_gears_states(&gears));
}
#[test]
fn get_gears_states_returns_all_states_in_vector_after_changing_state() {
let mut gears = vec![Gear::new(3), Gear::new(3)];
gears[0].next();
gears[0].next();
gears[1].next();
assert_eq!(vec![2, 1], get_gears_states(&gears));
}
#[test]
fn get_gears_combinations_returns_vector_of_4_vectors_containing_each_combination() {
let mut gears = vec![Gear::new(2), Gear::new(2)];
let combos = get_gears_combinations(&mut gears);
assert_eq!(4, combos.len());
assert_eq!(vec![vec![0, 0], vec![1, 0], vec![0, 1], vec![1, 1]], combos);
}
#[test]
fn get_gears_combinations_returns_vector_of_9_vectors_containing_each_combination() {
let mut gears = vec![Gear::new(3), Gear::new(3)];
let combos = get_gears_combinations(&mut gears);
assert_eq!(9, combos.len());
assert_eq!(
vec![
vec![0, 0],
vec![1, 0],
vec![2, 0],
vec![0, 1],
vec![1, 1],
vec![2, 1],
vec![0, 2],
vec![1, 2],
vec![2, 2]
],
combos
);
}
#[test]
fn get_gears_combinations_returns_vector_of_12_vectors_containing_each_combination() {
let mut gears = vec![Gear::new(2), Gear::new(2), Gear::new(3)];
let combos = get_gears_combinations(&mut gears);
assert_eq!(12,combos.len());
assert_eq!(
vec![
vec![0, 0, 0],
vec![1, 0, 0],
vec![0, 1, 0],
vec![1, 1, 0],
vec![0, 0, 1],
vec![1, 0, 1],
vec![0, 1, 1],
vec![1, 1, 1],
vec![0, 0, 2],
vec![1, 0, 2],
vec![0, 1, 2],
vec![1, 1, 2]
],
combos
);
}
#[test]
fn get_gears_combinations_returns_vector_of_27_vectors_containing_each_combination() {
let mut gears = vec![Gear::new(3), Gear::new(3), Gear::new(3)];
let combos = get_gears_combinations(&mut gears);
assert_eq!(27, combos.len());
assert_eq!(
vec![
vec![0, 0, 0],
vec![1, 0, 0],
vec![2, 0, 0],
vec![0, 1, 0],
vec![1, 1, 0],
vec![2, 1, 0],
vec![0, 2, 0],
vec![1, 2, 0],
vec![2, 2, 0],
vec![0, 0, 1],
vec![1, 0, 1],
vec![2, 0, 1],
vec![0, 1, 1],
vec![1, 1, 1],
vec![2, 1, 1],
vec![0, 2, 1],
vec![1, 2, 1],
vec![2, 2, 1],
vec![0, 0, 2],
vec![1, 0, 2],
vec![2, 0, 2],
vec![0, 1, 2],
vec![1, 1, 2],
vec![2, 1, 2],
vec![0, 2, 2],
vec![1, 2, 2],
vec![2, 2, 2],
],
combos
);
}
#[test]
fn gear_new_initializes_states() {
let gear = Gear::new(3);
assert!(!std::ptr::eq(&vec![0, 1, 2], gear.states()));
}
#[test]
fn gear_new_sets_state_to_first() {
let gear = Gear::new(3);
assert_eq!(0, gear.state());
}
#[test]
fn gear_next_increments_state_only_to_last_state() {
let mut gear = Gear::new(3);
assert_eq!(0, gear.state());
gear.next();
assert_eq!(1, gear.state());
gear.next();
assert_eq!(2, gear.state());
gear.next();
assert_eq!(2, gear.state());
}
#[test]
fn gear_next_increments_state_returning_true_then_false_at_last_state() {
let mut gear = Gear::new(3);
assert_eq!(0, gear.state());
assert!(gear.next());
assert_eq!(1, gear.state());
assert!(gear.next());
assert_eq!(2, gear.state());
assert!(!gear.next());
assert_eq!(2, gear.state());
}
#[test]
fn gear_next_increments_state_returning_true_then_false_at_last_state_until_reset() {
let mut gear = Gear::new(3);
assert_eq!(0, gear.state());
assert!(gear.next());
assert_eq!(1, gear.state());
assert!(gear.next());
assert_eq!(2, gear.state());
assert!(!gear.next());
assert_eq!(2, gear.state());
gear.reset();
assert_eq!(0, gear.state());
assert!(gear.next());
}
#[test]
fn gear_reset_sets_state_to_first() {
let mut gear = Gear::new(3);
assert_eq!(0, gear.state());
gear.next();
assert_eq!(1, gear.state());
gear.next();
assert_eq!(2, gear.state());
gear.next();
assert_eq!(2, gear.state());
gear.reset();
assert_eq!(0, gear.state());
}
#[test]
fn gear_end_returns_true_when_at_last_state() {
let mut gear = Gear::new(2);
assert!(!gear.end());
assert!(gear.next());
assert!(gear.end());
}
#[test]
fn gear_cycle_goes_through_all_states_and_back() {
let mut gear = Gear::new(2);
assert_eq!(0, gear.state());
assert!(gear.cycle());
assert_eq!(1, gear.state());
assert!(!gear.cycle());
assert_eq!(0, gear.state());
assert!(gear.cycle());
assert_eq!(1, gear.state());
}
}
pub struct Gear {
states: Vec<i32>,
state: usize,
}
impl Gear {
pub fn new(size: usize) -> Gear {
let mut s: Vec<i32> = Vec::with_capacity(size);
for i in 0..size {
s.push(i as i32);
}
Gear {
states: s,
state: 0,
}
}
pub fn next(&mut self) -> bool {
if self.end() {
false
} else {
self.state += 1;
true
}
}
pub fn cycle(&mut self) -> bool {
if self.next() {
true
} else {
self.reset();
false
}
}
pub fn end(&self) -> bool {
self.state == self.states.len() - 1
}
pub fn reset(&mut self) {
self.state = 0;
}
pub fn states(&self) -> &Vec<i32> {
&self.states
}
pub fn state(&self) -> i32 {
self.states[self.state]
}
}
pub fn reset_gears(gears: &mut Vec<Gear>) {
for gear in gears {
gear.reset();
}
}
pub fn get_gears_states(gears: &Vec<Gear>) -> Vec<i32> {
gears.iter().map(|g| g.state()).collect()
}
pub fn get_gears_combinations(gears: &mut Vec<Gear>) -> Vec<Vec<i32>> {
let mut combos: Vec<Vec<i32>> = Vec::with_capacity(gears.len());
let mut finished = false;
let last_index = gears.len() - 1;
reset_gears(gears);
combos.push(get_gears_states(gears));
while !finished {
if !gears[0].cycle() {
for (i, gear) in gears.iter_mut().enumerate() {
if i == 0 {
continue;
}
if !gear.cycle() {
if i == last_index {
finished = true;
break;
}
} else {
break;
}
}
}
if !finished {
combos.push(get_gears_states(gears));
}
}
combos
}