```  letter           = placeholders 1 to 26 and also letters A to Z
word             = non-empty sequence of letters
word_set         = collection of words all the same length
dictionary       = collection of words partitioned by length
partial_bindings = placeholder -> A..Z or still unknown(0)

unknown const =  0
A       const =  1   first letter
Z       const = 26   last letter

letter     type int
where it in [A,Z]
word       type [] letter
where size it > 0
wordSet   type [] word
where ∧/{size it[i-1] = size it[i] for i in [1,size it)}
dictionary type [] wordSet
where ∧/{size it[i] = 0 or size it[i][0] = i for i in [0,size it)}

partialBindings type []int
where size it = Z+1 and ∧/{it[i] in [unknown,Z] for i in [1,size it)}
unknown const = 0

check proc (
pattern     in word,
dictionary  in dictionary,
bindings    in out partialBindings
) ⇒ (
matchCount out int
0 => failed
1 => this word is solved, don't try it again
>1 => we may have learned something but not everything
)
matches var []partialBindings := {}
available var := {false} @@ (Z+1)
loop for c in [A,Z]
available[c] := bindings[c] = unknown
end loop
i const = size pattern
loop for j in [0,size dictionary[i])
word const = dictionary[i][j]
assert size word = size pattern
workingBindings var := bindings
loop for x in [0,size pattern)
w const = word[x]
p const = pattern[x]
c const = workingBindings[p]
while c = w or c = unknown and available[w]
if c = unknown then
(workingBindings[p], available[w]) := (w, false)
end if
present
matches @:= {workingBindings}
end loop
end loop
matchCount := size matches = 0
if matchCount > 1 then
newBindings var := matches[0]
loop for i in [1,size matches)
loop for c in [A,Z]
if newBindings[c] ≠ matches[i][c] then
newBindings[c] := 0
end if
end loop
end loop
workingBindings = newBindings
elif matchCount > 0 then
workingBindings := matches[0]
end if
end proc

dictionary var dictionary := {{}} @@ 40
loop
n var int
while get (n)
word var word := {0} @@ n
loop for i in [0,n)
get word[i]
assert word[i] in [A,Z]
end loop
dictionary[n] @:= {word}
end loop

bindings var := {0}@@(Z+1)
loop  read the partial solution
for code in [A,Z]
get bindings[code]
end loop

clues var []word
loop  read the clues
n var int
while get(n)
clue var word := {0} @@ n
loop for i in [0,n)
get clue[i]
assert clue[i] in [A,Z]
end loop
clues @:= {clue}
end loop

failed var := false
loop while size clues > 0 and not failed
remainingClues var []word := {}
loop for i in [0,size clues)
outcome const = check(clues[i], dictionary, bindings)
until outcome = 0
if outcome > 1 then
remainingClues @:= {clues[i]}
end if
present
clues := {}
failed := true
absent
clues := newClues
failed := false
end
end loop
if failed then
print `"Failed"`, bindings
else
print `"Succeeded"`, bindings
end if

```