Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -0,0 +1,87 @@
class
ANAGRAMS
create
make
feature
make
-- Set of Anagrams, containing most words.
local
count: INTEGER
do
read_wordlist
across
words as wo
loop
if wo.item.count > count then
count := wo.item.count
end
end
across
words as wo
loop
if wo.item.count = count then
across
wo.item as list
loop
io.put_string (list.item + "%T")
end
io.new_line
end
end
end
original_list: STRING = "unixdict.txt"
feature {NONE}
read_wordlist
-- Preprocessed wordlist for finding Anagrams.
local
l_file: PLAIN_TEXT_FILE
sorted: STRING
empty_list: LINKED_LIST [STRING]
do
create l_file.make_open_read_write (original_list)
l_file.read_stream (l_file.count)
wordlist := l_file.last_string.split ('%N')
l_file.close
create words.make (wordlist.count)
across
wordlist as w
loop
create empty_list.make
sorted := sort_letters (w.item)
words.put (empty_list, sorted)
if attached words.at (sorted) as ana then
ana.extend (w.item)
end
end
end
wordlist: LIST [STRING]
sort_letters (word: STRING): STRING
--Sorted in alphabetical order.
local
letters: SORTED_TWO_WAY_LIST [STRING]
do
create letters.make
create Result.make_empty
across
1 |..| word.count as i
loop
letters.extend (word.at (i.item).out)
end
across
letters as s
loop
Result.append (s.item)
end
end
words: HASH_TABLE [LINKED_LIST [STRING], STRING]
end

View file

@ -1,36 +1,34 @@
#define system.
#define system'collections.
#define system'routines.
#define system'io.
#define system'collections.
#define extensions.
#define extensions'text.
#define extensions'routines.
// --- Normalized ---
#symbol Normalized = (:aLiteral)
[
^ Summing new:(String new) foreach:(arrayControl sort:(literalControl toArray:aLiteral)) literal.
].
// --- Program ---
#class(extension) op
{
#method normalized
= self toArray ascendant summarize:(String new) literal.
}
#symbol program =
[
#var aDictionary := Dictionary new.
textFileControl forEachLine:"unixdict.txt" &do: aWord
File new &path:"unixdict.txt" run &eachLine: aWord
[
#var aKey := Normalized:aWord.
#var anItem := aDictionary getAt &key:aKey.
nil == anItem ?
#var aKey := aWord normalized.
#var anItem := aDictionary@aKey.
($nil == anItem) ?
[
anItem := List new.
aDictionary set &key:aKey &value:anItem.
anItem := ArrayList new.
aDictionary@aKey := anItem.
].
anItem += aWord.
].
listControl sort:aDictionary &with: (:aFormer:aLater) [ aFormer value length > aLater value length ].
controlEx foreach:aDictionary &top:20 &do: aPair [ consoleEx writeLine:(aPair value) ].
aDictionary array_list
sort: (:aFormer:aLater) [ aFormer length > aLater length ]
top:20 run &each: aPair [ console writeLine:aPair ].
].

View file

@ -0,0 +1,25 @@
defmodule Anagrams do
def find(file) do
File.read!(file)
|> String.split
|> Enum.map(&String.codepoints &1)
|> sort(%{})
|> Enum.group_by(fn {_,v} -> length(v) end)
|> Enum.max
|> print
end
defp sort([],m), do: m
defp sort([word|words],m) do
s = Enum.sort(word)
m = Dict.update(m, s, [word], fn val -> [word|val] end)
sort(words,m)
end
defp print({_,y}) do
Enum.each(y, fn {_,e} ->
Enum.map(e, &Enum.join(&1)) |> Enum.sort |> Enum.join(" ") |> IO.puts
end)
end
end
Anagrams.find("unixdict.txt")

View file

@ -0,0 +1,13 @@
File.stream!("unixdict.txt")
|> Stream.map(&String.strip &1)
|> Stream.map(&{&1, &1 |> String.codepoints |> Enum.sort |> Enum.join})
|> Enum.group_by(fn {_,y} -> y end)
|> Dict.values
|> Enum.group_by(&length(&1))
|> Enum.max
|> elem(1)
|> Enum.each(fn n -> Enum.map(n, fn {y,_} -> y end)
|> Enum.sort
|> Enum.join(" ")
|> IO.puts
end)

View file

