[klout] .

This commit is contained in:
soup 2024-12-21 18:03:12 -05:00
parent eb0ef2c4b2
commit 73d86358d5
Signed by: soup
SSH key fingerprint: SHA256:GYxje8eQkJ6HZKzVWDdyOUF1TyDiprruGhE0Ym8qYDY
5 changed files with 234 additions and 27 deletions

View file

@ -25,11 +25,11 @@
"locked": {
"lastModified": 1,
"narHash": "sha256-PVtFcvxh3Aqgel46BBFzxN0IvEVDzw/n/hWJ76mVThQ=",
"path": "/nix/store/0d80mkh7c7904wghfbvy3rpd395lriny-source/nix/deno-flake",
"path": "./nix/deno-flake",
"type": "path"
},
"original": {
"path": "/nix/store/0d80mkh7c7904wghfbvy3rpd395lriny-source/nix/deno-flake",
"path": "./nix/deno-flake",
"type": "path"
}
},

View file

@ -2,7 +2,7 @@
inputs.nixpkgs.url = "nixpkgs";
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.deno-flake = {
url = "./nix/deno-flake";
url = "path:./nix/deno-flake";
inputs.nixpkgs.follows = "nixpkgs";
};
inputs.fenix = {

131
klout/Cargo.lock generated
View file

@ -2,6 +2,18 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "eyre"
version = "0.6.12"
@ -12,6 +24,17 @@ dependencies = [
"once_cell",
]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "indenter"
version = "0.3.3"
@ -23,10 +46,118 @@ name = "klout"
version = "0.0.0"
dependencies = [
"eyre",
"rand",
]
[[package]]
name = "libc"
version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "once_cell"
version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "ppv-lite86"
version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [
"zerocopy",
]
[[package]]
name = "proc-macro2"
version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "syn"
version = "2.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"byteorder",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View file

@ -4,4 +4,5 @@ version = "0.0.0"
edition = "2024"
[dependencies]
eyre = "0.6.12"
eyre = "0.6.12"
rand = "0.8.5"

View file

@ -1,12 +1,19 @@
use std::collections::HashMap;
use core::f64;
use eyre::Result;
use rand::rngs::ThreadRng;
use std::{
collections::HashMap,
io::{self, Write},
sync::mpsc::{Receiver, Sender},
};
#[derive(Copy, Clone, Eq, PartialEq)]
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
enum Hand {
Left,
Right,
}
#[derive(Copy, Clone, Eq, PartialEq)]
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
enum Digit {
Pinky,
Ring,
@ -14,7 +21,7 @@ enum Digit {
Index,
}
#[derive(Copy, Clone, Eq, PartialEq)]
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
struct Finger {
hand: Hand,
digit: Digit,
@ -113,6 +120,7 @@ const CHAR_FREQ_LOOKUP: [f64; char_data_max_index()] = {
data
};
#[derive(Copy, Clone)]
struct Layout {
key_indices: [usize; char_data_max_index()],
}
@ -129,6 +137,15 @@ impl Layout {
Self { key_indices }
}
fn to_key_matrix(self) -> [char; MATRIX_COUNT] {
let mut out = ['0'; MATRIX_COUNT];
for ch in CHARACTERS.chars() {
out[self.key_indices[ch as usize]] = ch;
}
out
}
}
fn key_effort(ch: char, l: &Layout) -> f64 {
@ -210,24 +227,82 @@ fn all_bigrams() -> &'static [String] {
unsafe { ALL_BIGRAMS.as_ref().unwrap_unchecked() }
}
fn main() {
unsafe {
init_bigram_freqs();
init_all_bigrams();
};
const N_WORKERS: usize = 16;
let eff: f64 = CHARACTERS
.chars()
.map(|v| {
let mut eff = key_effort(v, &INITIAL_LAYOUT);
eff += all_bigrams()
.iter()
.map(|b| bigram_effort(b, &INITIAL_LAYOUT))
.sum::<f64>();
eff
})
.sum();
println!("{eff}");
fn mutate_layout(layout: &mut Layout, rng: &mut ThreadRng, num_swaps: usize) {
for _ in 0..num_swaps {}
}
struct WorkerThreadInit {
initial_layout: Layout,
report: Sender<(f64, Layout)>,
/// The maximum amount of deviation from the min_effort value allowed before
/// reverting back to the currently-known best layout
max_dev: f64,
/// The number of swaps to make between iterations
swaps: usize,
}
fn worker_thread_run(init: WorkerThreadInit) {
let mut rng = rand::thread_rng();
let mut layout = init.initial_layout;
let mut best_layout = layout;
let mut min_effort: f64 = f64::MAX;
loop {
let mut eff: f64 =
CHARACTERS.chars().map(|v| key_effort(v, &layout)).sum();
eff += all_bigrams()
.iter()
.map(|b| bigram_effort(b, &layout))
.sum::<f64>();
if eff < min_effort {
min_effort = eff;
best_layout = layout;
init.report.send((eff, layout)).unwrap();
} else if (eff - min_effort) > init.max_dev {
layout = best_layout;
}
mutate_layout(&mut layout, &mut rng, init.swaps);
}
}
fn main() -> Result<()> {
let (tx_agg, rx_agg) = std::sync::mpsc::channel();
let (tx_ui, rx_ui) = std::sync::mpsc::channel();
let ui_thread = std::thread::spawn(|| {
ui_thread_run(INITIAL_LAYOUT, rx_ui);
});
let aggregator_thread = std::thread::spawn(|| {
aggregator_thread_run(INITIAL_LAYOUT, rx_agg, tx_ui);
});
let worker_threads = (0..N_WORKERS)
.map(|_| {
let tx = tx_agg.clone();
std::thread::spawn(move || {
worker_thread_run(WorkerThreadInit {
initial_layout: INITIAL_LAYOUT,
report: tx,
max_dev: 1000.,
swaps: 1,
})
})
})
.collect::<Vec<_>>();
ui_thread.join().unwrap();
aggregator_thread.join().unwrap();
for j in worker_threads {
j.join().unwrap();
}
Ok(())
}