research-arrays.rs
2.5 kB · rust · 88 lines
1use figures::board::Frame;2use figures::{ink, save, Board, Grid};3use mrlyrs::core::error::Result;4use std::collections::HashSet;56const G: [i64; 4] = [0, 1, 2, 4];7const ORDER: u32 = 4;8const PX: f64 = 20.0;910fn coarray(s: &[i64]) -> HashSet<i64> {11 s.iter()12 .flat_map(|x| s.iter().map(move |y| x - y))13 .collect()14}1516fn paired(g: &[i64]) -> Vec<i64> {17 g.iter()18 .copied()19 .filter(|&x| {20 g.iter().any(|&y| {21 y != x22 && g.iter()23 .flat_map(|p| g.iter().map(move |q| p - q))24 .filter(|&d| d == x - y)25 .count()26 == 127 })28 })29 .collect()30}3132fn main() -> Result<()> {33 let a = *G.iter().max().unwrap();34 let base = 2 * a + 1;35 assert_eq!(coarray(&G).len() as i64, base);36 let digits: Vec<Vec<i64>> = (0..G.len().pow(ORDER))37 .map(|mut k| {38 (0..ORDER)39 .map(|_| {40 let d = G[k % G.len()];41 k /= G.len();42 d43 })44 .collect()45 })46 .collect();47 let sensors: Vec<i64> = digits48 .iter()49 .map(|d| d.iter().rev().fold(0, |acc, &x| acc * base + x))50 .collect();51 let full = coarray(&sensors);52 assert_eq!(full.len() as i64, base.pow(ORDER));53 let essential: Vec<bool> = sensors54 .iter()55 .map(|&s| {56 let rest: Vec<i64> = sensors.iter().copied().filter(|&x| x != s).collect();57 coarray(&rest) != full58 })59 .collect();60 let u = paired(&G);61 assert_eq!(u, vec![0, 1, 4]);62 for (d, &e) in digits.iter().zip(&essential) {63 assert_eq!(e, d.iter().all(|x| u.contains(x)));64 }65 assert_eq!(essential.iter().filter(|&&e| e).count(), u.len().pow(ORDER));66 let side = (a + base * a + 1) as usize;67 let mut board = Board::square();68 let edge = side as f64 * PX;69 let area = Frame::new(70 ((board.width as f64 - edge) / 2.0).round(),71 ((board.height as f64 - edge) / 2.0).round(),72 edge,73 edge,74 );75 let grid = Grid::new(area, side, side, 0.16);76 for (d, &e) in digits.iter().zip(&essential) {77 let col = (d[0] + base * d[2]) as usize;78 let row = side - 1 - (d[1] + base * d[3]) as usize;79 grid.fill(80 &mut board,81 col,82 row,83 if e { ink::orange() } else { ink::blue() },84 );85 }86 save("research-arrays", &board)?;87 Ok(())88}