ezb.sh logo
Back to Home

Words and Pickles - pickle.ooo šŸ„’

What pickle.ooo is and how I made it
Written by ezb
react
frontend
I love finding little patterns or quirks of programs or equations. It usually helps me learn about the limits of the system, or potentially a new way to use the system entirely. There's a lot of knowledge and experience you can gain by tinkering with the rules and expectations of things we've built.
This, however, is mostly pointless. It's art, and Wordle. This is a pickle.
Yesterday I built https://pickle.ooo, a toy tool that lets you find words that generate Wordle pictures. Let's dive in.

What is Pickle?

Pickle is a tool that lets you generate pictures using Wordle as your canvas. The order of operations is clunky, ineffective, not-at-all-practical, and I love it. If you know the current day's Wordle word, you can enter a picture you want to have as your result.
The name stems from the idea that "word" is to "wordle" as "pic" is to "pic(k)le". šŸ„’

A little backstory

There are two Wordles in particular that spawned this idea. For Wordle 221 ("whack"), I had ended up guessing a perfect upside-down T shape, with only greens and no yellows. Then, the following day for Wordle 222 ("mount"), both my partner and I generated results that looked like animals - mine looks like a swan, and theirs looks like a snake (...kinda).
1:
The upside down T:
2:
ā¬›ā¬›šŸŸ©ā¬›ā¬›
3:
ā¬›ā¬›šŸŸ©ā¬›ā¬›
4:
ā¬›ā¬›šŸŸ©ā¬›ā¬›
5:
ā¬›ā¬›šŸŸ©ā¬›ā¬›
6:
🟩🟩🟩🟩🟩
7:
8:
The swan:
9:
šŸŸØšŸŸ©ā¬›ā¬›ā¬›
10:
ā¬›šŸŸ©ā¬›šŸŸ©šŸŸ©
11:
ā¬›šŸŸ©šŸŸ©šŸŸ©šŸŸ©
12:
🟩🟩🟩🟩🟩
13:
14:
The snake:
15:
ā¬›ā¬›ā¬›šŸŸ©ā¬›
16:
ā¬›ā¬›šŸŸ©ā¬›ā¬›
17:
ā¬›šŸŸ©ā¬›ā¬›ā¬›
18:
ā¬›šŸŸ©šŸŸ©šŸŸ©ā¬›
19:
🟩🟩🟩🟩🟩
The idea of using Wordle as an artistic canvas via a list of words that generates certain Wordle results was a perfect little side project for a night where I was snowed in. So, let's see how it works!

How it works

If you're really interested, the whole source code is available on my Github. Otherwise, here's the breakdown:
Pickle's job is ultimately to solve the given problem:
What sequence of words would generate the input picture in Wordle?
Pickle finds the words that result in the desired yellow, green, and gray pixels in each row. I had chosen the npm package an-array-of-english-words for starters, but looking at some Wordle clones' lists of 5 letter words words, it appears Wordle may have used this package at some point too!
The entire picture is stored in an array of 30 integers ranging from 0 to 2, where 0 represents ⬜, 1 represnts 🟨, and 2 represents 🟩. Each row is a sequence of 5 digits in this array, which I used lodash's chunk method to do for convenience.
Each row is then run through a reduce call to generate a regex string, based on the input Wordle. The regex is generated on a letter-by-letter basis for each row. Then, from the top row down, each row's regex string is tested against the list of 5-letter words. If we get a match, then we know there's a valid English (and Wordle-compliant) word that meets that row's requirements. In the case that it doesn't, I've chosen to keep the picture intact, and just replace every letter in that row a "?" to indicate that no word could be found to satisfy the constraints.
I've also utilized lodash's shuffle method to shuffle the master word list before comparison. The search function uses <Array>.find() to find the first instance of a word that matches the regex, so if we didn't shuffle the list, we would always see the same words for each given row pattern.
The whole generation function looks like this:
1:
export const computePickleState = (
2:
pictureData: PictureData,
3:
wordle: string
4:
): ComputedPickleState => {
5:
const rows = chunk(pictureData, 5)
6:
7:
// Build the dynamic regexprs for each row
8:
const regexStrs: string[] = rows.map((row) =>
9:
row.reduce<string>((workingStr, pixel, position) => {
10:
const testChar: string = wordle.charAt(position)
11:
switch (pixel) {
12:
default:
13:
case EPickleChipColor.Gray: {
14:
// We cannot have any of the letters in the word appear here
15:
return workingStr + `[^(${wordle.split("").join("|")})]{1}`
16:
}
17:
case EPickleChipColor.Green: {
18:
// A very specific character must be in this spot
19:
return workingStr + `${testChar}{1}`
20:
}
21:
case EPickleChipColor.Yellow: {
22:
// This letter can be any other letter in the wordle, that isn't the one
23:
// actually at this location
24:
return (
25:
workingStr +
26:
`(${wordle
27:
.split("")
28:
.filter((char) => char !== testChar)
29:
.join("|")}){1}`
30:
)
31:
}
32:
}
33:
}, "")
34:
)
35:
36:
// Look to find a match for each row
37:
const foundWords: string[] = regexStrs.map((regexStr, i) => {
38:
console.log(`Processing row id ${i} [ ${regexStr} ]`)
39:
const regexp = new RegExp(regexStr)
40:
const word = shuffle(WORDLIST).find((str) => regexp.test(str))
41:
if (!word) {
42:
console.log(`Can't make a word for row id ${i}`)
43:
44:
// Return a replacement string
45:
return "?????"
46:
}
47:
return word
48:
})
49:
50:
return {
51:
foundWords,
52:
pictureData,
53:
}
54:
}
(Oh, yes. Each tile in Pickle is internally referred to as a PickleChip because I was hungry.)

An example

Wordle 224, the Wordle for the day I am writing this article, was could. I figured this out in an uninspiring set of moves with the only exciting part being there's more yellow squares than I've ever had in the past:
1:
Wordle 224 5/6
2:
3:
⬜🟨⬜⬜🟨
4:
🟨🟨⬜⬜⬜
5:
⬜🟨🟨⬜⬜
6:
⬜⬜🟨🟨⬜
7:
🟩🟩🟩🟩🟩
But... what if I had taken a more inventive approach, knowing now that the word is could? Say I wanted my picture to look like a duck (šŸ¦† Love these little guys). Something that may end up looking like so:
1:
🟨🟩⬜⬜⬜
2:
⬜🟩⬜⬜🟩
3:
⬜🟩🟩🟩🟩
4:
⬜🟩🟩🟩⬜
5:
⬜⬜⬜⬜⬜
6:
🟩🟩🟩🟩🟩
You can then take this information, and run Wordle in a private/incognito window to confirm Pickle's results. Closing and re-opening a private window to Wordle is sufficient for Wordle to forget who you are, letting you make more than one drawing per day!
And here's my share card! šŸ¦†
1:
Wordle 224 6/6
2:
3:
🟨🟩⬜⬜⬜
4:
⬜🟩⬜⬜🟩
5:
⬜🟩🟩🟩🟩
6:
⬜🟩🟩🟩⬜
7:
⬜⬜⬜⬜⬜
8:
🟩🟩🟩🟩🟩

What's next?

Not only was Pickle a lot of fun to make, it was also the first time I've ever used the Mantine component library. I learned the basics with Pickle, and I am planning on writing a follow-up article about my experience with Mantine during the development of Pickle.
Thank you for reading! If you end up using Pickle and find something nifty with it, shoot me a message on Discord: ebernerd#1123.
šŸ„’ Visit Pickle