コードゴルフ:フォーは魔法


88

パズル

高校時代に聞いた小さなパズルはこんな感じでした...

  • 質問者は私に彼に番号を与えるように頼みます。
  • 数を聞くと、質問者はそれをある種の変換(たとえば、10は3と言うかもしれません)を繰り返し行い、最終的に4に到達します(この時点で4で終わるのは魔法です)。
  • どんな数でも、最終的には4に変換できるようです。

目標は、変換関数を理解し、このパズルを自分で確実に監督できるようにすることでした。

ソリューション

任意のステップでの変換関数は

  • 問題の番号を取り、
  • ハイフンやスペース、「and」を無視して、英語の単語表現の文字数を数えます(たとえば、「ten」には3文字、「34」には10文字、「140」 20文字あります)。
  • その文字数を返します。

私がこれまでテストしてきたすべての数値について、これは4に収束します。「4」にも4文字が含まれているため、ここに無限ループがあります。代わりに、シーケンスを終了するために、慣例により単にマジックと呼ばれます。

挑戦

課題は、ユーザーから数値を読み取り、「フォーイズマジック」に達するまで繰り返し適用される変換関数を示す行を出力するコードを作成することです。

具体的には:

  1. ソリューションは、それ自体が完全なプログラムでなければなりません。それらは、単に数値を取り込む関数であってはなりません。
  2. 入力は標準入力から読み取る必要があります。(「エコー」からのピッピングまたは入力リダイレクトの使用は、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.

勝者はソースコードの文字数による最短の提出であり、これも正しいです。

ボーナス

また、変換関数を適用するたびに、数字の英語名を出力するバージョンのコードを作成することもできます。元の入力は依然として数値ですが、出力行には数値の単語形式が必要です。

(あなたのコードで図形を描くためのダブルボーナス)

(編集)いくつかの明確化:

  1. 該当するすべてのケースで単語を両側に表示したい Nine is four. Four is magic.
  2. ただし、大文字は気にしません。トークンは分離する必要がありますが、どのように分離するかは問題ではありません。大丈夫、ninety-nine大丈夫、ninety nine大丈夫でninetynineはありません。

私は、これらをチャレンジに関してボーナスコンペティションの別のカテゴリと見なしているので、この場合、コードが数値バージョンよりも長くなることを心配する必要はありません。

バージョンごとに1つのソリューションを送信してください。


1
どのくらいの数を処理する必要がありますか?<100?1000未満?<1000000?<2 ** 31?
Pダディ

1
これは0から99までで十分なので、0から99にマップする値をハードコードし、4に達するまでループするのが速い、短い解決策だと思います。その後、マイクロトゥイーキングが始まります。
Beska

@P Daddy ...パート6は0-99とだけ言っています。
Beska


14
4はまともなダイスの目で選ばれたため、魔法にすぎません。
VirtuosiMedia 2010

回答:


57

GolfScript- 101 96 93 92 91 90 94 86バイト

90 → 94:10の倍数の出力を修正しました。
94 → 86:再構成されたコード。ベース100を使用して、印刷できない文字を削除します。
86 → 85:文字列へのキャストが短い。

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

なぜこれがここまで下がっているのですか?Lispよりも短く、組み込みのフォーマット関数を使用しません
Claudiu

36
私はコードがで終わる方法が好きです"magic."、それはほとんどそれを要約します。
アイスティーナ

@Aistina:このチャレンジでそれは簡単だと思います。:-)
Platinum Azure

9
@Aistina:笑、それはちょっと面白いです。"mumbo jumbo yada yada..magic"
vol7ron

1
@P Daddyこれdは、)as によって抽出され100、基本変換の基数として使用されます。
Nabb、2014

85

Perl、約147文字

大まかにプラチナ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

