use crate::config::*; use crate::corpus::*; use crate::layout::*; use crate::output::*; use std::fmt; pub fn prelayout_fitness(corpus: &Corpus, layout: &Prelayout) -> u32 { let mut score: u32 = 0; for i in 0..6 { let keys = layout.get_standard_column(i); let k1 = keys[0]; let k2 = keys[1]; let k3 = keys[2]; score += corpus.get_bigram_count(k1, k2) + corpus.get_bigram_count(k1, k3) + corpus.get_bigram_count(k2, k3); } for i in 0..2 { let keys = layout.get_index_column(i); let k1 = keys[0]; let k2 = keys[1]; let k3 = keys[2]; let k4 = keys[3]; let k5 = keys[4]; let k6 = keys[5]; // We want index usage! let index_count: u32 = keys.iter().map(|&k| corpus.get_character_count(k)).sum(); score += index_usage_fitness(corpus.get_index_threshold(), index_count); score += corpus.get_bigram_count(k1, k2) + corpus.get_bigram_count(k1, k3) + corpus.get_bigram_count(k2, k3) + corpus.get_bigram_count(k4, k5) + corpus.get_bigram_count(k4, k6) + corpus.get_bigram_count(k5, k6) + corpus.get_bigram_count(k1, k4) + corpus.get_bigram_count(k1, k5) + corpus.get_bigram_count(k1, k6) + corpus.get_bigram_count(k2, k4) + corpus.get_bigram_count(k2, k5) + corpus.get_bigram_count(k2, k6) + corpus.get_bigram_count(k3, k4) + corpus.get_bigram_count(k3, k5) + corpus.get_bigram_count(k3, k6); } score } #[derive(Copy, Clone)] pub struct Evaluation { keypress: [u32; NUM_KEYS], total_keypress: u32, sfb: [u32; 8], } impl Evaluation { pub fn evaluate_layout(corpus: &Corpus, layout: &Layout) -> Evaluation { let mut keypress: [u32; NUM_KEYS] = [0; NUM_KEYS]; let mut sfb: [u32; 8] = [0; 8]; for (i, &c) in layout.get_keys().iter().enumerate() { keypress[i] = corpus.get_character_count(c); } for i in 0..8 { let ind = if i < 4 { i } else { i + 2 }; let k1 = layout.get_key(ind + 10 * 0); let k2 = layout.get_key(ind + 10 * 1); let k3 = layout.get_key(ind + 10 * 2); sfb[i] = corpus.get_bigram_count(k1, k2) + corpus.get_bigram_count(k1, k3) + corpus.get_bigram_count(k2, k3); if i == 3 { let k4 = layout.get_key(4 + 10 * 0); let k5 = layout.get_key(4 + 10 * 1); let k6 = layout.get_key(4 + 10 * 2); sfb[i] += corpus.get_bigram_count(k4, k5) + corpus.get_bigram_count(k4, k6) + corpus.get_bigram_count(k5, k6) + corpus.get_bigram_count(k1, k4) + corpus.get_bigram_count(k1, k5) + corpus.get_bigram_count(k1, k6) + corpus.get_bigram_count(k2, k4) + corpus.get_bigram_count(k2, k5) + corpus.get_bigram_count(k2, k6) + corpus.get_bigram_count(k3, k4) + corpus.get_bigram_count(k3, k5) + corpus.get_bigram_count(k3, k6); } else if i == 4 { let k4 = layout.get_key(5 + 10 * 0); let k5 = layout.get_key(5 + 10 * 1); let k6 = layout.get_key(5 + 10 * 2); sfb[i] += corpus.get_bigram_count(k4, k5) + corpus.get_bigram_count(k5, k6) + corpus.get_bigram_count(k4, k6) + corpus.get_bigram_count(k1, k4) + corpus.get_bigram_count(k1, k5) + corpus.get_bigram_count(k1, k6) + corpus.get_bigram_count(k2, k4) + corpus.get_bigram_count(k2, k5) + corpus.get_bigram_count(k2, k6) + corpus.get_bigram_count(k3, k4) + corpus.get_bigram_count(k3, k5) + corpus.get_bigram_count(k3, k6); } } return Evaluation { keypress, total_keypress: corpus.get_total_count(), sfb, }; } fn output_eval(&self) -> String { let mut result = String::new(); let tot = self.total_keypress as f32; result += &"Percent per key:\n"; result += &format_block_output(self.keypress.into_iter().map(|k| 100.0 * k as f32 / tot)); let mut finger_usages = [0; 8]; for (i, &c) in self.keypress.iter().enumerate() { finger_usages[KEY_TO_FINGER[i]] += c; } result += "\nFinger usage: "; let mut lh: f32 = 0.0; let mut rh: f32 = 0.0; for (i, &u) in finger_usages.iter().enumerate() { let f = u as f32 / tot * 100.0; result += &format!("{:>5.2}%{}", f, if i < 7 { ", " } else { "" }); if i % 10 < 4 { lh += f; } else { rh += f; } } result += &format!("\nHand usage: {:.2}% vs {:.2}%", lh, rh); result += "\nSame finger bigrams: "; for (i, &u) in self.sfb.iter().enumerate() { result += &format!( "{:>6.3}%{}", u as f32 / tot * 100.0, if i < 7 { ", " } else { "" } ); } let sfb = self.sfb.iter().sum::(); result += &format!("\nTotal sfb: {:.2}% ({})", sfb as f32 / tot * 100.0, sfb); return result; } } impl fmt::Display for Evaluation { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str(&self.output_eval()) } }