web-dev-qa-db-ja.com

コードゴルフ:4つは魔法です

パズル

高校生の時に聞いたちょっとしたパズルはこんな感じでした….

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

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

ソリューション

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

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

私がこれまでにテストしたすべての数値について、これは4に収束します。「4」にも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.

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

ボーナス

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

(コードで図形を描画するための2倍のボーナス)

(編集) いくつかの説明:

  1. 該当するすべての場合に、Wordを両側に表示したいと思います。 Nine is four. Four is magic.
  2. ただし、大文字の使用は気にしません。また、Wordトークンをどのように分離するかは関係ありませんが、分離する必要があります。ninety-nine 大丈夫、 ninety nineは大丈夫です、ninetynineは大丈夫ではありません。

チャレンジに関しては、ボーナス競争のためにこれらを別のカテゴリと考えているので、これを選択する場合は、コードが数値バージョンより長くなることを心配しないでください。

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

88
Platinum Azure

GolfScript- 101969392919094 86バイト

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

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

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
85
mob

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

Python 2.x、144 150154166 文字

これにより、数が10と1に分割され、それらが合計されます。疑似三項演算子の望ましくない特性a and b or ccが0の場合、bが返されます。ここでは悪用されています。

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

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

T-SQL、413 451499 文字

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.
10
Leon Bambrick

Windows PowerShell:152 153184 バイト

以前のソリューションに基づいており、他のソリューションからの影響が大きい

$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.'
9
Joey

Java(定型文付き)、 308290286282 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進数を使用しなくなり、キーストロークが少なくなりました

9
Mark Peters

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コードに基づいており、TomSirgedasの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.");
}
8
Ferruccio

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)を使用します。
  • Writeの代わりにWriteLineエスケープコードとともに\nを使用します
  • Write関数呼び出し内での割り当てを可能にするために、C#には定義された評価順序があるという事実を使用してください
  • 代入式を使用して、余分なステートメント、つまり余分な中括弧を削除します
6
LBushkin

Perl:148文字

(Perl: 233181212206200199198185179149 148文字)

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

Perlでささやかな試みをして、このボールを転がしてみましょう。

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

秘訣:

多すぎる!

6
Platinum Azure

Python、129 133137148 文字

ウォームアップとして、これが私の最初のバージョンです(以前の最高の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
Nas Banov

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は魔法です。
5
gnarf

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
Martin Jonáš

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);
}
4
Karl von Moor

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

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

C# 314286283274289273 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()をobject"magic"stringへのキャストに変更しました。
  • 一時変数oを作成したので、breakforループの外に移動できます。つまり、do-whileになります。
  • o割り当てとv割り当てをインライン化し、関数の引数にlの計算を挿入し続け、lの必要性を排除します。また、mの割り当てをインライン化しました。
  • int[] xのスペースを削除しました。int[]xも正当です。
  • 配列を文字列変換に変換しようとしましたが、using System.Linqが多すぎてこれを改善できませんでした。

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

3
mdm20

C-数字の単語なし

180175*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の代わりにコマンドラインで入力を受け取りました。追加された文字をゼロで処理しますが、コマンドライン引数の代わりにstdinを使用すると、さらに節約され、正味の節約になります。

3
P Daddy

Perl、 123 122文字

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

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

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

279278276 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%適切にフォーマットされていません。ゼロで終わる数値の後に余分なスペースを返します。仕様には次のように書かれています。

「Wordトークンをどのように分離してもかまいませんが、分離する必要があります」

でも、それはちょっと楽なことです。より正しいバージョンは

282281279 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/
2
user397369

Ruby、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."
1
Jon Smock

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"
1
Vlad

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

ルビー、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}
0
Krzysztof

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
0
Developer

Perl-130文字


5.12.1(130文字) 121123132136140

#        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文字) 125127136140144

#        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:2223mobrule の注意で変更を元に戻しましたが、($_%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


注:コメントで他の人の回答を改善するのにうんざりしていたので、今は貪欲になっていて、ここに変更を追加できます:)これは Platinum Azure の答え Hobbsmobrule 、および Platinum Azure に部分的にクレジットします。

0
vol7ron

数字の単語(329文字)を持つ恥知らずなPerl

P DaddyのCコードからかなり直接適応し、p()を微調整して、Cの代わりに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
hobbs