diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3ffccf2 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +all: wordle_opt.wasm + +wordle_opt.wasm: wordle_opt/target/wasm32-unknown-unknown/release/wordle_opt.wasm + #wasm-snip $< -o $@ + cp $< $@ + +wordle_opt/target/wasm32-unknown-unknown/release/wordle_opt.wasm: wordle_opt/src/*.rs + cd wordle_opt; cargo build --target wasm32-unknown-unknown --release + diff --git a/wordle_opt/.gitignore b/wordle_opt/.gitignore new file mode 100644 index 0000000..2f7896d --- /dev/null +++ b/wordle_opt/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/wordle_opt/Cargo.lock b/wordle_opt/Cargo.lock new file mode 100644 index 0000000..ba18caf --- /dev/null +++ b/wordle_opt/Cargo.lock @@ -0,0 +1,62 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "libc" +version = "0.2.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" + +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if", + "libc", + "memory_units", + "winapi", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wordle_opt" +version = "0.1.0" +dependencies = [ + "wee_alloc", +] diff --git a/wordle_opt/Cargo.toml b/wordle_opt/Cargo.toml new file mode 100644 index 0000000..b287053 --- /dev/null +++ b/wordle_opt/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "wordle_opt" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] +bench = false + +[profile.release] +debug = true +lto = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +wee_alloc = "*" diff --git a/wordle_opt/src/lib.rs b/wordle_opt/src/lib.rs new file mode 100644 index 0000000..907913d --- /dev/null +++ b/wordle_opt/src/lib.rs @@ -0,0 +1,82 @@ +extern crate wee_alloc; + +#[global_allocator] +static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; + + +// webassembly version of all the wordle logic +// because the javascript version is slow as hell on firefox +use std::os::raw::c_char; + +static mut LOOKUP: Option> = None; +static mut STRINGS: Option> = None; +static mut STR_IDXS: Option> = None; + +#[no_mangle] +pub extern fn init_strings(sz: usize) -> *mut c_char { + unsafe { + STRINGS = Some(vec![0u8; sz]); + STRINGS.as_deref_mut().map(|v| v.as_mut_ptr() as *mut c_char).unwrap() + } +} + +#[no_mangle] +pub extern fn init_idx() -> usize { + // TODO + 0 +} + +#[no_mangle] +pub extern fn init_lookup() -> *mut c_char { + unsafe { + let num_strings = STR_IDXS.as_ref().map(|idxs| idxs.len()).unwrap_or(0); + + LOOKUP = Some(vec![0u8; num_strings*num_strings]); + LOOKUP.as_deref_mut().map(|v| v.as_mut_ptr() as *mut c_char).unwrap() + } +} + +#[no_mangle] +pub extern fn calc_match(guess: *const c_char, reference: *const c_char) -> u8 { + let mut unmatched = vec![0u8; 26]; + let mut ret = 0; + let mut matched = 0; + + let mut mul = 1; + for i in 0..5 { + unsafe { + if *(guess.offset(i)) == *(reference.offset(i)) { + ret += 1*mul; + matched |= 1 << i; + } else { + unmatched[*(reference.offset(i)) as usize - 'a' as usize] += 1; + } + } + mul *= 3; + } + + mul = 1; + for i in 0..5 { + if (matched & (1 << i)) == 0 { + let idx = unsafe { *(guess.offset(i)) as usize - ('a' as usize) }; + if unmatched[idx] > 0 { + ret += 2*mul; + unmatched[idx] -= 1; + } + } + mul *= 3; + } + + ret +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +}