问题:
您正在制作一个新电话,人们可以在其中输入专用电话号码,例如,1-800-program
它们会自动转换为可用的电话号码,例如1-800-7764726
(对于上一个示例)。
您的程序将接收包含数字,字母和破折号的任意长度的字符串,并将所有字母转换为相应的数字。
这是一个键盘,供参考:
规则:
- 您的程序将收到一个字符串
- 它将处理并返回/打印另一个字符串
- 接受任何语言
- 由于它是代码高尔夫球,所以最短的代码获胜
问题:
您正在制作一个新电话,人们可以在其中输入专用电话号码,例如,1-800-program
它们会自动转换为可用的电话号码,例如1-800-7764726
(对于上一个示例)。
您的程序将接收包含数字,字母和破折号的任意长度的字符串,并将所有字母转换为相应的数字。
这是一个键盘,供参考:
规则:
Answers:
{.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个字符,这令人有些失望。
main(c){for(;~(c=getchar());putchar(c>96?20-c/122+5*c/16:c));}
~(c=getchar())
getch()
代替getchar()
吗?
getch()
它不是标准的C语言,因此我想它在ideone中没有链接。无论如何,我还是在MSVC中对其进行了测试,但它并没有真正令人遗憾地工作-由于它直接消耗键盘输入,因此无法退出程序,尽管它确实可以即时转换您键入的内容,这很巧妙。
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)}))
charCodeAt(0)
,charCodeAt()
并可以使用箭头功能function(y)...
来节省一些字节,并且~~(y/3)
可以使用y/3|0
gets.chars{|c|$><<"22233344455566677778889999#{c}"[[*?a..?z].index(c)||-1]}
使用不推荐使用的chars
with块,并使用分别打印每个字母$><<
。我也喜欢[[*?a..?z].index(c)||-1]
; 如果是字母,它将抓住与该字母相对应的字符,如果不是,则抓住最后一个字符(碰巧是测试字符)。
公然从@ace偷东西;)
puts gets.tr'a-z','22233344455566677778889'
如果我可以使用变量s
作为字符串在IRB中运行,则应减少8个字符:
s.tr'a-z','22233344455566677778889'
迄今为止最长的解决方案:
#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;}}
我知道,这是一种相当冗长的语言。这将检查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]
输入为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]
这遵循@ace解决方案的逻辑:
StringReplace[#,Thread[CharacterRange["A","Z"]->Characters@"22233344455566677778889999"]]&
例
StringReplace[#1,Thread[CharacterRange["A","Z"]->
Characters@"22233344455566677778889999"]]&["VI37889"]
8437889
1
in #1
:)
1
。仍然是90个字符,但剪切和粘贴将起作用。您当然知道使用单个字符箭头的动机。
Ace bash答案的另一个明显副本
($_)=@ARGV;y/a-z/22233344455566677778889999/;print
-p
switch,它使您可以很好地遍历stdin的每一行。当我们使用它时,y ///中的范围不需要放在方括号中。我们还可以摆脱三个9,只剩下一个,然后删除最后的分号: -p y/a-z/22233344455566677778889/
在那里,为30 + 1 -p
。感谢您使用Enterprise Chinese Perl高尔夫和优化服务,祝您愉快。
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)] ))
不是最短的,而是更有趣的:
<?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;}
}
strtolower
在过去的两个晚上中,我花了很多时间精心创建一个数学序列函数,该函数可以正确舍入以从字母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
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_input
以input
删除了多余的'\b'
和括号以及单引号
删除+2
偏移量并将其放在原始减法中(97-(3 * 2)= 91)
经过Python 2.7.6解释器测试。根据规则,假设一个字符串输入。
BaseX被用作XQuery处理器。$i
输入。
translate($i,"abcdefghijklmnopqrstuvwxyz","22233344455566677778889999")
不是最短的答案,而是相当简短且可读性强的答案。
啊,回忆...
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
行,否则解释器会抱怨,请转到图。)