2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -10,7 +10,11 @@ Assuming the digit keys are mapped to letters as follows:
|
|||
8 -> TUV
|
||||
9 -> WXYZ
|
||||
|
||||
The task is to write a program that finds textonyms in a list of words such as [[Textonyms/wordlist]] or [http://www.puzzlers.org/pub/wordlists/unixdict.txt].
|
||||
|
||||
;Task:
|
||||
Write a program that finds textonyms in a list of words such as
|
||||
[[Textonyms/wordlist]] or
|
||||
[http://www.puzzlers.org/pub/wordlists/unixdict.txt unixdict.txt].
|
||||
|
||||
The task should produce a report:
|
||||
|
||||
|
|
@ -24,10 +28,13 @@ Where:
|
|||
#{2} is the number of digit combinations required to represent the words in #{0}.
|
||||
#{3} is the number of #{2} which represent more than one word.
|
||||
|
||||
At your discretion show a couple of examples of your solution displaying Textonys. e.g.
|
||||
At your discretion show a couple of examples of your solution displaying Textonys.
|
||||
|
||||
E.G.:
|
||||
|
||||
2748424767 -> "Briticisms", "criticisms"
|
||||
|
||||
Extra credit:
|
||||
|
||||
;Extra credit:
|
||||
Use a word list and keypad mapping other than English.
|
||||
<br><br>
|
||||
|
|
|
|||
136
Task/Textonyms/ALGOL-68/textonyms.alg
Normal file
136
Task/Textonyms/ALGOL-68/textonyms.alg
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
# find textonyms in a list of words #
|
||||
# use the associative array in the Associate array/iteration task #
|
||||
PR read "aArray.a68" PR
|
||||
|
||||
# returns the number of occurances of ch in text #
|
||||
PROC count = ( STRING text, CHAR ch )INT:
|
||||
BEGIN
|
||||
INT result := 0;
|
||||
FOR c FROM LWB text TO UPB text DO IF text[ c ] = ch THEN result +:= 1 FI OD;
|
||||
result
|
||||
END # count # ;
|
||||
|
||||
CHAR invalid char = "*";
|
||||
|
||||
# returns text with the characters replaced by their text digits #
|
||||
PROC to text = ( STRING text )STRING:
|
||||
BEGIN
|
||||
STRING result := text;
|
||||
FOR pos FROM LWB result TO UPB result DO
|
||||
CHAR c = to upper( result[ pos ] );
|
||||
IF c = "A" OR c = "B" OR c = "C" THEN result[ pos ] := "2"
|
||||
ELIF c = "D" OR c = "E" OR c = "F" THEN result[ pos ] := "3"
|
||||
ELIF c = "G" OR c = "H" OR c = "I" THEN result[ pos ] := "4"
|
||||
ELIF c = "J" OR c = "K" OR c = "L" THEN result[ pos ] := "5"
|
||||
ELIF c = "M" OR c = "N" OR c = "O" THEN result[ pos ] := "6"
|
||||
ELIF c = "P" OR c = "Q" OR c = "R" OR c = "S" THEN result[ pos ] := "7"
|
||||
ELIF c = "T" OR c = "U" OR c = "V" THEN result[ pos ] := "8"
|
||||
ELIF c = "W" OR c = "X" OR c = "Y" OR c = "Z" THEN result[ pos ] := "9"
|
||||
ELSE # not a character that can be encoded # result[ pos ] := invalid char
|
||||
FI
|
||||
OD;
|
||||
result
|
||||
END # to text # ;
|
||||
|
||||
# read the list of words and store in an associative array #
|
||||
|
||||
CHAR separator = "/"; # character that will separate the textonyms #
|
||||
|
||||
IF FILE input file;
|
||||
STRING file name = "unixdict.txt";
|
||||
open( input file, file name, stand in channel ) /= 0
|
||||
THEN
|
||||
# failed to open the file #
|
||||
print( ( "Unable to open """ + file name + """", newline ) )
|
||||
ELSE
|
||||
# file opened OK #
|
||||
BOOL at eof := FALSE;
|
||||
# set the EOF handler for the file #
|
||||
on logical file end( input file, ( REF FILE f )BOOL:
|
||||
BEGIN
|
||||
# note that we reached EOF on the #
|
||||
# latest read #
|
||||
at eof := TRUE;
|
||||
# return TRUE so processing can continue #
|
||||
TRUE
|
||||
END
|
||||
);
|
||||
REF AARRAY words := INIT LOC AARRAY;
|
||||
INT word count := 0;
|
||||
INT combinations := 0;
|
||||
INT multiple count := 0;
|
||||
INT max length := 0;
|
||||
WHILE STRING word;
|
||||
get( input file, ( word, newline ) );
|
||||
NOT at eof
|
||||
DO
|
||||
STRING text word = to text( word );
|
||||
IF count( text word, invalid char ) = 0 THEN
|
||||
# the word can be fully encoded #
|
||||
word count +:= 1;
|
||||
INT length := ( UPB word - LWB word ) + 1;
|
||||
IF length > max length THEN
|
||||
# this word is longer than the maximum length found so far #
|
||||
max length := length
|
||||
FI;
|
||||
IF ( words // text word ) = "" THEN
|
||||
# first occurance of this encoding #
|
||||
combinations +:= 1;
|
||||
words // text word := word
|
||||
ELSE
|
||||
# this encoding has already been used #
|
||||
IF count( words // text word, separator ) = 0
|
||||
THEN
|
||||
# this is the second time this encoding is used #
|
||||
multiple count +:= 1
|
||||
FI;
|
||||
words // text word +:= separator + word
|
||||
FI
|
||||
FI
|
||||
OD;
|
||||
# close the file #
|
||||
close( input file );
|
||||
|
||||
# find the maximum number of textonyms #
|
||||
|
||||
INT max textonyms := 0;
|
||||
|
||||
REF AAELEMENT e := FIRST words;
|
||||
WHILE e ISNT nil element DO
|
||||
INT textonyms := count( value OF e, separator );
|
||||
IF textonyms > max textonyms
|
||||
THEN
|
||||
max textonyms := textonyms
|
||||
FI;
|
||||
e := NEXT words
|
||||
OD;
|
||||
|
||||
print( ( "There are ", whole( word count, 0 ), " words in ", file name, " which can be represented by the digit key mapping.", newline ) );
|
||||
print( ( "They require ", whole( combinations, 0 ), " digit combinations to represent them.", newline ) );
|
||||
print( ( whole( multiple count, 0 ), " combinations represent Textonyms.", newline ) );
|
||||
|
||||
# show the textonyms with the maximum number #
|
||||
print( ( "The maximum number of textonyms for a particular digit key mapping is ", whole( max textonyms + 1, 0 ), " as follows:", newline ) );
|
||||
e := FIRST words;
|
||||
WHILE e ISNT nil element DO
|
||||
IF INT textonyms := count( value OF e, separator );
|
||||
textonyms = max textonyms
|
||||
THEN
|
||||
print( ( " ", key OF e, " encodes ", value OF e, newline ) )
|
||||
FI;
|
||||
e := NEXT words
|
||||
OD;
|
||||
|
||||
# show the textonyms with the maximum length #
|
||||
print( ( "The longest words are ", whole( max length, 0 ), " chracters long", newline ) );
|
||||
print( ( "Encodings with this length are:", newline ) );
|
||||
e := FIRST words;
|
||||
WHILE e ISNT nil element DO
|
||||
IF max length = ( UPB key OF e - LWB key OF e ) + 1
|
||||
THEN
|
||||
print( ( " ", key OF e, " encodes ", value OF e, newline ) )
|
||||
FI;
|
||||
e := NEXT words
|
||||
OD;
|
||||
|
||||
FI
|
||||
104
Task/Textonyms/Io/textonyms.io
Normal file
104
Task/Textonyms/Io/textonyms.io
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
main := method(
|
||||
setupLetterToDigitMapping
|
||||
|
||||
file := File clone openForReading("./unixdict.txt")
|
||||
words := file readLines
|
||||
file close
|
||||
|
||||
wordCount := 0
|
||||
textonymCount := 0
|
||||
dict := Map clone
|
||||
words foreach(word,
|
||||
(key := word asPhoneDigits) ifNonNil(
|
||||
wordCount = wordCount+1
|
||||
value := dict atIfAbsentPut(key,list())
|
||||
value append(word)
|
||||
if(value size == 2,textonymCount = textonymCount+1)
|
||||
)
|
||||
)
|
||||
write("There are ",wordCount," words in ",file name)
|
||||
writeln(" which can be represented by the digit key mapping.")
|
||||
writeln("They require ",dict size," digit combinations to represent them.")
|
||||
writeln(textonymCount," digit combinations represent Textonyms.")
|
||||
|
||||
samplers := list(maxAmbiquitySampler, noMatchingCharsSampler)
|
||||
dict foreach(key,value,
|
||||
if(value size == 1, continue)
|
||||
samplers foreach(sampler,sampler examine(key,value))
|
||||
)
|
||||
samplers foreach(sampler,sampler report)
|
||||
)
|
||||
|
||||
setupLetterToDigitMapping := method(
|
||||
fromChars := Sequence clone
|
||||
toChars := Sequence clone
|
||||
list(
|
||||
list("ABC", "2"), list("DEF", "3"), list("GHI", "4"),
|
||||
list("JKL", "5"), list("MNO", "6"), list("PQRS","7"),
|
||||
list("TUV", "8"), list("WXYZ","9")
|
||||
) foreach( map,
|
||||
fromChars appendSeq(map at(0), map at(0) asLowercase)
|
||||
toChars alignLeftInPlace(fromChars size, map at(1))
|
||||
)
|
||||
|
||||
Sequence asPhoneDigits := block(
|
||||
str := call target asMutable translate(fromChars,toChars)
|
||||
if( str contains(0), nil, str )
|
||||
) setIsActivatable(true)
|
||||
)
|
||||
|
||||
maxAmbiquitySampler := Object clone do(
|
||||
max := list()
|
||||
samples := list()
|
||||
examine := method(key,textonyms,
|
||||
i := key size - 1
|
||||
if(i > max size - 1,
|
||||
max setSize(i+1)
|
||||
samples setSize(i+1)
|
||||
)
|
||||
nw := textonyms size
|
||||
nwmax := max at(i)
|
||||
if( nwmax isNil or nw > nwmax,
|
||||
max atPut(i,nw)
|
||||
samples atPut(i,list(key,textonyms))
|
||||
)
|
||||
)
|
||||
report := method(
|
||||
writeln("\nExamples of maximum ambiquity for each word length:")
|
||||
samples foreach(sample,
|
||||
sample ifNonNil(
|
||||
writeln(" ",sample at(0)," -> ",sample at(1) join(" "))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
noMatchingCharsSampler := Object clone do(
|
||||
samples := list()
|
||||
examine := method(key,textonyms,
|
||||
for(i,0,textonyms size - 2 ,
|
||||
for(j,i+1,textonyms size - 1,
|
||||
if( _noMatchingChars(textonyms at(i), textonyms at(j)),
|
||||
samples append(list(textonyms at(i),textonyms at(j)))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
_noMatchingChars := method(t1,t2,
|
||||
t1 foreach(i,ich,
|
||||
if(ich == t2 at(i), return false)
|
||||
)
|
||||
true
|
||||
)
|
||||
report := method(
|
||||
write("\nThere are ",samples size," textonym pairs which ")
|
||||
writeln("differ at each character position.")
|
||||
if(samples size > 10, writeln("The ten largest are:"))
|
||||
samples sortInPlace(at(0) size negate)
|
||||
if(samples size > 10,samples slice(0,10),samples) foreach(sample,
|
||||
writeln(" ",sample join(" ")," -> ",sample at(0) asPhoneDigits)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
main
|
||||
55
Task/Textonyms/Lua/textonyms.lua
Normal file
55
Task/Textonyms/Lua/textonyms.lua
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
-- Global variables
|
||||
http = require("socket.http")
|
||||
keys = {"VOICEMAIL", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}
|
||||
dictFile = "http://www.puzzlers.org/pub/wordlists/unixdict.txt"
|
||||
|
||||
-- Return the sequence of keys required to type a given word
|
||||
function keySequence (str)
|
||||
local sequence, noMatch, letter = ""
|
||||
for pos = 1, #str do
|
||||
letter = str:sub(pos, pos)
|
||||
for i, chars in pairs(keys) do
|
||||
noMatch = true
|
||||
if chars:match(letter) then
|
||||
sequence = sequence .. tostring(i)
|
||||
noMatch = false
|
||||
break
|
||||
end
|
||||
end
|
||||
if noMatch then return nil end
|
||||
end
|
||||
return tonumber(sequence)
|
||||
end
|
||||
|
||||
-- Generate table of words grouped by key sequence
|
||||
function textonyms (dict)
|
||||
local combTable, keySeq = {}
|
||||
for word in dict:gmatch("%S+") do
|
||||
keySeq = keySequence(word)
|
||||
if keySeq then
|
||||
if combTable[keySeq] then
|
||||
table.insert(combTable[keySeq], word)
|
||||
else
|
||||
combTable[keySeq] = {word}
|
||||
end
|
||||
end
|
||||
end
|
||||
return combTable
|
||||
end
|
||||
|
||||
-- Analyse sequence table and print details
|
||||
function showReport (keySeqs)
|
||||
local wordCount, seqCount, tCount = 0, 0, 0
|
||||
for seq, wordList in pairs(keySeqs) do
|
||||
wordCount = wordCount + #wordList
|
||||
seqCount = seqCount + 1
|
||||
if #wordList > 1 then tCount = tCount + 1 end
|
||||
end
|
||||
print("There are " .. wordCount .. " words in " .. dictFile)
|
||||
print("which can be represented by the digit key mapping.")
|
||||
print("They require " .. seqCount .. " digit combinations to represent them.")
|
||||
print(tCount .. " digit combinations represent Textonyms.")
|
||||
end
|
||||
|
||||
-- Main procedure
|
||||
showReport(textonyms(http.request(dictFile)))
|
||||
45
Task/Textonyms/PowerShell/textonyms.psh
Normal file
45
Task/Textonyms/PowerShell/textonyms.psh
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
$url = "http://www.puzzlers.org/pub/wordlists/unixdict.txt"
|
||||
$file = "$env:TEMP\unixdict.txt"
|
||||
(New-Object System.Net.WebClient).DownloadFile($url, $file)
|
||||
$unixdict = Get-Content -Path $file
|
||||
|
||||
[string]$alpha = "abcdefghijklmnopqrstuvwxyz"
|
||||
[string]$digit = "22233344455566677778889999"
|
||||
|
||||
$table = [ordered]@{}
|
||||
|
||||
for ($i = 0; $i -lt $alpha.Length; $i++)
|
||||
{
|
||||
$table.Add($alpha[$i], $digit[$i])
|
||||
}
|
||||
|
||||
$words = foreach ($word in $unixdict)
|
||||
{
|
||||
if ($word -match "^[a-z]*$")
|
||||
{
|
||||
[PSCustomObject]@{
|
||||
Word = $word
|
||||
Number = ($word.ToCharArray() | ForEach-Object {$table.$_}) -join ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$digitCombinations = $words | Group-Object -Property Number
|
||||
|
||||
$textonyms = $digitCombinations | Where-Object -Property Count -GT 1 | Sort-Object -Property Count -Descending
|
||||
|
||||
Write-Host ("There are {0} words in {1} which can be represented by the digit key mapping." -f $words.Count, $url)
|
||||
Write-Host ("They require {0} digit combinations to represent them." -f $digitCombinations.Count)
|
||||
Write-Host ("{0} digit combinations represent Textonyms.`n" -f $textonyms.Count)
|
||||
|
||||
Write-Host "Top 5 in ambiguity:"
|
||||
$textonyms | Select-Object -First 5 -Property Count,
|
||||
@{Name="Textonym"; Expression={$_.Name}},
|
||||
@{Name="Words" ; Expression={$_.Group.Word -join ", "}} | Format-Table -AutoSize
|
||||
Write-Host "Top 5 in length:"
|
||||
$textonyms | Sort-Object {$_.Name.Length} -Descending |
|
||||
Select-Object -First 5 -Property @{Name="Length" ; Expression={$_.Name.Length}},
|
||||
@{Name="Textonym"; Expression={$_.Name}},
|
||||
@{Name="Words" ; Expression={$_.Group.Word -join ", "}} | Format-Table -AutoSize
|
||||
|
||||
Remove-Item -Path $file -Force -ErrorAction SilentlyContinue
|
||||
|
|
@ -1,47 +1,49 @@
|
|||
/*REXX program counts the number of textonyms are in a file (dictionary)*/
|
||||
parse arg iFID . /*get optional fileID of the file*/
|
||||
if iFID=='' then iFID='UNIXDICT.TXT' /*filename of the word dictionary*/
|
||||
@.=0 /*digit combinations placeholder.*/
|
||||
!.=; $.= /*sparse array of textonyms;words*/
|
||||
alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZ' /*supported alphabet to be used. */
|
||||
digitKey= 22233344455566677778889999 /*translated alphabet to dig key.*/
|
||||
digKey=0; wordCount=0 /*# digit combinations; wordCount*/
|
||||
ills=0; dups=0; longest=0; mostus=0 /*illegals; duplicate words; lit.*/
|
||||
first=0; last=0; long=0; most=0 /*for: first, last, longest, ··· */
|
||||
call linein iFID, 1, 0 /*point to the first char in dict*/
|
||||
#=0 /*number of textonyms in the file*/
|
||||
/* [↑] ───in case file is open.*/
|
||||
do j=1 while lines(iFID)\==0 /*keep reading until exhausted. */
|
||||
x=linein(iFID); y=x; upper x /*get a word and uppercase it. */
|
||||
if \datatype(x,'U') then do; ills=ills+1; iterate; end /*illegal? */
|
||||
if $.x\=='' then do; dups=dups+1; iterate; end /*duplicate?*/
|
||||
else $.x=. /*indicate it's a righteous word.*/
|
||||
wordCount=wordCount+1 /*bump the word count (for file).*/
|
||||
z=translate(x, digitKey, alphabet) /*build translated digit key word*/
|
||||
@.z=@.z+1 /*flag the digit key word exists.*/
|
||||
!.z=!.z y; _=words(!.z) /*build a list of same digit key.*/
|
||||
if _>most then do; mostus=z; most=_; end /*remember mostus digKeys.*/
|
||||
if @.z==2 then do; #=#+1 /*bump the count of the textonyms*/
|
||||
if first==0 then first=z /*the first textonym found*/
|
||||
last=z /* " last " " */
|
||||
_=length(!.z) /*length of the digit key.*/
|
||||
if _>longest then long=z /*is this the longest ? */
|
||||
longest=max(_, longest) /*now, shoot for this len.*/
|
||||
end /* [↑] discretionary stuff*/
|
||||
if @.z\==1 then iterate /*Does it already exist? Skip it*/
|
||||
digKey=digKey+1 /*bump count of digit key words. */
|
||||
/*REXX program counts and displays the number of textonyms that are in a dictionary file*/
|
||||
parse arg iFID . /*obtain optional fileID from the C.L. */
|
||||
if iFID=='' then iFID='UNIXDICT.TXT' /*Not specified? Then use the default.*/
|
||||
@.=0 /*the placeholder of digit combinations*/
|
||||
!.=; $.= /*sparse array of textonyms; words. */
|
||||
alphabet= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' /*the supported alphabet to be used. */
|
||||
digitKey= 22233344455566677778889999 /*translated alphabet to digit keys. */
|
||||
digKey=0; wordCount=0 /*number digit combinations; wordCount.*/
|
||||
ills=0; dups=0; longest=0; mostus=0 /*illegals; duplicated words; longest..*/
|
||||
first=0; last=0; long=0; most=0 /*first, last, longest, most counts. */
|
||||
call linein iFID, 1, 0 /*point to the first char in dictionary*/
|
||||
#=0 /*number of textonyms in file (so far).*/
|
||||
|
||||
do j=1 while lines(iFID)\==0 /*keep reading the file until exhausted*/
|
||||
x=linein(iFID); y=x; upper x /*get a word; save a copy; uppercase it*/
|
||||
if \datatype(x,'U') then do; ills=ills+1; iterate; end /*is it illegal? */
|
||||
if $.x\=='' then do; dups=dups+1; iterate; end /*is it duplicate?*/
|
||||
else $.x=. /*indicate that it's a righteous word. */
|
||||
wordCount=wordCount+1 /*bump the word count (for the file). */
|
||||
z=translate(x, digitKey, alphabet) /*build a translated digit key word. */
|
||||
@.z=@.z+1 /*flag that the digit key word exists. */
|
||||
!.z=!.z y; _=words(!.z) /*build list of equivalent digit key(s)*/
|
||||
if _>most then do; mostus=z; most=_; end /*remember the "mostus" digit keys. */
|
||||
if @.z==2 then do; #=#+1 /*bump the count of the textonyms. */
|
||||
if first==0 then first=z /*the first textonym found. */
|
||||
last=z /* " last " " */
|
||||
_=length(!.z) /*the length (# chars) of the digit key*/
|
||||
if _>longest then long=z /*is this the longest textonym ? */
|
||||
longest=max(_, longest) /*now, use this length as a target/goal*/
|
||||
end /* [↑] discretionary (extra credit). */
|
||||
if @.z\==1 then iterate /*Does it already exist? Then Skip it.*/
|
||||
digKey=digKey+1 /*bump the count of digit key words. */
|
||||
end /*j*/
|
||||
@@=' which can be represented by the digit key mapping.'
|
||||
say wordCount 'is the number of words in file "'iFID'"' @@
|
||||
if ills\==0 then say ills 'word's(ills) "contained illegal characters."
|
||||
if dups\==0 then say dups "duplicate word"s(dups) 'detected.'
|
||||
say 'They require' digKey "combination"s(digKey) 'to represent them.'
|
||||
say # 'digit combination's(#) "represent Textonyms."
|
||||
@whichCan...= 'which can be represented by digit key mapping.'
|
||||
@Ta = 'There are '
|
||||
say 'The dictionary file being used is: ' iFID
|
||||
say @Ta wordCount ' words in the file' @whichCan...
|
||||
if ills\==0 then say @Ta ills ' word's(ills) "contained illegal characters."
|
||||
if dups\==0 then say @Ta dups " duplicate word"s(dups) 'in the dictionary detected.'
|
||||
say 'The textonyms require ' digKey " combination"s(digKey) 'to represent them.'
|
||||
say @Ta # ' digit combination's(#) " that can represent Textonyms."
|
||||
say
|
||||
if first\==0 then say ' first digit key=' !.first
|
||||
if last\==0 then say ' last digit key=' !.last
|
||||
if long\==0 then say ' longest digit key=' !.long
|
||||
if most\==0 then say ' numerous digit key=' !.mostus ' ('most "words)"
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────S subroutine────────────────────────*/
|
||||
s: if arg(1)==1 then return ''; return 's' /*a simple pluralizer.*/
|
||||
if first\==0 then say ' first digit key=' !.first
|
||||
if last\==0 then say ' last digit key=' !.last
|
||||
if long\==0 then say ' longest digit key=' !.long
|
||||
if most\==0 then say ' numerous digit key=' !.mostus ' ('most "words)"
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
s: if arg(1)==1 then return ''; return "s" /*a simple pluralizer.*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue