#[derive(Debug, PartialEq, Copy, Clone)] pub struct Fish { pub timer: u8, } impl Default for Fish { fn default() -> Fish { Fish::new(8) } } impl Fish { fn tick(&mut self) -> Option { match self.timer { 0 => { self.timer = 6; Some(Fish::default()) } _ => { self.timer -= 1; None } } } fn new(timer: u8) -> Fish { Fish { timer } } } #[derive(Debug, PartialEq, Clone, Default)] pub struct School { pub fishes: Vec, } impl School { pub fn tick(&mut self) { let mut spawned = Vec::new(); for fish in self.fishes.iter_mut() { if let Some(fish) = fish.tick() { spawned.push(fish); } } self.fishes.append(&mut spawned); } pub fn add(&mut self, fish: Fish) { self.fishes.push(fish); } pub fn size(&self) -> usize { self.fishes.len() } } #[derive(Debug, PartialEq, Clone, Default)] pub struct SmartSchool { pub fish_counter: [usize; 9], } impl SmartSchool { pub fn tick(&mut self) { let new_fish = self.fish_counter[0]; for i in 1..self.fish_counter.len() { self.fish_counter[i - 1] = self.fish_counter[i]; } self.fish_counter[8] = new_fish; self.fish_counter[6] += new_fish; } pub fn add(&mut self, fish: Fish) { self.fish_counter[fish.timer as usize] += 1; } pub fn size(&self) -> usize { self.fish_counter.iter().sum() } } impl From<&School> for SmartSchool { fn from(school: &School) -> Self { let mut smart = SmartSchool::default(); for fish in &school.fishes { smart.add(*fish); } smart } } #[cfg(test)] mod test { use super::{Fish, School}; #[test] fn default() { assert_eq!(Fish::default().timer, 8); } #[test] fn spawn() { let mut fish = Fish::default(); for _ in 0..8 { assert_eq!(fish.tick(), None); } assert_eq!(fish.tick(), Some(Fish::default())); assert_eq!(fish.timer, 6); } #[test] fn school_growth() { let mut school = School::default(); school.add(Fish::new(0)); school.add(Fish::new(0)); school.add(Fish::new(0)); assert_eq!(school.size(), 3); school.tick(); assert_eq!(school.size(), 6); } }