Letters in phone numbers
Bash, 30
Edit: Thank you Doorknob for eliminating 3 chars
tr a-z 22233344455566677778889
Example:
C, 83 78 77 65 63 62
main(c){for(;~(c=getchar());putchar(c>96?20-c/122+5*c/16:c));}
http://ideone.com/qMsIFQ
GolfScript, 24 chars
{.96>{,91,'qx'+-,3/`}*}%
Test input:
0123456789-abcdefghijklmnopqrstuvwxyz
Test output:
0123456789-22233344455566677778889999
Explanation:
{ }%
applies the code between the braces to each character of the input..96>{ }*
executes the code between the inner braces if and only if the ASCII code of the character is greater than 96 (i.e. it is a lowercase letter).The first
,
turns the character into a list of all characters with lower ASCII codes, and91,'qx'+-
filters out all characters with ASCII codes less than 91, as well as the lettersq
andx
, from the list. Thus, for example, the charactera
gets turned into the 6-character list[\]^_`
, whilez
gets turned into the 29-character list[\]^_`abcdefghijklmnoprstuvwy
.The second
,
counts the elements remaining in the list, and3/
divides this count by three (rounding down). Finally, the`
turns the resulting number (in the range 2 – 9) into a string.
Thus, as per spec, hyphens and numbers are left unchanged, while lowercase letters are mapped into numbers according to the reference keypad diagram. The code will actually cleanly pass through all printable ASCII characters except for lowercase letters (which as mapped as described) and the characters {
, |
and }
(which are mapped to the two-character string 10
). Non-ASCII 8-bit input will produce all sorts of weird numeric output.
After all this, it's a bit disappointing that this only beats the trivial bash solution by just six chars.