Textonyms

From Rosetta Code
Textonyms is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

When entering text on a phone's digital pad it is possible that a particular combination of digits corresponds to more than one word. Such are called textonyms.

Assuming the keys are as follows:

    2 -> ABC
    3 -> DEF
    4 -> GHI
    5 -> JKL
    6 -> MNO
    7 -> PQRS
    8 -> TUV
    9 -> WXYZ  

The task is to write a program that finds textonyms in a list of words such as Textonyms/wordlist or [1].

The task should produce a report:

There are #{0} words in #{1} which can be represnted by the Textonyms mapping.
They require #{2} digit combinations to represent them.
#{3} digit combinations represent Textonyms.

Where:

#{0} is the number of words in the list which can be represnted by the Textonyms mapping.
#{1} is the URL of the wordlist being used.
#{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.

 2748424767 -> "Briticisms", "criticisms"

Extra credit:

Use a word list and keypad mapping other than English.

Perl

This uses a file named "words.txt" as the dictionary. <lang perl>sub find { my @m = qw/$ $ abc def ghi jkl mno pqrs tvu wxyz/; (my $r = shift) =~ s{(\d)}{[$m[$1]]}g; grep /^$r$/i, split ' ', `cat words.txt`; # cats don't run on windows }

print join("\n", $_, find($_)), "\n\n" for @ARGV</lang> Usage:

./textnym.pl 7353284667 7361672
7353284667
rejections
selections

736672
senora

Incidentially, it sort of supports wildcards:

./textnym.pl '5432.*'
5432.*
liechtenstein

Ruby

<lang ruby> Textonyms = Hash.new {|n, g| n[g] = []} File.open("Textonyms.txt") do |file|

 file.each_line {|line|
   Textonyms[(n=line.chomp).gsub(/a|b|c|A|B|C/, '2').gsub(/d|e|f|D|E|F/, '3').gsub(/g|h|i|G|H|I/, '4').gsub(/p|q|r|s|P|Q|R|S/, '7')
                    .gsub(/j|k|l|J|K|L/, '5').gsub(/m|n|o|M|N|O/, '6').gsub(/t|u|v|T|U|V/, '8').gsub(/w|x|y|z|W|X|Y|Z/, '9')] += [n]
 }

end </lang>

Output:
puts "There are #{Textonyms.inject(0){|n,g| n+g[1].length}} words in #{"http://rosettacode.org/wiki/Textonyms/wordlist"} which can be represnted by the Textonyms mapping."
puts "They require #{Textonyms.length} digit combinations to represent them."

There are 132916 words in http://rosettacode.org/wiki/Textonyms/wordlist which can be represnted by the Textonyms mapping.
They require 117868 digit combinations to represent them.
puts Textonymes["7353284667"]

rejections
selections
puts Textonymes["736672"]

remora
senora