20
\$\begingroup\$

Sometimes when you're playing Wordle, you get to your fifth guess and you can't figure out the word any more, so you start mentally running through the list of remaining iterations, both sensical and nonsensical trying to figure out what those last few letters are.

The task here is to create all permutations of a final Wordle guess to save me from having to do it in my head, with the following rules:

General rules:

  • Wordle rules apply (similar to codebreaker game).
    • Guess an unknown five-letter word.
    • Guesses will return an indication of whether the letter is in the word such that:
      • If a letter is in the correct position, it will be green
      • If a letter appears in the word but is not in the correct position, it will be yellow
      • If a letter does not appear in the word, it will be black.
      • Letters can appear more than once in the solution (provided the solution is still a valid word)
      • If a letter is guessed twice in the same guess (such as "guess") but is in the correct word fewer times than guessed, only the number of the repeated letters will be green or yellow. If the position is correct for one of the placements, that will appear green, regardless of the position in the sequence. If the positions are all wrong, the earliest occurence/s will be marked yellow and the following one/s black.
  • Inputs should be solvable, even if no solutions are "real" words.
  • Since Wordle only uses valid English words, only letters that appear on a standard English keyboard (a-z) need to be tested. However, you should include all valid permutations, not just valid English words, in your output.
  • Solution is case insensitive.

Input:

  • A list of letters and indices (0 or 1 indexed, your choice), indicating the location of confirmed/green letters - indicate the index you chose;
  • A list of letters and indices (consistently indexed), indicating yellow letters (i.e. the letter is known to not be at that index);
  • A list/string of letters that are yet to be guessed.

Note, green and yellow letters may still appear in more than the known positions. For example, if the input for green is [('E', 1)], there may still be an E in an index other than 1 as well.

Output:

All potential "words" of exactly 5 letters, such that the green letters are in the indicated indexes, the yellow letters are not in the indicated indexes (but must appear at least once in the output), and the words consist of only the green, yellow, and remaining letters. The output may be in any order.

What's the shortest way to solve this problem? You may take input and output in any convenient method or format, and the shortest code in bytes wins.


Example:

  1. Green Guesses (1 indexed): O=2, E=4, N=5
  2. Yellow Guesses: N!=3 (E!=5 is excluded because we know N=5)
  3. Unguessed Letters: Q, W, I, P, F, J, K, X, B

All other letters (A, C, D, F, G, H, L, M, R, S, T, U, V, Y, Z) have been guessed and cannot occur in the result.

Output would be a list of all possible permutations given the known information, such as:

["BOBEN", "BOEEN", "BOFEN", "BOIEN", "BOJEN", "BOKEN", "BOOEN", "BOPEN", "BOQEN", "BOWEN", "BOXEN", "EOBEN", "EOEEN", "EOFEN", "EOIEN", "EOJEN", "EOKEN", "EOOEN", "EOPEN", "EOQEN", "EOWEN", "EOXEN", "FOBEN", "FOEEN", "FOFEN", "FOIEN", "FOJEN", "FOKEN", "FOOEN", "FOPEN", "FOQEN", "FOWEN", "FOXEN", "IOBEN", "IOEEN", "IOFEN", "IOIEN", "IOJEN", "IOKEN", "IOOEN", "IOPEN", "IOQEN", "IOWEN", "IOXEN", "JOBEN", "JOEEN", "JOFEN", "JOIEN", "JOJEN", "JOKEN", "JOOEN", "JOPEN", "JOQEN", "JOWEN", "JOXEN", "KOBEN", "KOEEN", "KOFEN", "KOIEN", "KOJEN", "KOKEN", "KOOEN", "KOPEN", "KOQEN", "KOWEN", "KOXEN", "NOBEN", "NOEEN", "NOFEN", "NOIEN", "NOJEN", "NOKEN", "NOOEN", "NOPEN", "NOQEN", "NOWEN", "NOXEN", "OOBEN", "OOEEN", "OOFEN", "OOIEN", "OOJEN", "OOKEN", "OOOEN", "OOPEN", "OOQEN", "OOWEN", "OOXEN", "POBEN", "POEEN", "POFEN", "POIEN", "POJEN", "POKEN", "POOEN", "POPEN", "POQEN", "POWEN", "POXEN", "QOBEN", "QOEEN", "QOFEN", "QOIEN", "QOJEN", "QOKEN", "QOOEN", "QOPEN", "QOQEN", "QOWEN", "QOXEN", "WOBEN", "WOEEN", "WOFEN", "WOIEN", "WOJEN", "WOKEN", "WOOEN", "WOPEN", "WOQEN", "WOWEN", "WOXEN", "XOBEN", "XOEEN", "XOFEN", "XOIEN", "XOJEN", "XOKEN", "XOOEN", "XOPEN", "XOQEN", "XOWEN", "XOXEN"]

