g | x | w | all
Bytes Lang Time Link
297Python3250824T172649ZAjax1234
055Charcoal221214T235940ZNeil
038Japt221215T182835ZKamil Dr
024Japt221221T170636ZShaggy
117Ruby221216T181621ZnaffetS
138Python 3221215T183748ZThe Thon

Python3, 297 bytes

def f(a,b):
 q=[(a,'')]
 for A,B in q:
  if[]==A:yield B;continue
  if A[0].isalpha():q+=[(A[1:],B+A[0])];continue
  v={u[0]for u in a if'!'==u[-1]and u!=' ' and u not in A[0]}
  if not v or any(I in a for I in v):v={*v,*b,*[u for u in a if u.isalpha()and u!=A[0][0]]}
  q+=[(A[1:],B+j)for j in v]

Try it online!

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).

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:

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

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?

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!

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!

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*

Input:

Output:

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