1
@Platinum Azureが入力を取得する方法はpop、引数なしでを使用することです。サブルーチンの外でpop削除@ARGVし、Perlプログラムへの引数のリストである最後の値を返します。同じように簡単にに置き換えることができますshiftが、それにより2文字が追加されます。参照:p3rl.org/pop
ブラッドギルバート、

で改行文字が必要なようです。(空白が改行リテラルである)で空白を数える場合'.'は2 \nまたは1です'. '
vol7ron

少し長くなりますが、私の本では創造性が大いに役立ちます。
Beska

@Platinum Azure et al:彼はstdinから入力を得ています。それがPerlでそれを行う方法です。(たぶん彼はあなたのコメントの後でそれを変更しましたか?)
フランク

@Pダディ:うめきますが、とにかくあなたのコメントに+1
Platinum Azure

30

Common Lisp 157文字

新しく標準に準拠したバージョン。フォームの標準入力を読み取り、スペースとハイフンを無視します。

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

5
「twenty-four」は10文字しかないと思いましたか?
kennytm

1
「is」の後の数字もテキストでなければなりません。
Mike DeSimone、2010

5
なぜこれがそんなに高いのですか?その他のものは組み込みのフォーマット関数を使用せず、文字数が少ない
Claudiu

3
@Claudiu Common Lispは素晴らしいからです。
Mornedhel、2013

3
ホールにボールが入らなければ、何回打ってもかまいません。人々は間違った解決策に賛成するときそれを忘れるようです。
Mark Peters、

21

Python 2.x、144 150 154 166 チャー

これは、数を10と1に分け、それらを合計します。擬似三項演算子の望ましくない特性の場合に返される0ここで虐待されています。a and b or ccb

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

申し訳ありませんが、このような理由のために、特にフルストップが必要でした。:-)しかし、良いエントリーです!(編集:私はPythonを知りませんが、あなたn,"is",p,"."はそうすることができますか?私が正しく数えているなら、あなたはまだいくつかの文字を保存すると思います)
Platinum Azure

2
@Plat:の前に余分なスペースが発生し.ます。
kennytm

@KennyTM:ああ、まあ、私はスニペットからでもそれに気づくべきでした。おっとっと!まあ、とにかく、私が言ったように、仕様のいくつかは物事を少し複雑にするために特別に設計されました。:-)
Platinum Azure

36より高いベースを使用してこれを短縮できますか?
MikeD 2010

@MikeD:いいえ。Pythonのドキュメントから:「baseパラメータは変換のベース(デフォルトでは10)を指定し、[2、36]の範囲の任意の整数、またはゼロにすることができます。」これで、やモジュール以外のことを言う以外の関数を使用できるようになるかもしれません ...int()structbase64
Mike DeSimone

20

C-数語

445 431 427 421 399 386 371 359 * 356 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"*/);
}

先頭付近のエンコードされた文字列について

番号の名前は非常に単純なスキームを使用して圧縮されます。頻繁に使用される部分文字列は、1文字のインデックスで名前配列に置き換えられます。追加の名前エントリの「ルックアップテーブル」が、最初のセットで完全に使用されていない部分文字列の最後に追加されます。ルックアップは再帰的です。エントリは他のエントリを参照できます。

たとえば、11の圧縮名はelMです。print()関数は文字を出力eし、l(小文字の「L」ではなく番号「1」)逐語的に、しかし、それは見つけM、それは29のエントリ(ASCII「M」 - ASCII「0」)のインデックスを持つ自分自身を呼び出すように、ルックアップテーブルに。この文字列は、evLそれが出力して、eそしてv、その後、あるルックアップテーブル内の28項目の指標で再び自分自身を呼び出しen、出力逐語的です。for (他のすべての名前に使用される)で使用enされるeLfor een(後eightに使用されるeighteen)でも使用されるため、これは便利です。tOteen-teen

このスキームにより、数値名のかなり重要な圧縮が行われますが、圧縮解除に必要なコードはごくわずかです。