Output may be in any order.

In this case:

  • There are 12 possibilities for the first letter (any of "BEFIJKNOPQWX")
  • There is 1 possibility for the second letter ("O")
  • There are 11 possibilities for the third letter (any of "BEFIJKOPQWX", excluding N)
  • There is 1 possibility for the fourth letter ("E")
  • There is 1 possibility for the fifth letter ("N")

So the result should contain a total of 12 * 1 * 11 * 1 * 1 = 132 items.

In code terms, the inputs may be given as:

  • [['O', 2], ['E', 4], ['N', 5]] or [["O", "E", "N"], [2, 4, 5]] or similar
  • [['N', 3]] or [["N"], [3]] or similar
  • "QWIPFJKXB" or ["Q","W","I","P","F","J","K","X","B"] or similar

and the output as:

['BOBEN', 'EOBEN', 'FOBEN', 'IOBEN', 'JOBEN', 'KOBEN', 'NOBEN', 'OOBEN', 'POBEN', 'QOBEN', 'WOBEN', 'XOBEN', 'BOEEN', 'EOEEN', 'FOEEN', 'IOEEN', 'JOEEN', 'KOEEN', 'NOEEN', 'OOEEN', 'POEEN', 'QOEEN', 'WOEEN', 'XOEEN', 'BOFEN', 'EOFEN', 'FOFEN', 'IOFEN', 'JOFEN', 'KOFEN', 'NOFEN', 'OOFEN', 'POFEN', 'QOFEN', 'WOFEN', 'XOFEN', 'BOIEN', 'EOIEN', 'FOIEN', 'IOIEN', 'JOIEN', 'KOIEN', 'NOIEN', 'OOIEN', 'POIEN', 'QOIEN', 'WOIEN', 'XOIEN', 'BOJEN', 'EOJEN', 'FOJEN', 'IOJEN', 'JOJEN', 'KOJEN', 'NOJEN', 'OOJEN', 'POJEN', 'QOJEN', 'WOJEN', 'XOJEN', 'BOKEN', 'EOKEN', 'FOKEN', 'IOKEN', 'JOKEN', 'KOKEN', 'NOKEN', 'OOKEN', 'POKEN', 'QOKEN', 'WOKEN', 'XOKEN', 'BOOEN', 'EOOEN', 'FOOEN', 'IOOEN', 'JOOEN', 'KOOEN', 'NOOEN', 'OOOEN', 'POOEN', 'QOOEN', 'WOOEN', 'XOOEN', 'BOPEN', 'EOPEN', 'FOPEN', 'IOPEN', 'JOPEN', 'KOPEN', 'NOPEN', 'OOPEN', 'POPEN', 'QOPEN', 'WOPEN', 'XOPEN', 'BOQEN', 'EOQEN', 'FOQEN', 'IOQEN', 'JOQEN', 'KOQEN', 'NOQEN', 'OOQEN', 'POQEN', 'QOQEN', 'WOQEN', 'XOQEN', 'BOWEN', 'EOWEN', 'FOWEN', 'IOWEN', 'JOWEN', 'KOWEN', 'NOWEN', 'OOWEN', 'POWEN', 'QOWEN', 'WOWEN', 'XOWEN', 'BOXEN', 'EOXEN', 'FOXEN', 'IOXEN', 'JOXEN', 'KOXEN', 'NOXEN', 'OOXEN', 'POXEN', 'QOXEN', 'WOXEN', 'XOXEN']
\$\endgroup\$
15
  • \$\begingroup\$ I assume we won't ever be given an invalid input (i.e. one with conflicting green/yellow letters), but will we ever be given an "impossible" scenario which would work out? For example, having 4 green Es and a yellow E in any position other than the empty one would result in just the one "word" in the output, but could never occur when playing the game. This scenario seems harmless, but I'm not sure if other ones might be weird, yet. \$\endgroup\$ Dec 14, 2022 at 21:55
  • \$\begingroup\$ @FryAmTheEggman Considering the specific exclusion of needing to check against a dictionary, it's not required there be an actual word solution but it should always follow the rules of wordle and there should be at least one solution. \$\endgroup\$
    – Catija
    Dec 14, 2022 at 22:02
  • \$\begingroup\$ Posts on Code Golf & Coding Challenges are supposed to be self-contained. You may not belive this but some people have no idea what Wordle is. So a brief explaination of Wordle rules would realy help those people to understand your post. :D (yes, I'm one of those people...) \$\endgroup\$
    – Noodle9
    Dec 14, 2022 at 23:22
  • 1
    \$\begingroup\$ @KamilDrakari I will admit that I didn't write the input formats so I'm not sure what they mean, but, yes. It should definitely be possible to have multiple letters that are yellow in the same space. (see my answer to tsh's comment for an actual example). \$\endgroup\$
    – Catija
    Dec 15, 2022 at 17:34
  • 1
    \$\begingroup\$ Every current answer seems to treat yellow guesses as just "This letter cannot be in this position" without "this letter must be in the word". I recommend adding more test cases, for example ["","B","","U","T"] ["O","","A","",""] ["Q","W","I","P","F","J","K","X"] should produce the single word "ABOUT". \$\endgroup\$ Dec 15, 2022 at 17:56

5 Answers 5

3
\$\begingroup\$

Python 3, 198 176 205 166 152 138 bytes

lambda g,y,u:{m for m in product(*[x or u+''.join(g+[a for a,b in y])for x in g])if all(m[q]!=p in m for p,q in y)}
from itertools import*

Try it online!

  • -22, -39, -14 thanks to Steffan
  • Thanks to Kamil Drakari for pointing out some bugs in the code

So, it didn't work before. I've now fixed it (I think).

Other test cases here, here and here.

Python 3 + golfing-shortcuts, 131 121 bytes

lambda G,Y,U:{M for M in Ip(*[X or U+sj('',G+[A for A,B in Y])for X in G])if j(M[Q]!=P in M for P,Q in Y)}
from s import*
  • -10 thanks to Steffan

Input:

  • g: The green letters, as a list, e.g. ['', 'O', '', 'E', 'N']
  • y: The yellow letters, in tuples with their positions, e.g. [('N', 2)]
  • u: The unguessed letters, as a string: e.g. 'QWIPFJKXB'

Output:

As letter tuples, e.g. ('Q', 'O', 'Q', 'E', 'N')

\$\endgroup\$
23
  • 1
    \$\begingroup\$ @Steffan thanks for telling me that. I'll roll it back. \$\endgroup\$
    – The Thonnu
    Dec 15, 2022 at 19:50
  • 1
    \$\begingroup\$ @KamilDrakari I think those bugs are fixed now. I've added your test case with the multiple yellows into the answer as the third additional test case. \$\endgroup\$
    – The Thonnu
    Dec 15, 2022 at 20:55
  • 1
    \$\begingroup\$ @KamilDrakari thanks for noticing that. That's easily fixed, by just swapping out [] for {}. I'll edit that in now. \$\endgroup\$
    – The Thonnu
    Dec 15, 2022 at 21:00
  • 1
    \$\begingroup\$ Question - I'm a non-programmer, so this is maybe a dumb question but if I have two yellow letters or a single yellow letter in two positions, such as E in positions 2 and 3, how would I indicate that in the inputs? Do I need two separate ones ('E' , 2) and ('E' , 3) both in the square brackets? \$\endgroup\$
    – Catija
    Dec 22, 2022 at 15:02
  • 1
    \$\begingroup\$ @Catija Python uses 0-indexing, so the first element is 0, the second one is 1, etc. Did you mean this? \$\endgroup\$
    – The Thonnu
    Dec 22, 2022 at 16:50
3
\$\begingroup\$

Charcoal, 55 bytes

UMθ∨ι⁻⪪α¹⁺⪪§ηκ¹⁻⪪α¹⁺θ⪪⁺ζΣη¹ΦEΠEθLι⭆θ§λ÷ιΠ∨E…θμLν¹⬤Ση№ιλ

Try it online! Link is to verbose version of code. Takes input in the ["", "O", "", "E", "N"], ["", "", "N", "", ""], "QWIPFJKXB" formats, i.e. multiple letters unguessed or in a given yellow position should be concatenated into a string rather than being a subarray. Explanation:

UMθ∨ι⁻⪪α¹⁺⪪§ηκ¹⁻⪪α¹⁺θ⪪⁺ζΣη¹

Fill in the gaps in the green guesses by taking the set union of all of the input and subtracting the yellow guesses for that position. (Charcoal doesn't actually do set union so I have to fake it by set difference with the whole alphabet twice.)

EΠEθLι⭆θ§λ÷ιΠ∨E…θμLν¹⬤Ση№ιλ

Calculate the number of potential words and map each to a string by mixed base conversion using the lists of possible letters (which again Charcoal has to emulate, although at least it has cyclic indexing to help). Ensure those words contain at least one of all of the yellow guesses.

50 bytes using the newer version of Charcoal on ATO that can take the product of an empty list and flatten a list of lists:

UMθ∨ι⁻⪪α¹⁺§ηκ⁻⪪α¹⁺Σθ⁺ζΣηΦEΠEθLι⭆θ§λ÷ιΠE…θμLν⬤Ση№ιλ

Attempt This Online! Link is to verbose version of code. Takes input in the ["", "O", "", "E", "N"], [[], [], ["N"], [], []], ["Q", "W", "I", "P", "F", "J", "K", "X", "B"] formats, i.e. letters unguessed or in a given yellow position need to be a subarray (both formats work for the green letters).

\$\endgroup\$
8
  • 1
    \$\begingroup\$ @KamilDrakari Yes, it's the same as for the unguessed letters; hopefully my edit clarifies that. \$\endgroup\$
    – Neil
    Dec 15, 2022 at 20:29
  • \$\begingroup\$ Thanks! I was able to use the TIO to get an answer to my Wordle this morning! It was easy to know how to input the options. My only frustration (and this wasn't in the requirements, so that doesn't disqualify the solution in any way) is that the list's sort isn't very useful to me - I like the Python solution because it puts the solution set in alphabetical order. :D \$\endgroup\$
    – Catija
    Dec 22, 2022 at 15:04
  • \$\begingroup\$ @Catija Sorting in lexical order of reversed word is an unfortunate consequence of optimising for byte count; 58 bytes to output in lexical order. \$\endgroup\$
    – Neil
    Dec 22, 2022 at 17:45
  • \$\begingroup\$ I'm not sure this is intended or not but it seems like you need to include the green letters in the list of possible letters to get those permutations. This is fine if the green letter is only used one time but if it's used multiple times, this will fail to identify the word. :) \$\endgroup\$
    – Catija
    Jan 9 at 15:46
  • \$\begingroup\$ @Catija I'm confused. My test case gives OOOEN as a possible answer; is this wrong, and if it is, why is it wrong? \$\endgroup\$
    – Neil
    Jan 9 at 16:54
2
\$\begingroup\$

Japt, 38 bytes

5ÆgX ªNc kVgX)fÃrÈï[Y]c '+Ãf@Vc e!øXÃâ

Try the original test case, or check that it's right

Try my proposed test case

Try another case demonstrating multiple yellow letters in the same position

Try a fourth test case with a yellow letter in the same position as a green letter

Input format in order:

  • Green letters as an array with "" for unkown, e.g. ["", "O", "", "E", "N"]
  • Yellow letters as an array of arrays of letters for each position, e.g. [[], [], ["N"], [], []]
  • Unguessed letters as an array of letters, e.g. ["Q","W","I","P","F","J","K","X","B"]

High-level explanation:

5ÆgX ªNc kVgX)fÃrÈï[Y]c '+Ãf@Vc e!øXÃâ
5ÆgX ªNc kVgX)fà                       # Find the valid letters for each position
                rÈï[Y]c '+Ã            # Generate words from the possible letters
                           f@Vc e!øXÃ  # Ensure that all yellow letters are used
                                     â # Remove duplicates

