rules.rs
2.3 kB · rust · 90 lines
1pub const RULES: usize = 256;23pub fn output(rule: usize, l: u8, c: u8, r: u8) -> u8 {4 ((rule >> (4 * l as usize + 2 * c as usize + r as usize)) & 1) as u85}67pub struct Diagram {8 pub steps: usize,9 pub width: usize,10 pub cells: Vec<u8>,11}1213impl Diagram {14 pub fn at(&self, t: usize, i: usize) -> u8 {15 self.cells[t * self.width + i]16 }17 pub fn centre(&self) -> usize {18 self.width / 219 }20 pub fn signed(&self, t: usize, offset: i64) -> u8 {21 let i = self.centre() as i64 + offset;22 if i < 0 || i >= self.width as i64 {23 024 } else {25 self.at(t, i as usize)26 }27 }28}2930pub fn evolve(rule: usize, steps: usize, pad: usize) -> (Diagram, u8) {31 let window = 2 * steps + 1;32 let width = window + 2 * pad;33 let mut cells = vec![0u8; (steps + 1) * width];34 cells[width / 2] = 1;35 let mut seen = 0u8;36 for t in 0..steps {37 for i in 0..width {38 let l = if i == 0 { 0 } else { cells[t * width + i - 1] };39 let c = cells[t * width + i];40 let r = if i + 1 == width {41 042 } else {43 cells[t * width + i + 1]44 };45 seen |= 1 << (4 * l + 2 * c + r);46 cells[(t + 1) * width + i] = output(rule, l, c, r);47 }48 }49 for i in 0..width {50 let l = if i == 0 {51 052 } else {53 cells[steps * width + i - 1]54 };55 let c = cells[steps * width + i];56 let r = if i + 1 == width {57 058 } else {59 cells[steps * width + i + 1]60 };61 seen |= 1 << (4 * l + 2 * c + r);62 }63 let mut cropped = vec![0u8; (steps + 1) * window];64 for t in 0..=steps {65 cropped[t * window..(t + 1) * window]66 .copy_from_slice(&cells[t * width + pad..t * width + pad + window]);67 }68 (69 Diagram {70 steps,71 width: window,72 cells: cropped,73 },74 seen,75 )76}7778pub fn single_seed(rule: usize, steps: usize) -> Diagram {79 evolve(rule, steps, steps).080}8182pub fn mirrored(diagram: &Diagram) -> Vec<u8> {83 let mut out = vec![0u8; diagram.cells.len()];84 for t in 0..=diagram.steps {85 for i in 0..diagram.width {86 out[t * diagram.width + i] = diagram.at(t, diagram.width - 1 - i);87 }88 }89 out90}