文字列の最初と最後のコンマは、この文字列内で部分文字列を見つける単純な方法を説明しています。ここに2つの文字を追加すると、後でさらに文字が節約されます。

虐待について main()

argv無視され(したがって、圧縮バージョンでは宣言されません)、argcの値は無視されますが、ストレージは現在の数を保持するために再利用されます。これにより、追加の変数を宣言する必要がなくなります。

の欠如について #include

一部を省略すること#include <stdio.h>は不正行為であると文句を言うでしょう。それはまったくありません。与えられたものは、私が知っているすべてのCコンパイラで正しくコンパイルされる、完全に合法なCプログラムです(警告は表示されます)。stdio関数のプロトタイプがない場合、コンパイラーはそれらがを返すcdecl関数であると想定し、int渡すべき引数がわかっていると信頼します。とにかく、このプログラムでは戻り値は無視され、戻り値はすべてcdecl( "C"呼び出し規約)関数であり、渡すべき引数はわかっています。

出力

出力は期待どおりです:

0
ゼロは4です。
4つは魔法です。
1
1つは3つです。
3は5です。
5は4です。
4つは魔法です。
4
4つは魔法です。
20
20は6です。
6は3です。
3は5です。
5は4です。
4つは魔法です。
21
21は9です。
9は4です。
4つは魔法です。

*以前のバージョンでは、仕様の2つの部分でマークがありませんでした。ゼロを処理せず、コマンドラインでstdinの代わりに入力を受け取りました。ゼロを追加した文字を処理しましたが、コマンドライン引数の代わりにstdinを使用したほか、他のいくつかの最適化により、同じ数の文字が保存され、結果としてウォッシュが発生しました。

「is」の両側に数字を印刷する必要があることを明確にするために、要件が変更されました。この新しいバージョンはその要件を満たし、必要な追加サイズを考慮して(以上)の最適化をいくつか実装しています。


これは、答えという言葉の私のお気に入りです。ブラボー、よくできました。あなたに+1、そして私が2つのチェックマークを付けることができれば、私はそうします。
Platinum Azure

5
読むのが楽しいです。これからも日常生活で使うと思います。6、sem、8、9、tel、elem、12、enpee、fourpee、fifpee、sixpee、sevenpee、eightoh、ninepee、twelkyu ... =)
deceze

10

J、107 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. 

15
それは中国語で編集されています
belisarius博士10

3
中国人以外の審判を選択してください
belisarius博士、

3
@beli:멩、겻、곋、멩は韓国語です。
kennytm 2010

1
私の妻(中国語を母国語とする人)は、中国語と韓国語の混合だと言っています。
Loren Pechtel 2010

3
@belisarius:1)彼女は韓国語を知らない。2)中国人は意味不明です。
Loren Pechtel 2010

10

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.

テーブルを返すのではなく、個々の結果を印刷することはできませんか?これにより、出力が見やすくなります。
ジョーイ

1
私はそれがゼロを適切に処理するとは思いません。このようなものはどうですか:CREATE FUNCTION d(@ int) RETURNS int AS BEGIN Declare @l char(9),@s char(50) Select @l='066555766',@s='03354435543668877987' if @=0 return 4 if @<20 return 0+substring(@s,@+1,1)return 0+substring(@l,@/10,1)+substring(@s,@%10+1,1)END
Gabe

9

Java(定型付き)、308 290 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");
   }
}

編集:16進数を使用しなくなりました。これはキーストロークが少なくなります。


1
249インポートなし、クラス定義またはメイン定義なし。
Mark Peters

1
それは凶悪です。私はベース16が好きです。(+1)
Platinum Azure

String[]a代わりにを使用すると、1つのスペースを節約できますString[] a
BalusC 2010

@Balusに感謝します。また、16進解析を使用する代わりに、文字に対して単純な算術を実行することにより、束を排除しました。
Mark Peters

