电话号码中的字母


23

问题:

您正在制作一个新电话,人们可以在其中输入专用电话号码,例如,1-800-program它们会自动转换为可用的电话号码,例如1-800-7764726(对于上一个示例)。

您的程序将接收包含数字,字母和破折号的任意长度的字符串,并将所有字母转换为相应的数字。

这是一个键盘,供参考:

键盘

规则:

  • 您的程序将收到一个字符串
  • 它将处理并返回/打印另一个字符串
  • 接受任何语言
  • 由于它是,所以最短的代码获胜

程序应该在输入中同时处理大小写字母吗?
mattnewport 2014年

3
@mattnewport-不,假设变量已被转换为小写字母
TheDoctor 2014年

Answers:


8

GolfScript,24个字符

{.96>{,91,'qx'+-,3/`}*}%

测试输入:

0123456789-abcdefghijklmnopqrstuvwxyz

测试输出:

0123456789-22233344455566677778889999

说明:

  • { }% 将花括号之间的代码应用于输入的每个字符。

  • .96>{ }* 当且仅当字符的ASCII码大于96(即,是小写字母)时,才在内括号之间执行代码。

  • 第一个,将字符转换为所有具有较低ASCII码的字符的列表,并91,'qx'+-从列表中过滤出所有ASCII码小于91的字符q以及字母和x。因此,例如,该字符a变成了6个字符的列表[\]^_`,而z变成了29个字符的列表[\]^_`abcdefghijklmnoprstuvwy

  • 第二个,计数列表中剩余的元素,然后3/将此计数除以三(四舍五入)。最后,`将结果数字(范围为2 – 9)变成一个字符串。

因此,根据规范,连字符和数字保持不变,而小写字母则根据参考键盘图映射为数字。该代码将实际上干净地通过所有可打印ASCII字符除了小写字母(其作为映射为描述)和字符{|}(其被映射到两个字符的字符串10)。非ASCII 8位输入将产生各种奇怪的数字输出。

毕竟,这仅使普通的bash解决方案击败了6个字符,这令人有些失望。


50

Bash,30岁

编辑:谢谢Doorknob消除了3个字符

tr a-z 22233344455566677778889

例:


10
您不能删除最后3 9秒钟吗?
门把手

16

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


3
数学不错。只是想说,您可以通过假设EOF为-1来减少1个字符,然后执行~(c=getchar())
user12205 2014年

您不能使用getch()代替getchar()吗?
starplusplus 2014年

严格来说,getch()它不是标准的C语言,因此我想它在ideone中没有链接。无论如何,我还是在MSVC中对其进行了测试,但它并没有真正令人遗憾地工作-由于它直接消耗键盘输入,因此无法退出程序,尽管它确实可以即时转换您键入的内容,这很巧妙。
mattnewport 2014年

4

Javascript-103个字符

alert(prompt().replace(/[a-z]/g,function(y){y=y.charCodeAt(0)-91;return y>27?9:y>24?8:y>20?7:~~(y/3)}))

1
我不知道您可以使用.replace来做到这一点。为您投票!
SuperJedi224

您可以替换为charCodeAt(0)charCodeAt()并可以使用箭头功能function(y)...来节省一些字节,并且~~(y/3)可以使用y/3|0
chau giang

3

Ruby,75个字符

gets.chars{|c|$><<"22233344455566677778889999#{c}"[[*?a..?z].index(c)||-1]}

使用不推荐使用的charswith块,并使用分别打印每个字母$><<。我也喜欢[[*?a..?z].index(c)||-1]; 如果是字母,它将抓住与该字母相对应的字符,如果不是,则抓住最后一个字符(碰巧是测试字符)。

Ruby,43(或35)个字符

公然从@ace偷东西;)

puts gets.tr'a-z','22233344455566677778889'

如果我可以使用变量s作为字符串在IRB中运行,则应减少8个字符:

s.tr'a-z','22233344455566677778889'

3

C ++-222个字符

迄今为止最长的解决方案:

#include<iostream>
#include<string>
#define o std::cout<<
int main(){std::string s;std::cin>>s;for(int i=0;i<s.size();i++){int j=s[i]-97;if(j<0)o s[i];if(0<=j&j<15)o 2+j/3;if(14<j&j<19)o 7;if(18<j&j<22)o 8;if(21<j&j<26)o 9;}}

1
大声笑,我认为最长的解决方案不是这里的目标……
Danny

@Danny C ++不适合代码高尔夫。Java和C#是我所知道的唯一更糟糕的语言(所有类,对象创建和用于输出的长名称...)。
Hosch250

我知道,我只是觉得您提到“最长的解决方案”真是可笑。
丹尼

3

Frink,92岁

我知道,这是一种相当冗长的语言。这将检查8个值而不是26个值,而不必键入比较。是否可以类似的方式减少上述“ 222333444 ..”解决方案中的任何一个?

使用内置结构,107

co=new OrderedList
co.insertAll[charList["cfilosv{"]]
println[input[""]=~%s/([a-z])/co.binarySearch[$1]+2/eg]

使用自定义递归函数92

fn[x,a]:=x<=(charList["cfilosv{"])@a?a+2:fn[x,a+1]
println[input[""]=~%s/([a-z])/fn[$1,0]/eg]

+1,用于将字符串翻译方法简化为8个字符的搜索。很好
Jonathan Van Matre 2014年

2

小话,79 70

输入为s:

s collect:[:c|' 22233344455566677778889999'at:1put:c;at:(($ato:$z)indexOf:c)+1]

可能不是最短的候选人-但可能有一个古老的技巧可以避免测试未找到的条件(在这种情况下,indexOf:返回0)。因此,不需要对字母进行特殊测试。但是,一些Smalltalks具有不可变的字符串,我们还需要4个字符(“副本”)。

哦,是更好的版本,它甚至可以处理70个字符的不可变字符串:

s collect:[:c|c,'22233344455566677778889999'at:(($ato:$z)indexOf:c)+1]

2

Mathematica 90

这遵循@ace解决方案的逻辑:

StringReplace[#,Thread[CharacterRange["A","Z"]->Characters@"22233344455566677778889999"]]&

StringReplace[#1,Thread[CharacterRange["A","Z"]-> 
Characters@"22233344455566677778889999"]]&["VI37889"]

8437889


Mma不接受您的箭头字符表示形式的复制/粘贴操作
belisarius博士2014年

另外,您不需要1in #1:)
belisarius博士2014年

贝利萨留,我将箭头改回去了,然后移开了1。仍然是90个字符,但剪切和粘贴将起作用。您当然知道使用单个字符箭头的动机。
DavidC 2014年

到那儿去了,做到了:)
belisarius博士