@ -6,7 +6,7 @@ function anagram(wordlist)
hash = Dict() ; ananum = 0
for word in wordlist
sorted = CharString(sort(collect(word.data)))
hash[sorted] = [ get(hash, sorted, {}), word ]
hash[sorted] = [ get(hash, sorted, []), word ]
ananum = max(length(hash[sorted]), ananum)
end
collect(values(filter((x,y)-> length(y) == ananum, hash)))

View file

@ -1,73 +1,24 @@
-- Build the word set
local set = {}
local file = io.open("unixdict.txt")
local str = file:read()
while str do
table.insert(set,str)
str = file:read()
function sort(word)
local bytes = {word:byte(1, -1)}
table.sort(bytes)
return string.char(unpack(bytes))
end
-- Build the anagram tree
local tree = {}
for i,word in next,set do
-- Sort a string from lowest char to highest
local function sortString(str)
if #str <= 1 then
return str
end
local less = ''
local greater = ''
local pivot = str:byte(1)
for i = 2, #str do
if str:byte(i) <= pivot then
less = less..(str:sub(i,i))
else
greater = greater..(str:sub(i,i))
end
end
return sortString(less)..str:sub(1,1)..sortString(greater)
end
local sortchar = sortString(word)
if not tree[#word] then tree[#word] = {} end
local node = tree[#word]
for i = 1,#word do
if not node[sortchar:byte(i)] then
node[sortchar:byte(i)] = {}
end
node = node[sortchar:byte(i)]
end
table.insert(node,word)
-- Read in and organize the words.
-- word_sets[<alphabetized_letter_list>] = {<words_with_those_letters>}
local word_sets = {}
local max_size = 0
for word in io.lines('unixdict.txt') do
local key = sort(word)
if word_sets[key] == nil then word_sets[key] = {} end
table.insert(word_sets[key], word)
max_size = math.max(max_size, #word_sets[key])
end
-- Gather largest groups by gathering all groups of current max size and droping gathered groups and increasing max when a new largest group is found
local max = 0
local set = {}
local function recurse (tree)
local num = 0
for i,node in next,tree do
if type(node) == 'string' then
num = num + 1
end
end
if num > max then
set = {}
max = num
end
if num == max then
local newset = {}
for i,node in next,tree do
if type(node) == 'string' then
table.insert(newset,node)
end
end
table.insert(set,newset)
end
for i,node in next,tree do
if type(node) == 'table' then
recurse(node)
end
end
-- Print out the answer sets.
for _, word_set in pairs(word_sets) do
if #word_set == max_size then
for _, word in pairs(word_set) do io.write(word .. ' ') end
print('') -- Finish with a newline.
end
end
recurse (tree)
for i,v in next,set do io.write (i..':\t')for j,u in next,v do io.write (u..' ') end print() end

View file

@ -1,30 +1,30 @@
/*REXX program finds words with the largest set of anagrams (same size).*/
iFID='unixdict.txt' /*input file identifier, # words.*/
hc=; !.=; #.=0; w=0; words=0; most=0 /*initialize some REXX variables.*/
/* [↓] read entire file by line.*/
do recs=0 while lines(iFID)\==0 /*Got data? Then read a record.*/
x=space(linein(iFID),0) /*pick off a word from the input.*/
L=length(x); if L<3 then iterate /*onesies and twosies can't win. */
if \datatype(x,'M') then iterate /*filter out nonanagramable words*/
words=words+1 /*count of (useable) words. */
z=sortA(x) /*sort the letters in the word. */
!.z=!.z x; #.z=#.z+1 /*append it to !.z, bump the ctr.*/
if #.z>most then do; hc=z; most=#.z; if L>w then w=L; iterate; end
if #.z==most then hc=hc z /*append sorted word─►max anagram*/
end /*recs*/ /*hc◄─list of high count anagrams.*/
say '' recs 'words in the dictionary file: ' iFID
/*REXX program finds words with the largest set of anagrams (of the same size)*/
iFID='unixdict.txt' /*the dictionary input File IDentifier.*/
$=; !.=; #.=0; w=0; uw=0; most=0 /*initialize a bunch of REXX variables.*/
/* [↓] read the entire file (by lines)*/
do while lines(iFID)\==0 /*Got any data? Then read a record. */
@=space(linein(iFID),0) /*pick off a word from the input line. */
L=length(@); if L<3 then iterate /*onesies and twosies words can't win. */
if \datatype(@,'M') then iterate /*ignore any non─anagramable words. */
uw=uw+1 /*count of the (useable) words in file.*/
z=sortA(@) /*sort the letters in the word. */
!.z=!.z @; #.z=#.z+1 /*append it to !.z; bump the counter. */
if #.z>most then do; $=z; most=#.z; if L>w then w=L; iterate; end
if #.z==most then $=$ z /*append the sorted word──◄ max anagram*/
end /*while*/ /*$ ►── list of high count anagrams. */
say '' uw 'useable words in the dictionary file: ' iFID
say
do m=1 for words(hc); z=subword(hc,m,1) /*high count anagrams*/
say ' ' left(subword(!.z,1,1),w) ' [anagrams: ' subword(!.z,2)"]"
end /*m*/ /* W is the maximum width word. */
do m=1 for words($); z=subword($,m,1) /*high count of anagrams.*/
say ' ' left(subword(!.z,1,1),w) ' [anagrams: ' subword(!.z,2)"]"
end /*m*/ /*W is the maximum width of any word.*/
say
say ' Found' words(hc) "words (each of which have" #.z-1 'anagrams).'
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────SORTA subroutine────────────────────*/
sortA: procedure; arg char +1 xx _. /*get 1st letter of arg, _.=null.*/
_.char=char /*no need to concatenate 1st char*/
/*[↓] put letters alphabetically.*/
do length(xx); parse var xx char +1 xx; _.char=_.char||char; end
/*reassemble word, sorted letters*/
return _.a||_.b||_.c||_.d||_.e||_.f||_.g||_.h||_.i||_.j||_.k||_.l||_.m||,
_.n||_.o||_.p||_.q||_.r||_.s||_.t||_.u||_.v||_.w||_.x||_.y||_.z
say ' Found' words($) "words (each of which have" #.z-1 'anagrams).'
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────SORTA subroutine──────────────────────────*/
sortA: procedure; arg char +1 xx,@. /*get the first letter of arg; @.=null*/
@.char=char /*no need to concatenate the first char*/
/*[↓] sort/put letters alphabetically.*/
do length(xx); parse var xx char +1 xx; @.char=@.char || char; end
/*reassemble word with sorted letters. */
return @.a||@.b||@.c||@.d||@.e||@.f||@.g||@.h||@.i||@.j||@.k||@.l||@.m||,
@.n||@.o||@.p||@.q||@.r||@.s||@.t||@.u||@.v||@.w||@.x||@.y||@.z

View file

@ -1,28 +1,28 @@
/*REXX program finds words with the largest set of anagrams (same size).*/
iFID='unixdict.txt' /*input file identifier, # words.*/
hc=; !.=; #.=0; w=0; words=0; most=0 /*initialize some REXX variables.*/
/* [↓] read entire file by line.*/
do recs=0 while lines(iFID)\==0 /*Got data? Then read a record.*/
x=space(linein(iFID),0) /*pick off a word from the input.*/
L=length(x); if L<3 then iterate /*onesies and twosies can't win. */
if \datatype(x,'M') then iterate /*filter out nonanagramable words*/
words=words+1 /*count of (useable) words. */
parse upper var x y +1 u _. /*get uppercase X & nullify "_." */
xx='?'y; _.xx=y /*get 1st letter (special case).*/
/*[↓] put letters alphabetically.*/
do length(u); parse var u y +1 u; xx='?'y; _.xx=_.xx||y; end
/*reassemble word, sorted letters*/
z=_.?a||_.?b||_.?c||_.?d||_.?e||_.?f||_.?g||_.?h||_.?i||_.?j||_.?k||_.?l||_.?m||,
_.?n||_.?o||_.?p||_.?q||_.?r||_.?s||_.?t||_.?u||_.?v||_.?w||_.?x||_.?y||_.?z
!.z=!.z x; #.z=#.z+1 /*append it to !.z, bump the ctr.*/
if #.z>most then do; hc=z; most=#.z; if L>w then w=L; iterate; end
if #.z==most then hc=hc z /*append sorted word─►hc anagrams*/
end /*recs*/ /*hc◄─list of high count anagrams*/
say '' recs 'words in the dictionary file: ' iFID
/*REXX program finds words with the largest set of anagrams (of the same size)*/
iFID='unixdict.txt' /*the dictionary input File IDentifier.*/
$=; !.=; #.=0; ww=0; uw=0; most=0 /*initialize a bunch of REXX variables.*/
/* [↓] read the entire file (by lines)*/
do while lines(iFID)\==0 /*Got any data? Then read a record. */
@=space(linein(iFID),0) /*pick off a word from the input line. */
LL=length(@); if LL<3 then iterate /*onesies and twosies (words) can't win*/
if \datatype(@,'M') then iterate /*ignore any non─anagramable words. */
uw=uw+1 /*count of the (useable) words in file.*/
parse upper var @ _ +1 xx @. /*get uppercase @ and nullify @. */
@._=_ /*get the first letter (special case). */
/*[↓] sort/put letters alphabetically.*/
do LL-1; parse var xx _ +1 xx; @._=@._||_; end /*get rest of word.*/
/*reassemble word with sorted letters. */
zz=@.a||@.b||@.c||@.d||@.e||@.f||@.g||@.h||@.i||@.j||@.k||@.l||@.m||,
@.n||@.o||@.p||@.q||@.r||@.s||@.t||@.u||@.v||@.w||@.x||@.y||@.z
!.zz=!.zz @; #.zz=#.zz+1 /*append it to !.zz; bump the counter.*/
if #.zz>most then do; $=zz; most=#.zz; if LL>ww then ww=LL; iterate; end
if #.zz==most then $=$ zz /*append the sorted word──◄ $ anagrams.*/
end /*while*/
say '' uw 'useable words in the dictionary file: ' iFID
say
do m=1 for words(hc); z=subword(hc,m,1) /*high count anagrams*/
say ' ' left(subword(!.z,1,1),w) ' [anagrams: ' subword(!.z,2)"]"
end /*m*/ /* W is the maximum width word. */
do m=1 for words($); z=subword($,m,1) /*high count of anagrams.*/
say ' ' left(subword(!.z,1,1),ww) ' [anagrams: ' subword(!.z,2)"]"
end /*m*/ /*WW is the maximum width of any word.*/
say
say ' Found' words(hc) "words (each of which have" #.z-1 'anagrams).'
/*stick a fork in it, we're done.*/
say ' Found' words($) "words (each of which have" #.z-1 'anagrams).'
/*stick a fork in it, we're all done. */

View file

@ -1,28 +1,28 @@
/*REXX program finds words with the largest set of anagrams (same size).*/
iFID='unixdict.txt' /*input file identifier, # words.*/
hc=; !.=; #.=0; ww=0; words=0; most=0 /*initialize some REXX variables.*/
/* [↓] read entire file by line.*/
do recs=0 while lines(iFID)\==0 /*Got data? Then read a record.*/
@=space(linein(iFID),0) /*pick off a word from the input.*/
LL=length(@); if LL<3 then iterate /*onesies and twosies can't win. */
if \datatype(@,'M') then iterate /*exclude non-anagramable words. */
words=words+1 /*count of (useable) words. */
parse upper var @ _ +1 xx _. /*get uppercase @ & nullify "_." */
_._=_ /*get 1st letter (special case).*/
/*[↓] put letters alphabetically.*/
do LL-1; parse var xx _ +1 xx; _._=_._||_; end /*rest of word.*/
/*reassemble word, sorted letters*/
zz=_.a||_.b||_.c||_.d||_.e||_.f||_.g||_.h||_.i||_.j||_.k||_.l||_.m||,
_.n||_.o||_.p||_.q||_.r||_.s||_.t||_.u||_.v||_.w||_.x||_.y||_.z
!.zz=!.zz @; #.zz=#.zz+1 /*append it to !.zz, bump the ctr.*/
if #.zz>most then do; hc=zz; most=#.zz; if LL>ww then ww=LL; iterate; end
if #.zz==most then hc=hc zz /*append sorted word─►hc anagrams*/
end /*recs*/ /*this loop can't have 1-letter vars.*/
say '' recs 'words in the dictionary file: ' iFID
/*REXX program finds words with the largest set of anagrams (of the same size)*/
iFID='unixdict.txt' /*the dictionary input File IDentifier.*/
$=; !.=; #.=0; ww=0; uw=0; most=0 /*initialize a bunch of REXX variables.*/
/* [↓] read the entire file (by lines)*/
do while lines(iFID)\==0 /*Got any data? Then read a record. */
@=space(linein(iFID),0) /*pick off a word from the input line. */
LL=length(@); if LL<3 then iterate /*onesies and twosies (words) can't win*/
if \datatype(@,'M') then iterate /*ignore any non─anagramable words. */
uw=uw+1 /*count of the (useable) words in file.*/
parse upper var @ _ +1 xx '' @. /*get uppercase @ and nullify @. */
@._=_ /*get the first letter (special case). */
/*[↓] sort/put letters alphabetically.*/
do LL-1; parse var xx _ +1 xx; @._=@._||_; end /*get rest of word.*/
/*reassemble word with sorted letters. */
zz=@.a||@.b||@.c||@.d||@.e||@.f||@.g||@.h||@.i||@.j||@.k||@.l||@.m||,
@.n||@.o||@.p||@.q||@.r||@.s||@.t||@.u||@.v||@.w||@.x||@.y||@.z
!.zz=!.zz @; #.zz=#.zz+1 /*append it to !.zz; bump the counter.*/
if #.zz>most then do; $=zz; most=#.zz; if LL>ww then ww=LL; iterate; end
if #.zz==most then $=$ zz /*append the sorted word──► $ anagrams.*/
end /*while*/
say '' uw 'useable words in the dictionary file: ' iFID
say
do m=1 for words(hc); z=subword(hc,m,1) /*high count anagrams*/
say ' ' left(subword(!.z,1,1),ww) ' [anagrams: ' subword(!.z,2)"]"
end /*m*/ /* WW is the maximum width word. */
do m=1 for words($); z=subword($,m,1) /*high count of anagrams.*/
say ' ' left(subword(!.z,1,1),ww) ' [anagrams: ' subword(!.z,2)"]"
end /*m*/ /*WW is the maximum width of any word.*/
say
say ' Found' words(hc) "words (each of which have" #.z-1 'anagrams).'
/*stick a fork in it, we're done.*/
say ' Found' words($) "words (each of which have" #.z-1 'anagrams).'
/*stick a fork in it, we're all done. */

View file

@ -5,7 +5,7 @@ say 'u=' u
say 'L=' L
_.=
do k=1 for L /*keep truckin' for L chars. */
y = substr(u,k,1) /*get the next character in U. */
parse var u =(k) y +1 /*get Kth character in U string. */
xx = '?'y /*assign a prefixed char to XX. */
_.xx = _.xx || y /*append it to all the Y chars.*/
end /*do k*/ /*U now has the first char gone.*/

View file

@ -1,27 +1,27 @@
use std::collections::hashmap::{HashMap, Occupied, Vacant};
use std::io::File;
use std::io::BufferedReader;
use std::collections::HashMap;
use std::collections::hash_map::Entry::*;
use std::fs::File;
use std::io::{BufRead,BufReader};
use std::cmp;
fn sort_string(string: &str) -> String {
let mut chars = string.chars().collect::<Vec<char>>();
chars.sort();
String::from_chars(chars.as_slice())
let mut chars = string.chars().collect::<Vec<char>>();
chars.sort();
chars.into_iter().collect()
}
fn main () {
let path = Path::new("unixdict.txt");
let mut file = BufferedReader::new(File::open(&path));
let mut map = HashMap::new();
for line in file.lines().map(|s| s.unwrap()) {
let s = line.as_slice().trim();
match map.entry(sort_string(s)) {
Vacant(entry) => { entry.set(vec![s.into_string()]); },
Occupied(mut entry) => { entry.get_mut().push(s.into_string()); }
}
}
let max_length = map.values().fold(0, |s, v| cmp::max(s, v.len()));
for v in map.values().filter(|&v| v.len() == max_length) {
println!("{}", v.connect(" "))
}
let file = BufReader::new(File::open("unixdict.txt").unwrap());
let mut map = HashMap::new();
for line in file.lines() {
let s: String = line.unwrap().trim().into();
match map.entry(sort_string(&s)) {
Vacant(entry) => { entry.insert(vec![s]); },
Occupied(mut entry) => { entry.get_mut().push(s); }
}
}
let max_length = map.values().fold(0, |s, v| cmp::max(s, v.len()));
for v in map.values().filter(|&v| v.len() == max_length) {
println!("{}", v.join(" "))
}
}