83 lines
2.6 KiB
Text
83 lines
2.6 KiB
Text
% Keep a list of anagrams
|
|
anagrams = cluster is new, add, largest_size, sets
|
|
anagram_set = struct[letters: string, words: array[string]]
|
|
rep = array[anagram_set]
|
|
|
|
new = proc () returns (cvt)
|
|
return(rep$[])
|
|
end new
|
|
|
|
% Sort the letters in a string
|
|
sort = proc (s: string) returns (string)
|
|
chars: array[int] := array[int]$fill(0,256,0) % Assuming ASCII here
|
|
for c: char in string$chars(s) do
|
|
i: int := char$c2i(c)
|
|
chars[i] := chars[i] + 1
|
|
end
|
|
sorted: array[char] := array[char]$predict(1,string$size(s))
|
|
for i: int in array[int]$indexes(chars) do
|
|
for j: int in int$from_to(1,chars[i]) do
|
|
array[char]$addh(sorted,char$i2c(i))
|
|
end
|
|
end
|
|
return(string$ac2s(sorted))
|
|
end sort
|
|
|
|
% Add a word
|
|
add = proc (a: cvt, s: string)
|
|
letters: string := sort(s)
|
|
as: anagram_set
|
|
begin
|
|
for t_as: anagram_set in rep$elements(a) do
|
|
if t_as.letters = letters then
|
|
as := t_as
|
|
exit found
|
|
end
|
|
end
|
|
as := anagram_set${letters: letters, words: array[string]$[]}
|
|
rep$addh(a, as)
|
|
end except when found: end
|
|
array[string]$addh(as.words, s)
|
|
end add
|
|
|
|
% Find the size of the largest set
|
|
largest_size = proc (a: cvt) returns (int)
|
|
size: int := 0
|
|
for as: anagram_set in rep$elements(a) do
|
|
cur: int := array[string]$size(as.words)
|
|
if cur > size then size := cur end
|
|
end
|
|
return(size)
|
|
end largest_size
|
|
|
|
% Yield all sets of a given size
|
|
sets = iter (a: cvt, s: int) yields (sequence[string])
|
|
for as: anagram_set in rep$elements(a) do
|
|
if array[string]$size(as.words) = s then
|
|
yield(sequence[string]$a2s(as.words))
|
|
end
|
|
end
|
|
end sets
|
|
end anagrams
|
|
|
|
start_up = proc ()
|
|
an: anagrams := anagrams$new()
|
|
dict: stream := stream$open(file_name$parse("unixdict.txt"), "read")
|
|
while true do
|
|
anagrams$add(an, stream$getl(dict))
|
|
except when end_of_file: break end
|
|
end
|
|
stream$close(dict)
|
|
|
|
po: stream := stream$primary_output()
|
|
max: int := anagrams$largest_size(an)
|
|
stream$putl(po, "Largest amount of anagrams per set: " || int$unparse(max))
|
|
stream$putl(po, "")
|
|
|
|
for words: sequence[string] in anagrams$sets(an, max) do
|
|
for word: string in sequence[string]$elements(words) do
|
|
stream$putleft(po, word, 7)
|
|
end
|
|
stream$putl(po, "")
|
|
end
|
|
end start_up
|