2

Perl,50岁

Ace bash答案的另一个明显副本

($_)=@ARGV;y/a-z/22233344455566677778889999/;print

1
该代码正常工作,但仍有改进的空间。让我们摆脱$ ARGV [0]并改用-pswitch,它使您可以很好地遍历stdin的每一行。当我们使用它时,y ///中的范围不需要放在方括号中。我们还可以摆脱三个9,只剩下一个,然后删除最后的分号: -p y/a-z/22233344455566677778889/ 在那里,为30 + 1 -p。感谢您使用Enterprise Chinese Perl高尔夫和优化服务,祝您愉快。
Chinese perl goth 2014年

2

R,很长但是很有趣

foo <- '1-800-splurghazquieaobuer57'
oof <- unlist(strsplit(foo,''))
#don't count that part - it's input formatting :-) 
digout <- unlist(strsplit('22233344455566677778889999','')) 
oof[oof%in%letters[1:26]] <- unlist(sapply(oof[oof%in%letters[1:26]], function(j) digout[which(letters[1:26]==j)] ))

2

k [32个字符]

{(.Q.a!|,/(4 3 4,5#3)#'|$2+!8)x}

用法

{(.Q.a!|,/(4 3 4,5#3)#'|$2+!8)x}"stack exchange"
"78225 39242643"

2

JavaScript,85岁

JavaScript永远不会赢得高尔夫大战,但是我喜欢它,并且我想做点不同于@ace潮流的事情。

alert(prompt().replace(/[a-z]/g,function(a){for(i=7;a<"dgjmptw{"[i--];);return i+4}))

2

PHP 141

不是最短的,而是更有趣的:

<?php foreach(str_split($argv[1])as$c){$v=ord($c);if($v>114){$v--;}if($v==121){$v--;}if($v<123&$v>96){echo chr(ceil($v/3+17));}else{echo$c;}}

更具可读性:

<?php 
foreach (str_split($argv[1]) as $c) {
  $v=ord($c);
  if ($v>114) {$v--;}
  if ($v==121){$v--;}
  if ($v<123 & $v>96){
    echo chr(ceil($v/3+17));
    } else {echo $c;}
}

OP说输入已经是小写字母,因此您可以删除strtolower
Einacio 2014年

2

Python 2.7、80

for c in raw_input():print'\b'+(`(ord(c)-97)/3+2-(c in('svyz'))`if c>'`'else c),

我是python的新手,所以我确定必须有一种进一步的方法,这是一个不同的方式,希望你们喜欢,我的上帝,python很漂亮!

运行示例:

  • 输入:01-800-abcdefghijklmnopqrstuvwxyz
  • 输出:01-800-22233344455566677778889999

2

T-SQL,216字节

在过去的两个晚上中,我花了很多时间精心创建一个数学序列函数,该函数可以正确舍入以从字母ASCII码生成正确的ASCII码。它在系数中的位数非常荒谬,但是有效。

但是,mattnewport的合理方法也可以在SQL中工作,而字节的成本却低得多,因此我无耻地放弃了自己的数学方法,而支持他。投票给他,这是一个优雅的解决方案!

这是我的:

DECLARE @p VARCHAR(MAX)='';WITH t AS(SELECT ASCII(LEFT(@s,1))c,2 i UNION ALL SELECT ASCII(SUBSTRING(@s,i,1)),i+1FROM t WHERE i<=LEN(@s))SELECT @p=@p+CHAR(CASE WHEN c>96THEN 20-c/122+5*c/16 ELSE c END)FROM t;SELECT @p

这使用递归CTE临时创建电话号码中的字符堆栈,并即时翻译字母,然后使用一些SQL技巧(SELECT @ p = @ p + columnValue)从CTE重组字符串,而无需另一个递归构造。

输出:

DECLARE @s VARCHAR(MAX)='1-800-abcdefghijklmnopqrstuvwxyz'
--above code runs here
1-800-22233344455566677778889999

2

Python 2.7版,66 65


Anakata的原著

for c in raw_input():print'\b'+(`(ord(c)-97)/3+2-(c in('svyz'))`if c>'`'else c),


进一步打高尔夫球

for c in input():print(ord(c)-91)/3-(c in('svyz'))if c>'`'else c,


我没有足够的声誉来评论@anakata的答案,所以我在这里发表了一篇单独的文章。我也有相同的想法(采用标准模数3),但无法弄清楚如何为s-z打印正确的数字。

无论如何,我对高尔夫进行了改进:

  • 改变raw_inputinput

  • 删除了多余的'\b'和括号以及单引号

  • 删除+2偏移量并将其放在原始减法中(97-(3 * 2)= 91)

经过Python 2.7.6解释器测试。根据规则,假设一个字符串输入。


您也可以删除)和if之间的空格
Willem

你是对的。好捕获
威廉

1

PHP,87

echo str_ireplace(range('a','z'),str_split('22233344455566677778889999'),fgets(STDIN));

1

q [38个字符]

{(.Q.a!"22233344455566677778889999")x}

受到@ace解决方案的启发

{(.Q.a!"22233344455566677778889999")x}"stack exchange"
"78225 39242643"

1

XQuery,71

BaseX被用作XQuery处理器。$i输入。

translate($i,"abcdefghijklmnopqrstuvwxyz","22233344455566677778889999")

不是最短的答案,而是相当简短且可读性强的答案。


1

Python,非常实用

由于每个人都在复制ace,因此我决定在提交问题之前先发布自己编写的代码:

def phonekeypad(text):
    c = ['','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
    st = ""
    for i in list(text):
        a = False
        for t in range(len(c)):
            if i in c[t]:
                st += str(t)
                a=True
        if a == False:
            st += str(i)
    return st

1

EcmaScript 6(103字节):

i.replace(/[a-z]/g,x=>keys(a='00abc0def0ghi0jkl0mno0pqrs0tuv0wxyz'.split(0)).find(X=>a[X].contains(x)))

期望i包含字符串。

在任何最新版本的Firefox中尝试。我没有尝试过谷歌浏览器。


1

Python 3、121

print("".join((lambda x:"22233344455566677778889999"[ord(x)-97] if ord(x)>96 and ord(x)<123 else x)(i) for i in input()))

1

93C Haskell

t[]_ a=a
t(b:c)(d:e)a
 |a==b=d
 |True=t c e a
y=map(t['a'..'z']"22233344455566677778889999")

用法

y "1-800-program"

1

C#140

using System.Linq;class P{static void Main(string[]a){System.Console.Write(string.Concat(a[0].Select(d=>(char)(d>96?20-d/122+5*d/16:d))));}}

0

蟒蛇

import string          
trans = str.maketrans(string.ascii_lowercase,
                      '22233344455566677778889999')                                                                                         
print("1-800-ask-usps".translate(trans))

0

ECMASCRIPT,101(带输入)

"1-800-PROGRAM".replace(/./g,function(c){
return "22233344455566677778889999"[c.charCodeAt(0)-65]||c})

添加换行符以使内容更加清晰。如果输入在变量中,则为85个字符。


0

Perl,54岁

print map{/[a-y]/?int(5/16*ord)-28:/z/?9:$_}<>=~/./gs

射门了,@ RobHoare还是击败了我四个角色。:)


0

QBasic,155

啊,回忆...

INPUT n$
FOR i=1 TO LEN(n$)
c$=MID$(n$,i,1)
a=ASC(c$)
IF 97>a THEN
PRINT c$;
ELSE IF 122>a THEN
PRINT STR$(a\3.2-28);
ELSE
PRINT 9;
END IF
NEXT i

这本来应该更短一些,但是我正在用repl.it进行测试,该代码不允许单行IF语句,并且如果将变量保留为off,则其行为会很奇怪NEXT i。它也无法识别该ASC功能,因此要运行代码,您需要在开始时添加以下解决方法:

DECLARE FUNCTION ASC(s$)
FUNCTION ASC(s$)
FOR j=1 TO 255
IF CHR$(j)=LEFT$(s$,1) THEN
ASC=j
END IF
NEXT j
END FUNCTION

(第二次运行它时,除非您删除该DECLARE FUNCTION行,否则解释器会抱怨,请转到图。)


0

R,110

s=strsplit(scan(,""),"")[[1]];i=grep("[a-z]",s);s[i]=sort(c(1:24%%8+2,7,9))[match(s[i],letters)];cat(s,sep="")

例:

> s=strsplit(scan(,""),"")[[1]];i=grep("[a-z]",s);s[i]=sort(c(1:24%%8+2,7,9))[match(s[i],letters)];cat(s,sep="")
1: 1-800-program
2: 
Read 1 item
1-800-7764726
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.