@マーク・ピーターズ:より厄介です。それに比べると私はとてもバニラを感じます。
Platinum Azure

9

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の倍数をサポートするように修正されました( "ninetyzero"ではなく "ninety")。
Gabe

@Gabeさん、こんにちは。最近ゴルフをする時間があまりありません。それでも、$input列挙子をに直接キャストすることはできないため、引用符は残しておく必要がありintます。string最初に通過するときに機能します:-)
Joey

8

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

(もともとは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.");
}

私にはうまくいかないようです:./magic 10 10は-27です。セグメンテーション違反
ケーシー

@Casey-scanf()呼び出しは少し大ざっぱでした。intをcharに読み込んでいました。私はそれをOSXとWindowsで回避していましたが、それは機能しましたが、終了時にクラッシュしました。それで、私は再びn&c intを作りました。K&R表記を使用してパラメーターを作成することで、intキーワードを削除できることに気付きました。結果はより安全で、1文字短くなります。
Ferruccio

" 466555766" [n / 10] + d [n%10] -96をd [n%10]-"+++)に置き換えることで3文字を節約できます" [n / 10]
Tom Sirgedas

6

Python、129 133 137 148 チャー

ウォームアップとして、これが私の最初のバージョンです(以前の最高のPythonよりもいくつかの文字が改善されています)。

PS。いくつかの編集後、現在は約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.'

6

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

このアプローチが使用するトリック:

  • 番号に表示される数字に基づいて番号名の長さのルックアップテーブルを作成します。
  • 数値配列の代わりに文字列で文字配列ルックアップを使用し、char演算を使用します。
  • クラス名のエイリアスを使用Console.して、C.
  • ?:代わりに条件付き(三項)演算子()を使用しif/elseます。
  • 代わりに\nwith Writeエスケープコードを使用してくださいWriteLine
  • C#には評価の順序が定義されているという事実を利用して、Write関数呼び出し内での割り当てを許可する
  • 割り当て式を使用して余分なステートメントを削除し、余分な中括弧を削除します

int[] zそれは必要としないので短くなるだろうnew[]
Joey

配列検索の代わりに文字演算を使用するように改訂されました。
LBushkin 2010

@ mdm20:その通りです。ルックアップテーブルに誤りがありました。今修正されました。
LBushkin 2010

さて、12回目は魅力です:* D
LBushkin

5つの文字保存するquicky:キャストよりも短く"magic"するにはobject、することです暗黙的に呼び出すToString()y追加することによって""。ただし、+はよりも優先順位が高いため、偽の部分 ではなく?:真の部分に配置する必要があります。x!=4?y+"":"magic"
Pダディ

6

Perl:148文字

(Perl:233 181 212 206 200 199 198 185 179 149 148文字)

  • 例外のハッシュをユニット配列に移動しました。これにより、たくさんのキャラクターをカットできるようになりました:-)
  • mobruleが厄介なバグを指摘しました。クイックフィックスにより31文字が追加されます。
  • 特別な場合をゼロにするためにリファクタリングされ、マイルドなゴルフも行われました。
  • 配列に格納するのではなく、使い捨ての直接リストアクセス?もちろん!
  • たった1人の血まみれのキャラクターのためのとても多くのリファクタリング。これはまさに、ゴルファーの人生です。:-(
  • おっと、簡単な空白の修正。今すぐ198。
  • いくつかの冗長なコードをリファクタリングしました。
  • 最後のreturnキーワードrは不要で、さらに削られます。
  • コメントごとの大規模なリファクタリング。残念ながら、以前のコードとコメンターのバージョンの両方に存在するバグを修正する必要があったため、149までしか取得できませんでした。
  • 素朴な「魔法」を試してみる。

Perlで控えめに試して、このボールを転がしましょう。

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

トリック:

多すぎる!


ACK!どのように私がテストしたことがないのか、私は決して知りません。
Platinum Azure

そこにいくつかのデッドコードがありますか?$ u [0]が4の場合、ゼロの特殊なケースがどのように必要になるのかわかりません。コードの166文字が機能しているように見えますが、それよりも少し短い余地があります。
ホブ、

@hobbs:良い点、もう一度見てみます。話は、私が2、3の改訂の途中で行き、突然物事が壊れたということです(私が4-> 0にすることを選択した時点で)。私はあなたがこの時点で正しいと思います:-)
Platinum Azure