Details:

5ÆgX ªNc kVgX)fÃ
5Æ             Ã # For each X in range [0...4]:
  gX             #  Return the green letter at index X if possible
     ª           #  Otherwise
      Nc         #  Get all letters from the three inputs
         k   )   #  Remove:
          VgX    #   The yellow letters at index X
              f  #  Remove empty strings

rÈï[Y]c '+Ã      
r         Ã      # Reduce the array of valid letters in steps:
 È               #  Current array of prefixes
   [Y]c          #  Possible next letters (converted to array if needed)
  ï              #  Cross product of those two arrays
        '+       #  Concatenate each prefix and letter

f@Vc e!øXÃ
f@       Ã       # Remove any word X where this is false:
  Vc             #  Flatten yellow letters to a single array
     e           #  Return true only if every letter:
      !øX        #   is contained in X
\$\endgroup\$
3
  • \$\begingroup\$ I was able to use your solution to find my Wordle options today! :) I appreciate your answer. If I had one piece of feedback (and this is outside the realms of the challenge), it's that the solution returns results that wrap, which makes it really difficult to see the answers. Other solutions put each answer on a newline, which makes it easier to scan. \$\endgroup\$
    – Catija
    Dec 22, 2022 at 15:13
  • 1
    \$\begingroup\$ @Catija I've replaced the links with versions which output each word on a separate line, it was just a different flag so the code is identical. \$\endgroup\$ Dec 22, 2022 at 16:11
  • \$\begingroup\$ Ah! Cool! That's a lot easier to read! \$\endgroup\$
    – Catija
    Dec 22, 2022 at 16:51
1
\$\begingroup\$

Ruby, 117 bytes

->g,y,u{a,*b=g.map{|x|(x>''?x:u+(g+y.map{_1[0]})*'').chars};a.product(*b).select{|m|y.all?{m[_2]!=_1&&m!=m-[_1]}}|[]}

Attempt This Online!

\$\endgroup\$
2
  • \$\begingroup\$ I have a similar question for you that I did on one of the other answers - for the input, how do I indicate multiple yellow letters or multiple positions for the same yellow letter - for example, if I know E is not in position 2 or 3. I tried [['E', 2],['E', 3]], but that didn't work. This would probably be obvious to a programmer but... I is not one! :P \$\endgroup\$
    – Catija
    Dec 22, 2022 at 15:16
  • \$\begingroup\$ The issue I was having with the Python answer is that I didn't realize it was a zero index. I'm guessing that's the same thing in Ruby? \$\endgroup\$
    – Catija
    Dec 22, 2022 at 16:54
1
\$\begingroup\$

Japt, 26 24 bytes

Takes input as 3 arrays of character strings, or empty strings for blanks, in the order: yellow, green, unguessed. Outputs an array of character arrays

c@NcfÃá5 £VíªXÃâ fÈíÀU e

Try it - modified to run in a reasonable amount of time without crashing your browser by not allowing letters to be used more than once in each guess.

c@NcfÃá5 £VíªXÃâ fÈíÀU e     :Implicit input of arrays U=yellow, V=green & W=unguessed
c                            :Flat map U by
 @                           :Passing each element through the following function
  N                          :  Array of all inputs
   c                         :  Flat map
    f                        :    Filter empty strings
     Ã                       :End map
      á5                     :Permutations of length 5
         £                   :Map each X
          Ví X               :  Interleave V with X
            ª                :  Reducing each pair by Logical OR
              Ã              :End map
               â             :Deduplicate
                 f           :Filter by
                  È          :Passing each through the following function
                   í U       :  Interleave with U
                    À        :  Reducing each pair by testing for inequality
                       e     :  All true?
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.