Pla*_*ure 88 language-agnostic code-golf rosetta-stone
我在高中时听到的一个小谜题是这样的......
目标是试图找出转换功能,然后能够自己可靠地监督这个难题.
任何步骤的转换功能都是
对于我曾经考虑过的所有数字,这会收敛到4.由于"四"也有四个字母,所以这里会有一个无限循环; 相反,它仅仅被称为魔术以结束序列.
您的挑战是创建一段代码,该代码将从用户读取数字,然后打印显示重复应用的转换函数的行,直到达到"四是魔术".
特别:
a is b.其中a和b是转换中数字的数字形式.4 is magic..例子:
> 4
4 is magic.
> 12
12 is 6.
6 is 3.
3 is 5.
5 is 4.
4 is magic.
> 42
42 is 8.
8 is 5.
5 is 4.
4 is magic.
> 0
0 is 4.
4 is magic.
> 99
99 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.
Run Code Online (Sandbox Code Playgroud)
获胜者是源代码字符数最短的提交,这也是正确的.
您也可以尝试编写一个代码版本,该代码使用转换函数的每个应用程序打印数字的ENGLISH NAMES.原始输入仍为数字,但输出行应具有数字的单词形式.
(编辑)一些澄清:
Nine is four. Four is magic.ninety-nine好的,ninety nine没关系,ninetynine不行.我正在考虑将这些作为奖金竞争的单独类别,因此如果你这样做,不要担心你的代码比数字版本更长.
随意为每个版本提交一个解决方案.
mob*_*mob 85
松散地基于Platinum Azure的解决方案:
chop
($_.=
<>);@
u="433
5443554
366 887
798 866
555 766
"=~ /\d
/gx ;#4
sub r{4
-$_ ?$_
<20 ?$u
[$_ ]:(
$'? $u[
$'] :0)
+$u[18+$&]:magic}print"
$_ is ",$_=r(),'.'while
/\d
/x;
444
Run Code Online (Sandbox Code Playgroud)
Nab*_*abb 57
90 ? 94:固定输出为10的倍数
94 ? 86:重组代码.使用base 100删除不可打印的字符.
86 ? 85:缩短演员阵容.
{n+~."+#,#6$DWOXB79Bd")base`1/10/~{~2${~1$+}%(;+~}%++=" is "\".
"1$4$4-}do;;;"magic."
Run Code Online (Sandbox Code Playgroud)
小智 30
Common Lisp 157 Chars
新的更符合标准的版本,现在读取标准输入并忽略空格和连字符:
(labels((g (x)(if(= x 4)(princ"4 is magic.")(let((n(length(remove-if(lambda(x)(find x" -"))(format nil"~r"x)))))(format t"~a is ~a.~%"x n)(g n)))))(g(read)))
Run Code Online (Sandbox Code Playgroud)
以人类可读的形式:
(labels ((g (x)
(if (= x 4)
(princ "4 is magic.")
(let ((n (length (remove-if (lambda(x) (find x " -"))
(format nil "~r" x)))))
(format t"~a is ~a.~%" x n)
(g n)))))
(g (read)))
Run Code Online (Sandbox Code Playgroud)
一些测试运行:
>24
24 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.
>23152436
23152436 is 64.
64 is 9.
9 is 4.
4 is magic.
Run Code Online (Sandbox Code Playgroud)
奖金版本,165个字符:
(labels((g(x)(if(= x 4)(princ"four is magic.")(let*((f(format nil"~r"x))(n(length(remove-if(lambda(x)(find x" -"))f))))(format t"~a is ~r.~%"f n)(g n)))))(g(read)))
Run Code Online (Sandbox Code Playgroud)
给予
>24
twenty-four is ten.
ten is three.
three is five.
five is four.
four is magic.
>234235
two hundred thirty-four thousand two hundred thirty-five is forty-eight.
forty-eight is ten.
ten is three.
three is five.
five is four.
four is magic.
Run Code Online (Sandbox Code Playgroud)
ken*_*ytm 21
这将数字分成数十和一,并将它们相加.伪三元运算符的不想要的性质a and b or c是c,如果返回b值为0这里正在被滥用.
n=input()
x=0x4d2d0f47815890bd2
while n-4:p=n<20and x/10**n%10or 44378/4**(n/10-2)%4+x/10**(n%10)%10+4;print n,"is %d."%p;n=p
print"4 is magic."
Run Code Online (Sandbox Code Playgroud)
以前的天真版本(150个字符).只需将所有长度编码为整数.
n=input()
while n-4:p=3+int('1yrof7i9b1lsi207bozyzg2m7sclycst0zsczde5oks6zt8pedmnup5omwfx56b29',36)/10**n%10;print n,"is %d."%p;n=p
print"4 is magic."
Run Code Online (Sandbox Code Playgroud)
P D*_*ddy 20
而已.我认为我不能缩短它.
所有换行都是为了便于阅读,可以删除:
i;P(x){char*p=",one,two,three,four,five,six,sM,eight,nine,tL,elM,twelve,NP,4P,
fifP,6P,7P,8O,9P,twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,en,evL,thir,eL,tO,ty, is ,.\n,
4RmagicS,zero,";while(x--)if(*++p-44&&!x++)*p>95|*p<48?putchar(*p),++i:P(*p-48);
}main(c){for(scanf("%d",&c);c+(i=-4);P(34),P(c=i),P(35))P(c?c>19?P(c/10+18),
(c%=10)&&putchar(45):0,c:37);P(36);}
Run Code Online (Sandbox Code Playgroud)
下面,它有点不明确,但仍然很难阅读.请参阅下面的更易读的版本.
i;
P(x){
char*p=",one,two,three,four,five,six,sM,eight,nine,tL,elM,twelve,NP,4P,fifP,6P,7P,8O,9P,twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,en,evL,thir,eL,tO,ty, is ,.\n,4RmagicS,zero,";
while(x--)
if(*++p-44&&!x++)
*p>95|*p<48?putchar(*p),++i:P(*p-48);
}
main(c){
for(scanf("%d",&c);c+(i=-4);P(34),P(c=i),P(35))
P(c?
c>19?
P(c/10+18),
(c%=10)&&
putchar(45)
:0,
c
:37);
P(36);
}
Run Code Online (Sandbox Code Playgroud)
扩大和评论:
int count; /* type int is assumed in the minified version */
void print(int index){ /* the minified version assumes a return type of int, but it's ignored */
/* see explanation of this string after code */
char *word =
/* 1 - 9 */
",one,two,three,four,five,six,sM,eight,nine,"
/* 10 - 19 */
"tL,elM,twelve,NP,4P,fifP,6P,7P,8O,9P,"
/* 20 - 90, by tens */
"twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,"
/* lookup table */
"en,evL,thir,eL,tO,ty, is ,.\n,4RmagicS,zero,";
while(index >= 0){
if(*word == ',')
index--;
else if(index == 0) /* we found the right word */
if(*word >= '0' && *word < 'a') /* a compression marker */
print(*word - '0'/*convert to a number*/);
else{
putchar(*word); /* write the letter to the output */
++count;
}
++word;
}
}
int main(int argc, char **argv){ /* see note about this after code */
scanf("%d", &argc); /* parse user input to an integer */
while(argc != 4){
count = 0;
if(argc == 0)
print(37/*index of "zero"*/);
else{
if(argc > 19){
print(argc / 10/*high digit*/ + 20/*offset of "twenty"*/ - 2/*20 / 10*/);
argc %= 10; /* get low digit */
if(argc != 0) /* we need a hyphen before the low digit */
putchar('-');
}
print(argc/* if 0, then nothing is printed or counted */);
}
argc = count;
print(34/*" is "*/);
print(argc); /* print count as word */
print(35/*".\n"*/);
}
print(36/*"four is magic.\n"*/);
}
Run Code Online (Sandbox Code Playgroud)
使用非常简单的方案压缩数字的名称.经常使用的子字符串被一个字符的索引替换为name数组.对于未在第一组中完整使用的子串,将额外名称条目的"查找表"添加到末尾.查找是递归的:条目可以引用其他条目.
例如,11的压缩名称是elM.该print()函数逐字输出字符e和l(小写'L',而不是数字'1'),但随后它找到了M,所以它用第29个条目的索引(ASCII'M' - ASCII'0')调用自身进入查找表.这个字符串evL,因此它输出e和v,然后在查找表,这是第28项的指标再次调用自身en,并逐字输出.这很有用,因为en它也用于eLfor een(在after之后eight使用eighteen),用于tOfor teen(用于其他所有-teen名称).
该方案导致数字名称的相当大的压缩,同时仅需要少量代码来解压缩.
字符串开头和结尾的逗号表示在此字符串中找到子字符串的简单方式.此处添加两个字符可以在以后保存更多字
main()argv被忽略(因此未在压缩版本中声明),argc的值被忽略,但存储被重用以保存当前数字.这只是让我不必声明一个额外的变量.
#include有人会抱怨省略#include <stdio.h>是作弊.它完全没有.给定的是一个完全合法的C程序,可以在我知道的任何C编译器上正确编译(尽管有警告).由于缺少stdio函数的原型,编译器会假设它们是cdecl函数返回的int,并且相信你知道要传递什么参数.无论如何,在这个程序中忽略返回值,它们都是cdecl("C"调用约定)函数,我们确实知道要传递什么参数.
输出符合预期:
0 zero is four. four is magic.
1 one is three. three is five. five is four. four is magic.
4 four is magic.
20 twenty is six. six is three. three is five. five is four. four is magic.
21 twenty-one is nine. nine is four. four is magic.
*之前的版本错过了规范的两个部分:它没有处理零,并且它在命令行而不是stdin上输入.处理零添加了字符,但使用stdin而不是命令行args,以及其他一些优化保存了相同数量的字符,从而导致清洗.
†已更改要求,以明确数字应印在"是"的两侧.这个新版本满足了这个要求,并实现了一些更多的优化(超过)考虑所需的额外大小.
Dav*_*vid 10
'4 is magic.',~}:('.',~":@{.,' is ',":@{:)"1]2&{.\.
(]{&(#.100 4$,#:3 u:ucp'?????????????????????????'))^:a:
Run Code Online (Sandbox Code Playgroud)
(仅限可读性换行符)
用法和输出:
'4 is magic.',~}:('.',~":@{.,' is ',":@{:)"1]2&{.\.(]{&(#.100 4$,#:3 u:ucp'?????????????????????????'))^:a:12
12 is 6.
6 is 3.
3 is 5.
5 is 4.
4 is magic.
Run Code Online (Sandbox Code Playgroud)
Leo*_*ick 10
CREATE FUNCTION d(@N int) RETURNS int AS BEGIN
Declare @l char(50), @s char(50)
Select @l='0066555766',@s='03354435543668877987'
if @N<20 return 0+substring(@s,@N+1,1) return 0+substring(@l,(@N/10)+1,1) + 0+(substring(@s,@N%10+1,1))END
GO
CREATE proc M(@x int) as BEGIN
WITH r(p,n)AS(SELECT p=@x,n=dbo.d(@x) UNION ALL SELECT p=n,n=dbo.d(n) FROM r where n<>4)Select p,'is',n,'.' from r print '4 is magic.'END
Run Code Online (Sandbox Code Playgroud)
(不是说我真的建议你这样做......真的我只是想写一个CTE)
使用:
M 95
Run Code Online (Sandbox Code Playgroud)
返回
p n
----------- ---- -----------
95 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.
Run Code Online (Sandbox Code Playgroud)
class A{public static void main(String[]a){int i=4,j=0;for(;;)System.out.printf("%d is %s.%n",i=i==4?new java.util.Scanner(System.in).nextInt():j,i!=4?j="43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:".charAt(i)-48:"magic");}}
Run Code Online (Sandbox Code Playgroud)
我相信Groovy会摆脱很多.
说明和格式化(计数中删除了所有注释,换行符和前导/尾随空格):
合理地直截了当,但是
//boilerplate
class A{
public static void main(String[]a){
//i is current/left number, j right/next number. i=4 signals to start
//by reading input
int i=4,j=0;
for(;;)
//print in the form "<left> is <right>."
System.out.printf(
"%d is %s.%n",
i=i==4?
//<left>: if i is 4 <left> will be a new starting number
new java.util.Scanner(System.in).nextInt():
//otherwise it's the next val
j,
i!=4?
//use string to map number to its length (:;< come after 9 in ASCII)
//48 is value of '0'. store in j for next iteration
j="43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:".charAt(i)-48:
//i==4 is special case for right; print "magic"
"magic");
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:不再使用十六进制,这是更少的击键
基于以前的解决方案,其他解决方案的影响更大
$o="03354435543668877988"
for($input|sv b;($a=$b)-4){if(!($b=$o[$a])){$b=$o[$a%10]-48+"66555766"[($a-$a%10)/10-2]}$b-=48-4*!$a
"$a is $b."}'4 is magic.'
Run Code Online (Sandbox Code Playgroud)
main(n,c){char*d="03354435543668877988";for(scanf("%d",&n);n-4;n=c)printf("%d is %d.\n",n,c=n?n<19?d[n]-48:d[n%10]-"_,**+++)**"[n/10]:4);puts("4 is magic.");}
Run Code Online (Sandbox Code Playgroud)
(最初基于Vlad的Python代码,借用了Tom Sirgedas的C++解决方案中的技巧来挤出更多的字符)
扩展版本:
main(n, c) {
char *d = "03354435543668877988";
for (scanf("%d",&n); n-4; n = c)
printf("%d is %d.\n", n, c = n ? n<19 ? d[n]-48 : d[n%10] - "_,**+++)**"[n/10] : 4);
puts("4 is magic.");
}
Run Code Online (Sandbox Code Playgroud)
(Perl:233 181 212 206 200 199 198 185 179 149 148个字符)
r是不必要的,剃掉了一些关闭.让我们在Perl中进行一次适度的尝试.
@u=split'','4335443554366887798866555766';$_=<>;chop;print"$_ is ".($_=$_==4?0:$_<20?$u[$_]:($u[$_/10+18]+($_%10&&$u[$_%10]))or magic).".
"while$_
Run Code Online (Sandbox Code Playgroud)
技巧:
太多!
压扁:
using C=System.Console;class B{static void Main(){int
x=0,y=int.Parse(C.ReadLine());while(x!=4)C.Write((x=y)+" is {0}.\n",x==4?"magic":""+(y=x==0?4:"03354435543668877988"[x<20?x:x%10]+"0066555766"[x/10]-96));}}
Run Code Online (Sandbox Code Playgroud)
扩展:
using C=System.Console;
class B
{
static void Main()
{
int x=0,y=int.Parse(C.ReadLine());
while(x!=4)
C.Write((x=y)+" is {0}.\n",
x==4?
"magic":
""+(y= x==0?
4:
"03354435543668877988"[x<20?x:x%10]+
"0066555766"[x/10]-96)
);
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法使用的技巧:
Console.到C.?:)代替if/else.\nwith Writeescape代码而不是WriteLineWrite函数调用内进行赋值的事实作为热身,这是我的第一个版本(比以前最好的Python提高了几个字符).
PS.经过几次修改后,现在约有二十个字符更短:
n=input()
while n-4:p=(922148248>>n/10*3&7)+(632179416>>n%10*3&7)+(737280>>n&1)+4*(n<1);print n,'is %d.'%p;n=p
print'4 is magic.'
Run Code Online (Sandbox Code Playgroud)
l='4335443554366887798866555766'.split('')
for(b=readline();(a=+b)-4;print(a,'is '+b+'.'))b=a<20?l[a]:+l[18+a/10|0]+(a%10&&+l[a%10])
print('4 is magic.')
Run Code Online (Sandbox Code Playgroud)
用法: echo 42 | js golf.js
输出:
42 is 8.
8 is 5.
5 is 4.
4 is magic.
Run Code Online (Sandbox Code Playgroud)
l='zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty thirty fourty fifty sixty seventy eighty ninety'.split(' ')
z=function(a)a<20?l[a]:l[18+a/10|0]+(a%10?' '+l[a%10]:'')
for(b=+readline();(a=b)-4;print(z(a),'is '+z(b)+'.'))b=z(a).replace(' ','').length
print('four is magic.')
Run Code Online (Sandbox Code Playgroud)
输出:
ninety nine is ten. ten is three. three is five. five is four. four is magic.
| 归档时间: |
|
| 查看次数: |
7015 次 |
| 最近记录: |