Implement a Wordle Hard Mode solver
This commit is contained in:
parent
2d66be5208
commit
e6df0633bf
182721
web/pages/wordle/dictionary.json
Normal file
182721
web/pages/wordle/dictionary.json
Normal file
File diff suppressed because it is too large
Load Diff
108
web/pages/wordle/index.tsx
Normal file
108
web/pages/wordle/index.tsx
Normal file
|
@ -0,0 +1,108 @@
|
|||
import { Page } from '../../components/page'
|
||||
import { Title } from '../../components/title'
|
||||
// From https://github.com/lynn/hello-wordl
|
||||
// `dictionary` has all accepted words; `targets` are common-ish words
|
||||
import * as dictionary from './dictionary.json'
|
||||
import * as targets from './targets.json'
|
||||
|
||||
export default function Wordle() {
|
||||
const WORD_LENGTH = 5
|
||||
// Find all words of length WORD_LENGTH
|
||||
// const dict = dictionary.filter((word) => word.length === WORD_LENGTH)
|
||||
const words = targets.filter((word) => word.length === WORD_LENGTH)
|
||||
|
||||
const pastGuesses: PastGuess[] = [
|
||||
// From https://hellowordl.net/?challenge=aGFyZHk
|
||||
// { guess: 'sheep', result: 'BYBBB' },
|
||||
// { guess: 'butch', result: 'BBBBY' },
|
||||
// { guess: 'hydra', result: 'GYYYY' },
|
||||
// Answer: hardy
|
||||
{ guess: 'snowy', result: 'BBBYB' },
|
||||
{ guess: 'wheel', result: 'GYBBB' },
|
||||
]
|
||||
|
||||
const valids = validHardMode(words, pastGuesses)
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<div className="text-gray-500">
|
||||
<Title text="Wordle: Hard Mode possibilities" />
|
||||
<p className="text-black">
|
||||
Given a list of past Wordle guesses, show all possible valid next
|
||||
guesses for Hard Mode
|
||||
</p>
|
||||
Actually for{' '}
|
||||
<a href="https://hellowordl.net/">https://hellowordl.net/</a>
|
||||
<p>Past guesses:</p>
|
||||
<pre>{JSON.stringify(pastGuesses, null, 2)}</pre>
|
||||
<br />
|
||||
<br />
|
||||
<p className="text-black">
|
||||
{Array(10)
|
||||
.fill(null)
|
||||
.map((_) => chooseRandom(valids))
|
||||
.join(', ')}
|
||||
</p>
|
||||
<p>Total valid words: {valids.length}</p>
|
||||
<p>All valid words:</p>
|
||||
<pre>{JSON.stringify(valids, null, 2)}</pre>
|
||||
</div>
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
function chooseRandom(list: any[]) {
|
||||
return list[Math.floor(Math.random() * list.length)]
|
||||
}
|
||||
|
||||
type PastGuess = {
|
||||
guess: string
|
||||
// Result is a string like 'GYBBG'
|
||||
// G = Green (match), Y = Yellow (somewhere), B = Black (nowhere)
|
||||
result: string
|
||||
}
|
||||
|
||||
function validHardMode(wordlist: string[], pastGuesses: PastGuess[]) {
|
||||
let candidates = wordlist.slice()
|
||||
const blacks = new Set()
|
||||
for (const { guess, result } of pastGuesses) {
|
||||
candidates = candidates.filter((word) => {
|
||||
// e.g. guess = 'helot', result = 'GGGYB', word = 'hello => true
|
||||
// e.g. guess = 'helot', result = 'GGGYB', word = 'helot => false
|
||||
const guessYellows = []
|
||||
const wordNonGreens: string[] = []
|
||||
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
switch (result[i]) {
|
||||
case 'G':
|
||||
if (word[i] !== guess[i]) return false
|
||||
break
|
||||
case 'Y':
|
||||
if (word[i] === guess[i]) return false
|
||||
guessYellows.push(guess[i])
|
||||
wordNonGreens.push(word[i])
|
||||
break
|
||||
case 'B':
|
||||
if (word[i] === guess[i]) return false
|
||||
wordNonGreens.push(word[i])
|
||||
blacks.add(guess[i])
|
||||
break
|
||||
}
|
||||
if (blacks.has(word[i])) return false
|
||||
}
|
||||
// Return true if every letter in guessYellows is in wordNonGreens
|
||||
return guessYellows.every((letter) => wordNonGreens.includes(letter))
|
||||
})
|
||||
}
|
||||
return candidates
|
||||
}
|
||||
|
||||
function parsePastGuesses(pastGuesses: string) {
|
||||
return pastGuesses.split('\n').map((pg) => {
|
||||
const [guess, result] = pg.split(', ')
|
||||
return { guess, result }
|
||||
})
|
||||
}
|
||||
|
||||
// Bad target words: witan, sedum
|
||||
// TODO: Maybe just use canonical Wordle dictionaries
|
37949
web/pages/wordle/targets.json
Normal file
37949
web/pages/wordle/targets.json
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user