Skip to content

Instantly share code, notes, and snippets.

@nfreeze
Last active February 6, 2022 15:53
Show Gist options
  • Select an option

  • Save nfreeze/48f3ea62541c39c002c47d84882f5bdc to your computer and use it in GitHub Desktop.

Select an option

Save nfreeze/48f3ea62541c39c002c47d84882f5bdc to your computer and use it in GitHub Desktop.
import fs from 'fs';
import axios from 'axios';
import readline from 'readline';
const config = {
score_duplicate_letters: true,
dictionary_url: 'https://gist.githubusercontent.com/BideoWego/60fbd40d5d1f0f1beca11ba95221dd38/raw/58fb4cce910fbf5fa67a2f0f1f619c09d7b1b373/dictionary.json'
}
export default class WordleSolver {
constructor() {
let self = this;
self.guesses = [];
self.wordList = [];
self.wordDict = {};
self.letterOccurrences = {};
self.updateWordList().then().catch(x => console.warn('error updating word list'));
self.rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
self.rl.on('close', function () {
console.log('\ngoodbye...');
});
}
calculateWordScore(word) {
let self = this;
let score = 0;
let tested = {};
for (let letter of word) {
if (!tested[letter] || config.score_duplicate_letters) {
tested[letter] = true;
score += self.letterOccurrences[letter];
}
}
return score;
}
async updateWordList() {
let self = this;
self.wordDict = {};
if (!fs.existsSync('dictionary.json')) {
let resp = await axios.get(config.dictionary_url);
fs.writeFileSync('dictionary.json', JSON.stringify(resp.data));
self.wordDict = resp.data;
} else {
let d = fs.readFileSync('dictionary.json');
self.wordDict = JSON.parse(d.toString());
}
self.wordList = [];
for (let word of Object.keys(self.wordDict)) {
if (word.length === 5) {
word = word.toLowerCase();
self.wordList.push(word);
for (let letter of word) {
if (!self.letterOccurrences[letter]) {
self.letterOccurrences[letter] = 0;
}
self.letterOccurrences[letter]++;
}
}
}
self.wordList.sort(function (a, b) {
let aScore = self.calculateWordScore(a);
let bScore = self.calculateWordScore(b);
return aScore > bScore ? -1 : 1;
})
console.log('letter occurrences:', self.letterOccurrences);
console.log('top 20 words with most common letters:', self.wordList.slice(0, 20));
}
async prompt(msg) {
let self = this;
return new Promise(function (resolve) {
self.rl.question(msg, function (word) {
resolve(word.toLowerCase());
});
})
}
reduceWordList(guess, correctPos, incorrectPos) {
let self = this;
let matches = [];
correctPos = correctPos.split('').map(c => c === ' ' ? '' : c);
incorrectPos = incorrectPos.split('').map(c => c === ' ' ? '' : c);
let notInWord = guess.split('').filter(c => !incorrectPos.includes(c) && !correctPos.includes(c));
let inWord = correctPos.concat(incorrectPos).filter(f=> f !== '');
for (let word of self.wordList) {
let valid = inWord.map(c=> word.includes(c)).indexOf(false) === -1;
if (!valid) continue;
for (let i = 0; i < 5; i++) {
if (notInWord.includes(word[i])) {
valid = false;
break;
}
if (correctPos[i] && word[i] !== correctPos[i]) {
valid = false;
break;
}
if (incorrectPos[i] && word[i] === incorrectPos[i]) {
valid = false;
break;
}
}
if (valid) {
matches.push(word);
}
}
self.wordList = matches;
}
async start() {
let self = this;
let tries = 0;
while (tries <= 6) {
tries++;
let guess = await self.prompt('Enter a five letter word: ');
let win = await self.prompt('Did you win? (y/n): ');
self.guesses.push(guess);
if (win[0] === 'y') {
console.log(self.guesses.join(' > '),'-', self.wordDict[guess]);
process.exit(0);
}
let correctPos = await self.prompt('Correct letters in correct position (use spaces to position):');
let incorrectPos = await self.prompt('Correct letters in incorrect position (use spaces to position):');
self.reduceWordList(guess, correctPos, incorrectPos);
console.log('possible words:', self.wordList);
}
}
}
let solver = new WordleSolver();
solver.start().then().catch(x => console.warn('Error:', x.message));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment