diff --git a/wordle-wasm.htm b/wordle-wasm.htm new file mode 100644 index 0000000..bca4ccc --- /dev/null +++ b/wordle-wasm.htm @@ -0,0 +1,296 @@ + + + + + + + + + + +
+
+
+

+ +

+

+ + + + + + +

+
+
loading words...
+ log: + +
+ +

How to use

+

1. Initialize the solver by pressing the Initialize button. This causes it to precompute this large (~220 MB) array of values

+

2. Use "Find best" to choose a word for you or enter in your own choice of word, and press Submit word. Submit this word in Wordle as well

+

3. Click on the letters of the word to match the results of what was matching according to Wordle. Hit confirm when it matches the colors of the word in Wordle. This will cause the solver to eliminate words that are no longer possible. If there was an error in the color pattern you can hit Back to remove the last confirmed word, and reenter it.

+

4. Optimally win Wordle.

+ + diff --git a/wordle.htm b/wordle.htm index d443cfe..24766bd 100644 --- a/wordle.htm +++ b/wordle.htm @@ -53,8 +53,6 @@ var valid_words = null; console.log("found " + words.length+ " words") status("found " + words.length + " words") valid_words = gen_all_words_list() - - init_wasm_solver(text) }) req.send() diff --git a/wordle.js b/wordle.js index 34b67ed..10e8f6a 100644 --- a/wordle.js +++ b/wordle.js @@ -65,6 +65,7 @@ var all_matches = null const precompute_all = (() => { var idx = 0 var init_start = null + var num_loops = 10 return () => { const l = words.length const start = Date.now() @@ -73,7 +74,7 @@ const precompute_all = (() => { all_matches = new Uint8Array(all_matches_buffer) init_start = start } - for (; (Date.now() - start) < 40 && idx < l; idx++) { + for (var i = 0; i < num_loops && idx < l; i++, idx++) { for (var j = 0; j < l; j++) { all_matches[idx*l + j] = compute_match(words[idx], words[j]) } @@ -81,9 +82,12 @@ const precompute_all = (() => { if (idx < l) { status("computing word " + idx + "/" + words.length + " " + words[idx]) } + const end = Date.now() + const millis = end - start + num_loops = Math.floor(num_loops - 0.5*(millis - 50)) + num_loops = Math.max(num_loops, 1) if (idx >= l) { - const end = Date.now() inited = true console.log("precompute done, mem = " + all_matches.length + " bytes") log("precompute done, mem = " + all_matches.length + " bytes") diff --git a/wordle_shim.js b/wordle_shim.js index 185837e..ff02435 100644 --- a/wordle_shim.js +++ b/wordle_shim.js @@ -1,7 +1,8 @@ var wasm_solver = null -var solver = null - +var word_count = 0 +var words_str_len = 0 function init_wasm_solver(words_str) { + words_str_len = words_str.length const fill_string = (offset) => { console.log("fill strings called " + offset) const str_buf = new Uint8Array(wasm_solver.exports.memory.buffer, offset) @@ -9,6 +10,7 @@ function init_wasm_solver(words_str) { str_buf.set(buf, 0) } const log_num_idxs = i => { + word_count = i console.log("wasm: found " + i + " words") } WebAssembly.instantiateStreaming(fetch("wordle_opt.wasm"), { @@ -18,47 +20,61 @@ function init_wasm_solver(words_str) { } }).then(wm => { wasm_solver = wm.instance - const exports = wasm_solver.exports - const solver_ptr = wasm_solver.exports.init(words_str.length) - solver = { - ptr: solver_ptr, - precalc: (nw) => exports.precalc(solver_ptr, nw), - precalc_done: () => exports.precalc_done(solver_ptr), - reset: () => exports.reset(solver_ptr), - eliminate_words: (guess_idx, guess_result) => - exports.eliminate_words(solver_ptr, guess_idx, guess_result), - words_left: () => exports.words_left(solver_ptr), - calc_entropy: (idx) => exports.calc_entropy(solver_ptr, idx), - find_word: (w) => { - const ary = new TextEncoder().encode(w, "utf8") - const offset = exports.find_word_load(solver_ptr) - const dst = new Uint8Array(exports.memory.buffer, offset, 5) - dst.set(ary) - return exports.find_word(solver_ptr) - }, - best_word: () => { - const idx = exports.best_word(solver_ptr) - const entropy = exports.best_word_entropy(solver_ptr) - var word = null - if (idx != -1) { - const offset = exports.lookup_word(solver_ptr, idx) - word_ary = new Uint8Array(exports.memory.buffer, offset, 5) - word = new TextDecoder().decode(word_ary) - } - return [idx, entropy, word] - }, - - lookup_valid_word: (i) => { - const idx = exports.get_valid_word(solver_ptr, i) - if (idx != -1) { - const offset = exports.lookup_word(solver_ptr, idx) - word_ary = new Uint8Array(exports.memory.buffer, offset, 5) - return new TextDecoder().decode(word_ary) - } else { - return null - } - } - } }) } + +function init_solver() { + const exports = wasm_solver.exports + console.log("wsl = ", words_str_len) + const solver_ptr = wasm_solver.exports.init(words_str_len) + return { + ptr: solver_ptr, + precalc: (nw) => exports.precalc(solver_ptr, nw), + precalc_idx: () => exports.get_precalc(solver_ptr), + precalc_done: () => exports.precalc_done(solver_ptr), + + reset: () => exports.reset(solver_ptr), + eliminate_words: (guess_idx, guess_result) => + exports.eliminate_words(solver_ptr, guess_idx, guess_result), + words_left: () => exports.words_left(solver_ptr), + calc_entropy: (idx) => exports.calc_entropy(solver_ptr, idx), + find_word: (w) => { + const ary = new TextEncoder().encode(w, "utf8") + const offset = exports.find_word_load(solver_ptr) + const dst = new Uint8Array(exports.memory.buffer, offset, 5) + dst.set(ary) + return exports.find_word(solver_ptr) + }, + best_word: () => { + const idx = exports.best_word(solver_ptr) + const entropy = exports.best_word_entropy(solver_ptr) + console.log(idx) + var word = null + if (idx != -1) { + const offset = exports.lookup_word(solver_ptr, idx) + word_ary = new Uint8Array(exports.memory.buffer, offset, 5) + word = new TextDecoder().decode(word_ary) + } + return [idx, entropy, word] + }, + + lookup_word: (idx) => { + const offset = exports.lookup_word(solver_ptr, idx) + if (offset == -1) return null + word_ary = new Uint8Array(exports.memory.buffer, offset, 5) + return new TextDecoder().decode(word_ary) + }, + + lookup_valid_word: (i) => { + const idx = exports.get_valid_word(solver_ptr, i) + if (idx != -1) { + const offset = exports.lookup_word(solver_ptr, idx) + word_ary = new Uint8Array(exports.memory.buffer, offset, 5) + return new TextDecoder().decode(word_ary) + } else { + return null + } + } + } +}