ternary_spreadsheet/
autofill.rs1use crate::cell::TernaryValue;
2use crate::grid::Grid;
3
4#[derive(Debug, Clone)]
6pub struct MutationConfig {
7 pub mutation_rate: f64,
9 pub allow_flip: bool,
11 pub seed: Option<u64>,
13}
14
15impl Default for MutationConfig {
16 fn default() -> Self {
17 MutationConfig {
18 mutation_rate: 0.3,
19 allow_flip: true,
20 seed: None,
21 }
22 }
23}
24
25pub fn autofill_mutate(
29 grid: &mut Grid,
30 src_row: usize,
31 src_col: usize,
32 dst_r1: usize,
33 dst_c1: usize,
34 dst_r2: usize,
35 dst_c2: usize,
36 config: &MutationConfig,
37) -> usize {
38 let source = grid.get(src_row, src_col)
39 .map(|c| c.value)
40 .unwrap_or(TernaryValue::Neutral);
41
42 let (r_min, r_max) = (dst_r1.min(dst_r2), dst_r1.max(dst_r2));
43 let (c_min, c_max) = (dst_c1.min(dst_c2), dst_c1.max(dst_c2));
44
45 let mut mutated = 0usize;
46 let mut counter: u64 = config.seed.unwrap_or(42);
47
48 for r in r_min..=r_max {
49 for c in c_min..=c_max {
50 if r == src_row && c == src_col {
52 continue;
53 }
54
55 counter = counter.wrapping_mul(6364136223846793005).wrapping_add(1);
56 let rand_val = (counter >> 33) as f64 / (1u64 << 31) as f64;
57
58 let new_value = if rand_val < config.mutation_rate {
59 mutated += 1;
60 if config.allow_flip {
61 counter = counter.wrapping_mul(6364136223846793005).wrapping_add(1);
62 let flip_val = (counter >> 33) as u32;
63 TernaryValue::from_seed(flip_val)
64 } else {
65 TernaryValue::Neutral
66 }
67 } else {
68 source
69 };
70
71 if let Some(cell) = grid.get_mut(r, c) {
72 cell.set_value(new_value);
73 }
74 }
75 }
76
77 mutated
78}