私は自分を素晴らしいPerlプログラマとは見なしていませんが、いくつかの文字を減らすことができ@u=split$x,'43350435543668877988';ます。カンマは不必要な19文字を使用し、undefすべての文字で分割を分割し$xます。`undef`の代わりに未定義の変数として使用します-合計節約額:11文字。また、mインchompを削除すると、スコアから別のキャラクターが削られます。
vol7ron、2013

より良いことをしますが、sub r完全に失うことでより多くを節約することができます-それは一度だけ使用し、括弧さえもない単一のネストされた三項ですべて置き換えることができます。:私のバージョンは今144文字ですgist.github.com/473289
ホッブズ

5

JavaScript 1.8(SpiderMonkey)-153文字

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.

ボーナス付き-364文字

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

出力:

99は10です。
10は3です。
3は5です。
5は4です。
4つは魔法です。

4

Haskell、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

4

C ++ Stdioバージョン、縮小:196文字

#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 ++ Iostreamsバージョン、縮小: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);
}

修繕。それも少し短くなりました。
Mike DeSimone、2010

よくできました。(20文字の標準難問で私はよく笑いました!)
Platinum Azure

ええ、それは本当のヘッドバンガーでした、それが私に気付くまで#define、それはいくつかのトークンを置き換えることができるのでさらに短くなるでしょう。
Mike DeSimone、2010

printf("is magic".\n)=> putsprintf("%d",p)=> puts(atoi(p))。短いだけでなく高速でもあります。
Ben Voigt 2010

2
@Mike DeSimone:にwhile(p!=4)短縮できると思いますwhile(p-4)。私は知っていますが、それでも1つのキャラクター全体です。:-)
Platinum Azure

3

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


3

C#314 286 283 274 289 273 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();
    }
}

Dykamの編集:いくつかの注意深い挿入と変更を行いました:

  • l.ToString()をのキャストに変更しましobjectstring "magic"
  • 一時変数を作成しo、私は動くことができるように、breakforで、その結果、あるループ、do-while
  • 関数の引数にの計算を挿入し続けることでov割り当てと同様に割り当てをインライン化し、lの必要性を排除しましたl。の割り当てもインライン化しましたm
  • でスペースを削除しましたがint[] x、これint[]xも合法です。
  • 配列を文字列変換に変換しようとしましたが、using System.Linqこれを改善するには多すぎます。

Edit 2 Dykam int配列をchar配列/文字列に変更し、これを修正する適切な演算を追加しました。


ええ、Javaバージョンよりも短くなりました。
Dykam

3

ルア、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."

3

C-数字なし

180の 175 * 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.");
}

*以前のバージョンでは、仕様の2つの部分でマークがありませんでした。ゼロを処理せず、コマンドラインでstdinの代わりに入力を受け取りました。追加された文字をゼロで処理しますが、コマンドライン引数の代わりに標準入力を使用すると、さらに節約され、結果的に正味節約になります。


2

perl、123 122文字

STDOUTに出力する必要がないことに気付いたので、代わりにSTDERRに出力し、別のキャラクターをノックオフします。

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

そして、スペルアウトした数字を返すバージョン:

279の 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 281 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/

1

Python:

#!/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"

4
私はそれが好きです。あなたはおそらく少しそれをさらに引き締めることができます。
Josh K

@Vlad:入力は、引数からではなくstdinから読み取る必要があります。つまり、使用N = input()(またはraw_input())して、sysものを削除することができます。
kennytm 2010

また、スモールにティーンを含めることもでき、ifステートメントは「if n <20:return Smalls [n]」のみになります。10によるモジュラスのため、Smallは20以上の場合でも機能します
。– Jon Smock

5
she-bangコードゴルフの回答で(完全に省略可能)を目にしたのはこれが初めてです;-)
ChristopheD

良いスタートのように見えます...間違いなくそれを厳しくします、Pythonでさえこの空白のすべてを必要としません。:-)また、Ferluccioが指摘するように、0は機能しません。具体的には、無限ループに入るようです。
Platinum Azure

1

C ++、171文字(#includeは省略)

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

これをCと見なせば#include、関数はintパラメータを取るだけと見なされるため、Cの必要性を回避できると思います。main戻ることでストロークを保存することもできintます。
Gabe

1

ルビー、164文字

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

シンプルなRubyソリューション。:
Platinum Azure

シンプルに保つことは、それを過度に長く保つことの言い訳にはなりません;-)
Joey

「if n == 0」を「if!n」で置き換えることができると思います
Vincent

2
Rubyでは?私はいつもfalseとnilを除くすべての値がtrueと評価されると思っていました:-(
Platinum Azure

1

ルア185 190 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.'

n=io.read()標準入力から数値を読み取るルールに準拠するには、(+ 11文字)が必要です。に変更print('4 is magic.')するprint'4 is magic.'と、2文字節約されます。;後で削除)すると1文字節約されます。printカンマの使用は不正行為のように見えますが、仕様は不明です。print(n,'is',m,'.')2文字節約するように変更することもできます。
グウェル

Luaでカンマは改行として表示されますか?私が使って久しぶりです。
Nick Van Brunt、

コンマはタブとしてレンダリングされます。
グウェル10/07/17

0

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

4
@wallacoloo:卑劣な言語の卑劣なソリューション:D
Thomas Eding

5
または、もっと短い178文字:$l='4335443554366887798866555766';for($b=(int)fgets(fopen('php://stdin','r'));($a=$b)-4;){$b=$a<20?$l[$a]:$l[18+$a/10]+($a%10?$l[$a%10]:0);echo"$a is $b.\n";}echo"4 is magic.\n";
gnarf

ナイスジョーク。:-Dとてもよくプログラムされています。
TomPažourek10年

0

Perl-130文字


5.12.1(130文字) 121 123 132 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 127 136 140 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[$_])、これは同じ文字数ですが、誰かがそれを改善する方法を見つけた可能性がある場合に備えて行いました

20100714:0041- split//,'...''...'=~/./g
20100714:0025- ($_%10&&$u[$_%10])$u[$_%10]
20100713:2340- while$_until/\D/+不要な括弧の削除
20100713:xxxx- $=<>;chop;$_=pop;への礼儀を- mobrule


注:私はコメントで他の人の回答を改善するのに疲れていたので、今私は貪欲になっていて、ここに私の変更を追加することができます:)これは、プラチナAzureの回答から分離されました -一部はHobbsmobrule、そしてプラチナアズール


$_%10&&...構成を取り除くと、入力の仕様に違反しました20,30,40、...
mob

+1よくできました。stdinからargsに移行しました:-(
Platinum Azure

右、と置き換えARGVによって移入され、STDIN:)または... echo bar | xargs perl foo.pl、技術的にperlの:)のために引数にエコーからパイプ
vol7ron

0

数語を使った恥知らずなPerl(329文字)

P DaddyのCコードからかなり直接的に適応しました。Cのp()プリミティブの代わりにPerlプリミティブを使用して同じことを実行するように微調整し、ほとんどが書き換えられたメインループです。説明については彼を参照してください。改行はすべてオプションです。

@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がtrue / falseを返すだけでは残念です。カウントが返された場合、7ストローク節約できます。


0

Ruby、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}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.