```  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
word_set   type [] word
where ∧/{size it[i-1] = size it[i] for i in [1,size it)}
dictionary type [] word_set
where ∧/{size it[i] = 0 or size it[i][0] = i for i in [0,size it)}

partial_bindings 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 partial_bindings
) ⇒ (
match_count 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 []partial_bindings := {}
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
working_bindings var := bindings
loop for x in [0,size pattern)
w const = word[x]
p const = pattern[x]
c const = working_bindings[p]
while c = w or c = unknown and available[w]
if c = unknown then
(working_bindings[p], available[w]) := (w, false)
end if
present
matches @:= {working_bindings}
end loop
end loop
match_count := size matches = 0
if match_count > 1 then
new_bindings var := matches[0]
loop for i in [1,size matches)
loop for c in [A,Z]
if new_bindings[c] ≠ matches[i][c] then
new_bindings[c] := 0
end if
end loop
end loop
working_bindings = new_bindings
elif match_count > 0 then
working_bindings := 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
remaining_clues var []word := {}
loop for i in [0,size clues)
outcome const = check(clues[i], dictionary, bindings)
until outcome = 0
if outcome > 1 then
remaining_clues @:= {clues[i]}
end if
present
clues := {}
failed := true
absent
clues := new_clues
failed := false
end
end loop
if failed then
print `"Failed"`, bindings
else
print `"Succeeded"`, bindings
end if

```