代码之家  ›  专栏  ›  技术社区  ›  Platinum Azure

高尔夫守则:四是魔术

  •  88
  • Platinum Azure  · 技术社区  · 5 年前

    我高中时听到的一个小谜题是这样的。。。

    • 提问者会让我给他一个数字;
    • 当听到这个数字时,提问者会反复对它进行某种变换(例如,他可能会说 )直到最后到达4号(此时他将以 四是魔术

    我们的目标是试图找出转换函数,然后能够可靠地处理这个难题自己。

    解决方案

    任何一步的变换函数都是

    • 拿这个号码来说,
    • 计算其英语单词表示中的字母数,忽略连字符或空格或“and”(例如,“ten”中有3个字母,“three-four”中有10个字母,“143”中有20个字母)。
    • 返回那个字母数。

    对于我想测试的所有数字,这个收敛到4,因为“4”也有四个字母,所以这里会有一个无限循环;相反,它只是被称为 魔术 按惯例结束这个序列。

    您的挑战是创建一段代码,从用户那里读取一个数字,然后打印行,显示正在重复应用的转换函数,直到达到“四是魔法”。

    1. 解决方案本身必须是完整的程序。它们不能仅仅是在输入中接受数字因子的函数。
    2. 输入必须从标准输入读取(从“echo”进行管道传输或使用输入重定向是可以的,因为这也来自stdin)
    3. 输入应为数字形式。
    4. 对于变换函数的每个应用程序,应打印一行: a is b. ,其中a和b是变换中数字的数字形式。
    5. 句号(句号)是必需的!
    6. 最后一行自然应该说, 4 is magic. .
    7. 代码应该为来自的所有数字生成正确的输出 0到99

    示例:

    > 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.
    

    胜利者是 这也是 对的

    奖金

    您还可以尝试编写一个版本的代码,在每次应用转换函数时打印出数字的英文名称。最初的输入仍然是数字,但是输出行应该是数字的单词形式。

    (Double bonus for drawing shapes with your code)

    一些澄清:

    1. 我确实希望这个词在所有适用的情况下都出现在两边。 Nine is four. Four is magic.
    2. 不过,我不在乎资本化。我不在乎你怎么区分代币这个词,尽管它们应该分开: ninety-nine 一切正常, ninety nine 一切正常, ninetynine

    请为每个版本提交一个解决方案。

    30 回复  |  直到 7 年前
        1
  •  57
  •   Nabb    14 年前

    高尔夫脚本- 101 93 91 90 94

    90 → 94 :10的倍数的固定输出。
    94 → 86 :重新构造的代码。使用base 100删除不可打印的字符。
    86 → 85 :转换为字符串。

    {n+~."+#,#6$DWOXB79Bd")base`1/10/~{~2${~1$+}%(;+~}%++=" is "\".
    "1$4$4-}do;;;"magic."
    
        2
  •  85
  •   mob    14 年前

    Perl,大约147个字符

    大致基于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
    
        3
  •  30
  •   3 revs<br/>user110763&#13;    14 年前

    (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)))
    

    以人类可读的形式:

     (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)))
    

    以及一些测试运行:

    >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.
    

    奖励版,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)))
    

    >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.
    
        4
  •  21
  •   KennyTM    14 年前

    Python 2.x版,144 150 154

    这将数字分成十和一,然后相加。伪三元算子的非期望性质 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."
    

    以前的天真版本(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."
    
        5
  •  20
  •   P Daddy    13 年前

    445 431 427 399 371 359 * 354 348 347个字符

    就这样。我想我不能再缩短了。

    所有换行符都是为了可读性,可以删除:

    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);}
    

    下面,它有点不统一,但仍然很难阅读。请参阅下面更可读的版本。

    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);
    }
    

    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"*/);
    }
    

    关于开头附近的编码字符串

    数字的名称是用一个非常简单的方案压缩的。常用的子字符串被替换为名称数组中的一个字符索引。对于第一个集合中未完整使用的子字符串,将在末尾添加额外名称项的“查找表”。查找是递归的:条目可以引用其他条目。

    例如,11的压缩名称是 elM print() 函数输出字符 e l (小写'L',而不是数字'1')逐字,但它会找到 M evL ,所以它输出 e v ,然后使用查找表中第28个条目的索引再次调用自身,即 en 也用于 eL 对于 een (用于 eight 在里面 eighteen ),用于 tO 对于 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而不是命令行参数,以及其他一些优化会保存相同数量的字符,从而导致清洗。

        6
  •  10
  •   David    14 年前

    112 人物

    '4 is magic.',~}:('.',~":@{.,' is ',":@{:)"1]2&{.\.
    (]{&(#.100 4$,#:3 u:ucp'䌵䐵吶梇禈榛ꪛ멩鮪鮺墊馊꥘誙誩墊馊ꥺ겻곋榛ꪛ멩鮪鮺'))^:a:
    

    (换行仅用于可读性)

        '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. 
    
        7
  •  10
  •   Joel Spolsky    4 年前

    T-SQL,413 451 499 字符

    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
    

    (并不是说我真的建议你这么做。。。真的,我只想写一个CTE)

    使用方法:

    M 95
    

    退换商品

    p                n
    ----------- ---- -----------
    95          is   10.
    10          is   3.
    3           is   5.
    5           is   4.
    4 is magic.
    
        8
  •  9
  •   Mark Peters    14 年前

    爪哇语(带样板), 308 286 282 280个字符

    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");}}
    

    我相信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");
       }
    }
    

        9
  •  9
  •   Јοеу    14 年前

    Windows PowerShell:152 153 184 字节

    $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.'
    
        10
  •  8
  •   Ferruccio    14 年前

    C、 158个字符

    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.");}
    

    (最初基于弗拉德的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.");
    }
    
        11
  •  6
  •   Nas Banov    14 年前

    133 148 字符

    另外,经过几次修订后,现在大约缩短了20个字符:

    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.'
    
        12
  •  6
  •   Yann Ramin    14 年前

    C#:210个字符。

    压扁:

    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));}}
    

    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)
                       );
        }
    }
    

    • 根据数字中出现的数字创建数字名称长度的查找表。
    • 使用类名别名来缩短 Console. C.
    • 使用条件(三元)运算符( ?: if/else
    • 使用 \n Write 转义码而不是 WriteLine
    • 利用C#具有定义的求值顺序这一事实,允许在 函数调用
        13
  •  6
  •   Platinum Azure    14 年前

    Perl:148个字符

    (Perl: 181 212 198 185 179 148个字符)

    • 已将异常哈希移到单位数组中。这导致我能够削减了很多字符:-)
    • 暴徒指出了一个讨厌的虫子。快速修复增加了31个字符,哎哟!
    • 单次使用直接列表访问而不是存储到阵列?见鬼,是的!
    • 哦,简单的空白修复。现在是198。
    • 重构了一些多余的代码。
    • 中的最后一个返回关键字 r 没必要,再剃掉一些。
    • 试着用“魔法”这个词。

    让我们在Perl中进行一次适度的尝试来完成这个任务。

    @u=split'','4335443554366887798866555766';$_=<>;chop;print"$_ is ".($_=$_==4?0:$_<20?$u[$_]:($u[$_/10+18]+($_%10&&$u[$_%10]))or magic).".
    "while$_
    

    技巧:

    太多了!

        14
  •  5
  •   gnarf    4 年前

    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.')
    

    用法: echo 42 | js golf.js

    输出:

    42 is 8.
    8 is 5.
    5 is 4.
    4 is magic.
    

    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.')
    

    输出:

    ninety nine is ten.
    ten is three.
    three is five.
    five is four.
    four is magic.
    
        15
  •  4
  •   Axel Gneiting    4 年前

    哈斯克尔,224 270 人物

    o="43354435543668877988"
    x!i=read[x!!i]
    n x|x<20=o!x|0<1="0066555766"!div x 10+o!mod x 10
    f x=zipWith(\a b->a++" is "++b++".")l(tail l)where l=map show(takeWhile(/=4)$iterate n x)++["4","magic"]
    main=readLn>>=mapM putStrLn.f
    

    更具可读性-

    ones = [4,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8]
    tens = [0,0,6,6,5,5,5,7,6,6]
    
    n x = if x < 20 then ones !! x else (tens !! div x 10) + (ones !! mod x 10)
    
    f x = zipWith (\a b -> a ++ " is " ++ b ++ ".") l (tail l)
        where l = map show (takeWhile (/=4) (iterate n x)) ++ ["4", "magic"]
        
    main = readLn >>= mapM putStrLn . f
    
        16
  •  4
  •   Karl von Moor    14 年前

    #include <cstdio>
    #define P;printf(
    char*o="43354435543668877988";main(int p){scanf("%d",&p)P"%d",p);while(p!=4){p=p<20?o[p]-48:"0366555966"[p/10]-96+o[p%10]P" is %d.\n%d",p,p);}P" is magic.\n");}
    

    C++流版本,缩小:195个字符

    #include <iostream>
    #define O;std::cout<<
    char*o="43354435543668877988";main(int p){std::cin>>p;O p;while(p!=4){p=p<20?o[p]-48:"0366555966"[p/10]-96+o[p%10]O" is "<<p<<".\n"<<p;}O" is magic.\n";}
    

    原始,未缩小:344个字符

    #include <cstdio>
    
    int ones[] = { 4, 3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8 };
    int tens[] = { 0, 3, 6, 6, 5, 5, 5, 9, 6, 6 };
    
    int n(int n) {
        return n<20 ? ones[n] : tens[n/10] + ones[n%10];
    }
    
    int main(int p) {
        scanf("%d", &p);
        while(p!=4) {
            int q = n(p);
            printf("%i is %i\n", p, q);
            p = q;
        }
        printf("%i is magic\n", p);
    }
    
        17
  •  3
  •   Jørn E. Angeltveit    14 年前

    Delphi:329个字符

    单线版本:

    program P;{$APPTYPE CONSOLE}uses SysUtils;const S=65;A='EDDFEEDFFEDGGIIHHJII';B='DGGFFFJGG';function Z(X:Byte):Byte;begin if X<20 then Z:=Ord(A[X+1])-S else Z:=(Ord(B[X DIV 10])-S)+Z(X MOD 10)end;var X,Y:Byte;begin Write('> ');ReadLn(X);repeat Y:=Z(X);WriteLn(Format('%d is %d.',[X,Y]));X:=Y;until X=4;WriteLn('4 is magic.');end.
    

    program P;
    
    {$APPTYPE CONSOLE}
    
    uses
      SysUtils;
    
    const
      S = 65;
      A = 'EDDFEEDFFEDGGIIHHJII';
      B = 'DGGFFFJGG';
    
    function Z(X:Byte):Byte;
    begin
      if X<20
      then Z := Ord(A[X+1])-S
      else Z := (Ord(B[X DIV 10])-S) + Z(X MOD 10);
    end;
    
    var
      X,Y: Byte;
    
    begin
      Write('> ');
      ReadLn(X);
    
      repeat
        Y:=Z(X);
        WriteLn(Format('%d is %d.' , [X,Y]));
        X:=Y;
      until X=4;
    
      WriteLn('4 is magic.');
    end.
    

    可能还有地方挤…:-P

        18
  •  3
  •   Oliver Giesen    14 年前

    C级# 314 286 283 289 252个字符。

    压扁:

    252 
    

    using C = System.Console;
    class P
    {
        static void Main()
        {
            var x = "4335443554366877798866555766";
            int m, o, v = int.Parse(C.ReadLine());
            do {
                C.Write("{0} is {1}.\n", o = v, v == 4 ? (object)"magic" : v = v < 20 ? x[v] - 48 : x[17 + v / 10] - 96 + ((m = v % 10) > 0 ? x[m] : 48));
            } while (o != 4);
            C.ReadLine();
        }
    }
    

    • 将l.ToString()更改为 object string "magic"
    • 创建了一个临时变量 o break 外面 for 循环,即导致 do-while .
    • o 任务,以及 v l 在函数参数中,删除 . 还内联了 m
    • 删除了中的空格 int[] x int[]x 也是合法的。
    • 试图将数组转换为字符串转换,但 using System.Linq 太多了,不能让这成为一个进步。

    将int数组更改为char array/string,并添加了适当的算法来更正此问题。

        19
  •  3
  •   gwell    4 年前

    Lua,176个字符

    o={[0]=4,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8}t={3,6,6,5,5,5,7,6,6}n=0+io.read()while n~=4 do a=o[n]or o[n%10]+t[(n-n%10)/10]print(n.." is "..a..".")n=a end print"4 is magic."
    

      o={[0]=4,3,3,5,4,4
      ,3,5,5,4,3,6,6,8,8
      ,7,7,9,8,8}t={3,6,
       6,5,5,5,7,6,6}n=
       0+io.read()while
       n ~= 4 do a= o[n
       ]or o[n%10]+t[(n
       -n%10)/10]print(
    n.." is "..a.."." )n=a
    end print"4 is magic."
    
        20
  •  3
  •   P Daddy    13 年前

    C-无数字字

    180 * 172 167个字符

    i;V(x){return"\3#,#6$:WOXB79B"[x/2]/(x%2?1:10)%10;}main(c){for(scanf("%d",&c);
    c-4;)i=c,printf("%d is %d.\n",i,c=c?c>19?V(c/10+19)+V(c%10):V(c):4);puts(
    "4 is magic.");}
    

    稍不统一:

    i;
    V(x){return"\3#,#6$:WOXB79B"[x/2]/(x%2?1:10)%10;}
    main(c){
        for(scanf("%d",&c);c-4;)
            i=c,
            printf("%d is %d.\n",i,c=c?c>19?V(c/10+19)+V(c%10):V(c):4);
        puts("4 is magic.");
    }
    

        21
  •  2
  •   5 revs<br/>user397369&#13;    14 年前

    perl公司, 123

    刚刚意识到不需要输出到STDOUT,所以改为输出到STDERR并去掉另一个字符。

    @u='0335443554366887798866555766'=~/./g;$_+=<>;warn"$_ is ",$_=$_-4?$_<20?$u[$_]||4:$u[chop]+$u[$_+18]:magic,".\n"until/g/
    

    并且,一个返回指定数字的版本:

    278 276 280个字符

    @p=(Thir,Four,Fif,Six,Seven,Eigh,Nine);@n=("",One,Two,Three,Four,Five,@p[3..6],Ten,Eleven,Twelve,map$_.teen,@p);s/u//for@m=map$_.ty,Twen,@p;$n[8].=t;sub n{$n=shift;$n?$n<20?$n[$n]:"$m[$n/10-2] $n[$n%10]":Zero}$p+=<>;warnt$m=n($p)," is ",$_=$p-4?n$p=()=$m=~/\w/g:magic,".\n"until/c/
    

    虽然它符合规范,但它并不是100%格式良好。它在以零结尾的数字后面返回一个额外的空格。说明书上说:

    “我不管你怎么把代币分开,尽管它们应该分开”

    不过,这有点软弱。 更正确的版本

    282 279 283个字符

    @p=(Thir,Four,Fif,Six,Seven,Eigh,Nine);@n=("\x8",One,Two,Three,Four,Five,@p[3..6],Ten,Eleven,Twelve,map$_.teen,@p);s/u//for@m=map$_.ty,Twen,@p;$n[8].=t;sub n{$n=shift;$n?$n<20?$n[$n]:"$m[$n/10-2]-$n[$n%10]":Zero}$p+=<>;warn$m=n($p)," is ",$_=$p-4?n$p=()=$m=~/\w/g:magic,".\n"until/c/
    
        22
  •  1
  •   Vlad    14 年前

    蟒蛇:

    #!/usr/bin/env python
    
    # Number of letters in each part, we don't count spaces
    Decades = ( 0, 3, 6, 6, 6, 5, 5, 7, 6, 6, 0 )
    Smalls  = ( 0, 3, 3, 5, 4, 4, 3, 5, 5, 4 )
    Teens  =  ( 6, 6, 8, 8, 7, 7, 9, 8, 8 )
    
    def Count(n):
        if n > 10 and n < 20: return Teens[n-11]
        return   Smalls[n % 10 ] + Decades [ n / 10 ]
    
    N = input()
    
    while N-4:
        Cnt = Count(N)
        print "%d is %d" % ( N, Cnt)
        N = Cnt
    
    print "4 is magic"
    
        23
  •  1
  •   Graeme Perrow    14 年前

    void main(){char x,y,*a="03354435543668877988";scanf("%d",&x);for(;x-4;x=y)y=x?x<19?a[x]-48:"_466555766"[x/10]+a[x%10]-96:4,printf("%d is %d.\n",x,y);puts("4 is magic.");}
    
        24
  •  1
  •   Jon Smock    14 年前

    n=gets.to_i;s="03354435543668877987";if n==0;puts"0 is 4.";else;puts"#{n} is #{n=(n<20)?s[n]-48:"0066555766"[n/10]-48+s[n%10]-48}." until n==4;end;puts"4 is magic."
    

    已解码:

    n = gets.to_i
    s = "03354435543668877987"
    if n == 0
      puts "0 is 4."
    else
      puts "#{n} is #{n = (n < 20) ? s[n] - 48 : "0066555766"[n / 10] - 48 + s[n % 10] - 48}." until n == 4
    end
    
    puts "4 is magic."
    
        25
  •  1
  •   ScottG    14 年前

    卢阿 185 199

    添加了句点,添加了io.read,删除了上次打印时的()

     n=io.read();while(n~=4)do m=('43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:'):sub(n+1):byte()-48;print(n,' is ',m,'.')n=m;end print'4 is magic.'
    

    带换行符

     n=io.read()
     while (n~=4) do
        m=('43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:'):sub(n+1):byte()-48;
        print(n,' is ',m,'.')
        n=m;
     end 
     print'4 is magic.'
    
        26
  •  0
  •   Developer    14 年前

    PhP代码

    function get_num_name($num){  
        switch($num){  
            case 1:return 'one';  
        case 2:return 'two';  
        case 3:return 'three';  
        case 4:return 'four';  
        case 5:return 'five';  
        case 6:return 'six';  
        case 7:return 'seven';  
        case 8:return 'eight';  
        case 9:return 'nine';  
        }  
    }  
    
    function num_to_words($number, $real_name, $decimal_digit, $decimal_name){  
        $res = '';  
        $real = 0;  
        $decimal = 0;  
    
        if($number == 0)  
            return 'Zero'.(($real_name == '')?'':' '.$real_name);  
        if($number >= 0){  
            $real = floor($number);  
            $decimal = number_format($number - $real, $decimal_digit, '.', ',');  
        }else{  
            $real = ceil($number) * (-1);  
            $number = abs($number);  
            $decimal = number_format($number - $real, $decimal_digit, '.', ',');  
        }  
        $decimal = substr($decimal, strpos($decimal, '.') +1);  
    
        $unit_name[1] = 'thousand';  
        $unit_name[2] = 'million';  
        $unit_name[3] = 'billion';  
        $unit_name[4] = 'trillion';  
    
        $packet = array();    
    
        $number = strrev($real);  
        $packet = str_split($number,3);  
    
        for($i=0;$i<count($packet);$i++){  
            $tmp = strrev($packet[$i]);  
            $unit = $unit_name[$i];  
            if((int)$tmp == 0)  
                continue;  
            $tmp_res = '';  
            if(strlen($tmp) >= 2){  
                $tmp_proc = substr($tmp,-2);  
                switch($tmp_proc){  
                    case '10':  
                        $tmp_res = 'ten';  
                        break;  
                    case '11':  
                        $tmp_res = 'eleven';  
                        break;  
                    case '12':  
                        $tmp_res = 'twelve';  
                        break;  
                    case '13':  
                        $tmp_res = 'thirteen';  
                        break;  
                    case '15':  
                        $tmp_res = 'fifteen';  
                        break;  
                    case '20':  
                        $tmp_res = 'twenty';  
                        break;  
                    case '30':  
                        $tmp_res = 'thirty';  
                        break;  
                    case '40':  
                        $tmp_res = 'forty';  
                        break;  
                    case '50':  
                        $tmp_res = 'fifty';  
                        break;  
                    case '70':  
                        $tmp_res = 'seventy';  
                        break;  
                    case '80':  
                        $tmp_res = 'eighty';  
                        break;  
                    default:  
                        $tmp_begin = substr($tmp_proc,0,1);  
                        $tmp_end = substr($tmp_proc,1,1);  
    
                        if($tmp_begin == '1')  
                            $tmp_res = get_num_name($tmp_end).'teen';  
                        elseif($tmp_begin == '0')  
                            $tmp_res = get_num_name($tmp_end);  
                        elseif($tmp_end == '0')  
                            $tmp_res = get_num_name($tmp_begin).'ty';  
                        else{  
                            if($tmp_begin == '2')  
                                $tmp_res = 'twenty';  
                            elseif($tmp_begin == '3')  
                                $tmp_res = 'thirty';  
                            elseif($tmp_begin == '4')  
                                $tmp_res = 'forty';  
                            elseif($tmp_begin == '5')  
                                $tmp_res = 'fifty';  
                            elseif($tmp_begin == '6')  
                                $tmp_res = 'sixty';  
                            elseif($tmp_begin == '7')  
                                $tmp_res = 'seventy';  
                            elseif($tmp_begin == '8')  
                                $tmp_res = 'eighty';  
                            elseif($tmp_begin == '9')  
                                $tmp_res = 'ninety';  
    
                            $tmp_res = $tmp_res.' '.get_num_name($tmp_end);  
                        }  
                        break;  
                }  
    
                if(strlen($tmp) == 3){  
                    $tmp_begin = substr($tmp,0,1);  
    
                    $space = '';  
                    if(substr($tmp_res,0,1) != ' ' && $tmp_res != '')  
                        $space = ' ';  
    
                    if($tmp_begin != 0){  
                        if($tmp_begin != '0'){  
                            if($tmp_res != '')  
                                $tmp_res = 'and'.$space.$tmp_res;  
                        }  
                        $tmp_res = get_num_name($tmp_begin).' hundred'.$space.$tmp_res;  
                    }  
                }  
            }else  
                $tmp_res = get_num_name($tmp);  
            $space = '';  
            if(substr($res,0,1) != ' ' && $res != '')  
                $space = ' ';  
            $res = $tmp_res.' '.$unit.$space.$res;  
        }  
    
        $space = '';  
        if(substr($res,-1) != ' ' && $res != '')  
            $space = ' ';  
    
        if($res)  
            $res .= $space.$real_name.(($real > 1 && $real_name != '')?'s':'');  
    
        if($decimal > 0)  
            $res .= ' '.num_to_words($decimal, '', 0, '').' '.$decimal_name.(($decimal > 1 && $decimal_name != '')?'s':'');  
        return ucfirst($res);  
    }  
    

    ////////////测试////////////////

     $str2num = 12;
        while($str2num!=4){
            $str = num_to_words($str2num, '', 0, '');  
            $str2num = strlen($str)-1;
            echo $str . '=' . $str2num .'<br/>';
            if ($str2num == 4)
                echo 'four is magic';
        }
    

    //////结果/////////

    Twelve =6
    Six =3
    Three =5
    Five =4
    four is magic
    
        27
  •  0
  •   vol7ron    7 年前


    5.12.1(130个字符) 121 123 136 140

    #        1         2         3         4         5         6         7         8         9        100        11        12        13       14    
    #23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123
    
    @u='4335443554366887798866555766'=~/./g;$_=pop;say"$_ is ",$_=$_-4?$_<20?$u[$_]:$u[$_/10+18]+(($_%=10)&&$u[$_]):magic,"."until/\D/
    


    5.10.1(134个字符) 125 136 144

    #        1         2         3         4         5         6         7         8         9        100        11        12        13       14    
    #23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234
    
    @u='4335443554366887798866555766'=~/./g;$_=pop;print"$_ is ",$_=$_-4?$_<20?$u[$_]:$u[$_/10+18]+(($_%=10)&&$u[$_]):magic,".\n"until/\D/
    


    更改历史记录:

    20100714:2223 -在…的注意下恢复了变化 mobrule ,但是 ($_%10&&$u[$_%10]) (($_%=10)&&$u[$_]) ,这和chars是一样的,但我是这样做的,以防有人发现改进的方法

    20100714:0041 - split//,'...' '...'=~/./g
    20100714:0025 (10&美元)&$单位[$\%10]) $u[$_%10]
    20100713:2340 - while$_ until/\D/
    20100713:xxxx $=<>;chop; $_=pop; -礼节 暴民统治


    注: 我厌倦了在评论中改进别人的答案,所以现在我很贪婪,可以在这里添加我的修改:)这是一个与 Platinum Azure 的答案——部分归功于 Hobbs ,和 铂天青

        28
  •  0
  •   hobbs    14 年前

    相当直接地改编自P Daddy的C代码,并对 p()

    @t=(qw(zero 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 4SmagicT)," is ",".\n");
    sub p{local$_=$t[pop];1while s/[0-Z]/$t[-48+ord$&]/e;
    print;length}$_=<>;chop;while($_-4){
    $_=($_>19?(p($_/10+18),$_&&print("-"),$_%=10)[0]:0)+p$_;
    p 35;p$_;p 36}p 34
    

    旁注:perl print

        29
  •  0
  •   Krzysztof    13 年前

    红宝石,141个字符:

    n=gets.to_i;m="4335443554366887798866555766";loop{s=n;n=n>20?m[18+n/10]+m[n%10]-96: m[n]-48;puts"#{s} is #{n==s ? 'magic': n}.";n==s &&break}
    
        30
  •  -7
  •   user368038    14 年前
    while(true)
    {
        string a;
        ReadLine(a)
        WriteLine(4);
    
    }