코드 골프 : Four is magic


88

퍼즐

고등학교 때 들었던 작은 수수께끼는 이런 식으로 진행되었습니다.

  • 질문자는 나에게 번호를 물어볼 것입니다.
  • 숫자를 듣고 질문자는 결국 숫자 4에 도달 할 때까지 (예를 들어 10은 3 이라고 말할 수 있음) 반복적으로 변형을 수행합니다 ( 4로 끝나는 시점 은 마술입니다 ).
  • 어떤 숫자라도 결국 4 개로 변환 될 수있는 것 같습니다.

목표는 변형 함수를 알아 내고이 퍼즐을 스스로 확실하게 감독 할 수 있도록하는 것이 었습니다.

해결책

모든 단계에서 변환 기능은

  • 문제의 번호를 가지고
  • 하이픈이나 공백 또는 "and"를 무시하고 영어 단어 표현의 문자 수를 계산합니다 (예 : "ten"에는 3 개의 문자가 있고, "thirty-four"에는 10 개의 문자가 있습니다. "1 백 사십 삼") 20 글자 포함).
  • 그 수의 문자를 반환하십시오.

내가 테스트 해 본 모든 숫자에 대해, 이것은 4로 수렴됩니다. "four"도 그 안에 4 개의 문자가 있기 때문에 여기에 무한 루프가 있습니다. 대신 시퀀스를 끝내는 것은 관례 상 마법 이라고합니다 .

도전

당신의 도전은 사용자로부터 숫자를 읽을 코드 조각을 만들고 "four is magic"에 도달 할 때까지 반복적으로 적용되는 변환 함수를 보여주는 줄을 인쇄하는 것입니다.

구체적으로 특별히:

  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.

우승자는 또한 정확한 소스 코드 문자 수에 의한 가장 짧은 제출 입니다.

보너스

변환 함수의 각 응용 프로그램과 함께 숫자에 대한 영어 이름을 인쇄하는 코드 버전을 작성할 수도 있습니다. 원래 입력은 여전히 ​​숫자이지만 출력 행에는 숫자의 단어 형식이 있어야합니다.

(코드로 도형을 그리는 데 두 배의 보너스)

(편집) 일부 설명 :

  1. 해당하는 모든 경우에 단어가 양쪽에 나타나기를 원합니다. 예 : Nine is four. Four is magic.
  2. 하지만 대소 문자는 신경 쓰지 않습니다. 그리고 토큰이라는 단어를 분리하는 방법은 신경 쓰지 않습니다. 비록 분리되어야하지만 : ninety-nine괜찮아, ninety nine괜찮아, ninetynine괜찮지 않습니다.

도전과 관련하여 보너스 경쟁을위한 별도의 범주로 간주하고 있으므로,이 경우 코드가 숫자 버전보다 길다는 것에 대해 걱정하지 마십시오.

각 버전에 대해 하나의 솔루션을 자유롭게 제출하십시오.


1
얼마나 높은 숫자를 처리해야합니까? 100 미만? 1000 미만? 1000000 미만? <2 ** 31?
P Daddy

1
이것은 0에서 99까지만 이동하면되므로 빠르고 짧은 해결책은 0-99가 매핑되는 값을 하드 코딩 한 다음 4에 도달 할 때까지 반복하는 것입니다. 그 후 마이크로 트위 킹이 시작됩니다.
Beska 2010

@P 대디 ... 6 부에는 0-99 만 나와 있습니다
Beska 2010


14
4는 공정한 주사위 굴림으로 선택 되었기 때문에 마법 일뿐입니다.
VirtuosiMedia

답변:


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

왜 이렇게 멀어? 그것은 혀짤배기 하나보다 짧은 그리고 내장 된 서식 기능을 사용하지 않습니다
Claudiu

36
코드가으로 끝나는 방식이 마음에 "magic."들었습니다.
Aistina

@Aistina :이 도전에서는 쉽게 할 수 있다고 생각합니다. :-)
Platinum Azure

9
@Aistina : 하하, 그건 좀 웃기 네요. "미신적 점보 궁시렁 yada..magic"
vol7ron

1
@P Daddy d)as로 추출되며 100기본 변환의 기수로 사용됩니다.
Nabb

85

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

1
@Platinum Azure가 입력을 얻는 방식은 pop인수없이를 사용하는 것입니다 . 서브 루틴 외부에서 pop제거 @ARGV하고 Perl 프로그램에 대한 인수 목록 인 마지막 값을 리턴합니다 . 로 쉽게 바꿀 수 shift있지만 2 개의 문자가 추가됩니다. 참조 : p3rl.org/pop
Brad Gilbert

당신이 개행 문자가 필요한 것 같습니다 '.'에 대한 2, \n또는 1을 경우 당신에게에있어 계수 공백 '. '(개행 문자 인 공간)
vol7ron

조금 더 길지만 창의성은 내 책에서 먼 길을 간다.
Beska 2010

@Platinum Azure 외 : 그는 stdin에서 입력을 받고 있습니다. 이것이 Perl에서하는 방법입니다. (어쩌면 그는 당신의 코멘트 후 변경?)
프랭크

@P 아빠 : 신음 하지만 귀하의 코멘트에 +1 어쨌든
플래티넘 푸른

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

사람이 읽을 수있는 형식 :

 (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
"스물 넷"이 10 글자 밖에 없다고 생각했는데?
kennytm 2010

1
"is"뒤의 숫자도 텍스트 여야합니다.
Mike DeSimone

5
왜 이렇게 높은가요? 다른 사람은 포맷 기능을 내장하고 그들이 더 적은 문자를 사용하지 마십시오
Claudiu

3
@Claudiu Common Lisp는 굉장하기 때문입니다.
Mornedhel 2010

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

죄송합니다. 저는 특별히 이런 이유로 풀 스톱을 원했습니다. :-) 그래도 좋은 입장! (편집 : 나는 파이썬을 모르지만, 당신은 할 수 n,"is",p,"."있습니까? 내가 옳다고 생각한다면 여전히 일부 캐릭터를 구할 수 있다고 생각합니다)
Platinum Azure

2
@Plat : ..
kennytm 2010

@KennyTM : 오, 이런, 스 니펫에서도 알아 차렸어야 했어요. 이런! 어쨌든 제가 말했듯이 일부 사양은 상황을 약간 복잡하게 만들도록 특별히 설계되었습니다. :-)
Platinum Azure

36보다 높은 기준을 사용하여 이것을 줄일 수 있습니까?
MikeD 2010

@MikeD : 아니요. Python 문서에서 : " 기본 매개 변수는 변환의 기본 (기본적으로 10)을 제공하며 [2, 36] 또는 0 범위의 정수일 수 있습니다." 지금 당신은 할 수 이외의 다른 기능을 사용할 수 int()의 무언가를 말 struct하거나 base64... 모듈
마이크 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"*/);
}

시작 부분의 인코딩 된 문자열 정보

숫자의 이름은 매우 간단한 체계를 사용하여 압축됩니다. 자주 사용되는 부분 문자열은 이름 배열의 한 문자 인덱스로 대체됩니다. 추가 이름 항목의 "조회 테이블"이 첫 번째 세트에서 전체적으로 사용되지 않는 부분 문자열의 끝에 추가됩니다. 조회는 재귀 적입니다. 항목은 다른 항목을 참조 할 수 있습니다.

예를 들어 11의 압축 된 이름은 elM. 이 print()함수는 문자 el(숫자 '1'이 아닌 소문자 'L')을 그대로 출력하지만를 찾아서 M29 번째 항목의 인덱스 (ASCII 'M'-ASCII '0')로 자신을 호출합니다. 조회 테이블에. 이 문자열은 evL이 출력되도록 e하고 v, 그 다음 인 룩업 테이블의 28 엔트리의 인덱스로 다시 자신을 호출 en하고, 그대로 출력된다. 때문에 유용 en도에서 사용 eL하기위한 een(후에 사용 eight에서 eighteen)에 사용되는 tO대한 teen(다른 모든에 사용되는 -teen이름).

이 체계는 숫자 이름을 상당히 많이 압축하는 반면 압축을 푸는 데 적은 양의 코드 만 필요합니다.

문자열의 시작과 끝에있는 쉼표는이 문자열 내에서 하위 문자열이 발견되는 단순한 방법을 설명합니다. 여기에 두 문자를 추가하면 나중에 더 많은 문자가 절약됩니다.

남용에 관하여 main()

argv무시되고 (따라서 압축 된 버전에서 선언되지 않음) argc의 값은 무시되지만 스토리지는 현재 번호를 유지하기 위해 재사용됩니다. 이렇게하면 추가 변수를 선언 할 필요가 없습니다.

부족에 대해 #include

일부는 생략 #include <stdio.h>이 속임수 라고 불평 할 것 입니다. 전혀 그렇지 않습니다. 주어진 것은 내가 아는 모든 C 컴파일러에서 올바르게 컴파일되는 완전히 합법적 인 C 프로그램입니다 (경고가 있음에도 불구하고). stdio 함수에 대한 프로토 타입이 부족하면 컴파일러는 이들이를 반환하는 cdecl 함수라고 가정하고 int전달할 인수를 알고 있다고 신뢰합니다. 어쨌든이 프로그램에서 반환 값은 무시되고, 그것들은 모두 cdecl ( "C"호출 규칙) 함수이며, 우리는 실제로 어떤 인자를 전달할지 알고 있습니다.

산출

예상대로 출력됩니다.

0
0은 4입니다.
4는 마법입니다.
1
하나는 셋입니다.
3은 5입니다.
5는 4입니다.
4는 마법입니다.
4
4는 마법입니다.
20
20은 6입니다.
6은 3입니다.
3은 5입니다.
5는 4입니다.
4는 마법입니다.
21
21은 9입니다.
9는 4입니다.
4는 마법입니다.

* 이전 버전은 사양의 두 부분에서 표시를 놓쳤습니다. 0을 처리하지 않았고 stdin 대신 명령 줄에 입력을 받았습니다. 0으로 추가 된 문자를 처리하지만 명령 줄 인수 대신 stdin을 사용하고 몇 가지 다른 최적화를 사용하면 동일한 수의 문자가 저장되어 세척이 발생했습니다.

"is"의 양면에 숫자 단어를 인쇄해야 함을 명확히하기 위해 요구 사항이 변경되었습니다. 이 새 버전은 해당 요구 사항을 충족하고 필요한 추가 크기를 설명하기 위해 몇 가지 더 많은 최적화를 구현합니다.


이것은 제가 가장 좋아하는 답변입니다 ... 브라보, 잘 했어요. 당신을 위해 +1하고 두 개의 체크 표시를 할 수 있다면 그렇게 할 것입니다.
Platinum Azure

5
재미 있네요. 앞으로도이 숫자들을 일상 생활에서 사용할 것 같아요. 여섯, SEM, 여덟, 아홉, 전화, ELEM 열두, 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
그것은 중국어로 컴파일 된 것
벨리 사리우스 박사

3
비 중국어 심판 선택하십시오
박사 벨리 사리우스

3
@beli : 멩, 겻, 곋, 멩은 한국어입니다.
kennytm 2010

1
제 아내 (중국어 원어민)는 중국어와 한국어가 섞여 있다고합니다.
Loren Pechtel

3
@belisarius : 1) 그녀는 한국어를 모릅니다. 2) 중국인은 횡설수설합니다.
Loren Pechtel

10

T-SQL, 413451 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.

표를 반환하는 대신 개별 결과를 인쇄 할 수 없습니까? 그러면 출력이 더 좋아 보일 것입니다.
Joey

1
나는 그것이 0을 제대로 처리한다고 생각하지 않습니다. 어떻게 이런 일에 대해 :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
게이브

9

(보일러 포함) 자바, 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
그것은 사악하다. I like the base 16. (+1)
Platinum Azure

String[]a대신을 사용하여 하나의 공간을 절약 할 수 String[] a있습니다.
BalusC 2010

감사합니다 @Balus, 또한 16 진수 구문 분석을 사용하는 대신 문자에 대해 간단한 산술을 수행하여 무리를 제거했습니다.
Mark Peters

@Mark Peters : 더 나쁘다. 그것에 비해 너무 바닐라 느낌이 듭니다.
백금 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처음 :-)
조이

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

@Casey-scanf () 호출은 약간 개략적이었습니다. int를 char로 읽는 중이었습니다. OSX와 Windows에서는 작동했지만 종료시 충돌했습니다. 그래서 n & c int를 다시 만들었습니다. K & R 표기법을 사용하여 매개 변수를 만들어 int 키워드를 삭제할 수 있다는 것을 깨달았습니다. 결과는 더 안전하고 한 문자 더 짧습니다.
Ferruccio 2010-07-13

" 466555766"[n / 10] + d [n % 10] -96을 d [n % 10]- " , +++) "[n / 10]
Tom Sirgedas

6

파이썬, 129 133 137 148 문자

워밍업으로 여기에 첫 번째 버전이 있습니다 (이전 최고의 Python에 비해 몇 가지 문자가 향상됨).

추신. 몇 번 수정 한 후 이제 약 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 자.

Squished :

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.
  • 대신 \nwith Write이스케이프 코드를 사용하십시오.WriteLine
  • C #에 정의 된 평가 순서가 있다는 사실을 사용하여 Write함수 호출 내에서 할당을 허용합니다.
  • 할당 표현식을 사용하여 추가 문을 제거하고 추가 중괄호를 제거합니다.

int[] z가 필요하지 않기 때문에 짧은 것new[]
조이

배열 조회 대신 문자 산술을 사용하도록 수정되었습니다.
LBushkin 2010

@ mdm20 : 당신 말이 맞아요. 조회 테이블에 실수가있었습니다. 지금 수정되었습니다.
LBushkin 2010

음, 열두 번째 시간이 매력입니다 : * D
LBushkin 2010-07-12

quicky 5 개 문자를 저장합니다 : 주조보다 짧은 "magic"object,하는 것입니다 암시 적으로 호출 ToString()y추가하여 "". 그러나 +우선 순위가보다 높기 때문에 거짓 부분 대신 부분 ?:에 넣어야합니다 : . x!=4?y+"":"magic"
P Daddy

6

Perl : 148 자

(펄 : 233 181 212 206 200 199 198 185 179 개 149 개 148 문자)

  • 예외 해시를 단위 배열로 이동했습니다. 이로 인해 많은 문자를자를 수있었습니다. :-)
  • mobrule은 불쾌한 버그를 지적했습니다. 빠른 수정은 31 개의 문자를 추가합니다.
  • 특별한 경우를 제로로 리팩토링하고 가벼운 골프도 수행했습니다.
  • 배열에 저장하지 않고 일회용 목록에 직접 액세스 하시겠습니까? 당근 빠따 지!
  • 단 하나의 피 묻은 캐릭터에 대한 너무 많은 리팩터링. 이것은 진정으로 골퍼의 삶입니다. :-(
  • 죄송합니다. 쉬운 공백 수정입니다. 198 지금.
  • 일부 중복 코드를 리팩터링했습니다.
  • 마지막 반환 키워드 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 일 때 0에 대한 특수한 경우가 어떻게 필요한지 모르겠습니다. 코드 @ 166 문자로 겉보기에 작동하는 버전이 있고 그보다 조금 더 짧게 할 여지가 있다고 생각합니다.
hobbs

@hobbs : 좋은 지적, 다시 볼게요. 이야기는 내가 몇 번의 수정을 중간에 거쳐 갑자기 문제가 발생했다는 것입니다 (4-> 0을 선택하는 지점에서). 나는이 시점에서 당신이 맞아요 생각 :-)하지만
플래티넘 푸른

나는 나 자신을 훌륭한 Perl 프로그래머라고 생각하지 않지만 몇 가지 문자를 줄일 수 있습니다. @u=split$x,'43350435543668877988';쉼표는 불필요한 19 개의 문자를 사용하고 undef모든 문자에서 분할로 분할하며 $x정의되지 않은 변수로 사용 하여`undef`-total을 대신합니다. 절약 : 11 자. 또한, 제거 m에서을 chomp하고 다른 캐릭터가 점수를 깎아 얻는다.
vol7ron 2010

더 잘하지만 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.')

산출:

아흔 아홉은 10입니다.
10은 3입니다.
3은 5입니다.
5는 4입니다.
4는 마법입니다.

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

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

잘하셨습니다. (나는 20 자 표준 수수께끼에 많이 웃었다!)
Platinum Azure

예, #define그것은 여러 토큰을 대체 할 수 있기 때문에 더 짧아 질 것이라는 것이 나에게 밝혀지기 전까지는 진정한 헤드 뱅커였습니다 .
Mike DeSimone

printf("is magic".\n)=> puts. printf("%d",p)=> puts(atoi(p)). 더 짧을뿐만 아니라 더 빠릅니다.
Ben Voigt

2
@ 마이크 DeSimone : 내 생각 while(p!=4)에 단축 할 수있다 while(p-4). 하나의 전체 캐릭터를 알고 있지만 여전히. :-)
Platinum Azure

3

델파이 : 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 273252 문자.

Squished :

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 으므로 루프 break외부 로 이동할 수 있습니다. for즉, do-while.
  • 인라인 o할당과 할당을 함수 인수에의 v계산을 계속 삽입하여 . 또한 .llm
  • 의 공간을 제거 int[] x, int[]x너무 합법적이다.
  • 배열을 문자열 변환으로 변환하려고 시도했지만 using System.Linq개선하기에는 너무 많았습니다.

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

* 이전 버전은 사양의 두 부분에서 표시를 놓쳤습니다. 0을 처리하지 않았고 stdin 대신 명령 줄에 입력을 받았습니다. 0 개의 추가 된 문자를 처리하지만 명령 줄 인수 대신 stdin을 사용하면 훨씬 더 많은 비용이 절약되어 순 절감 효과가 있습니다.


2

perl, 123122

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 % 제대로 포맷되지 않았습니다. 0으로 끝나는 숫자 뒤에 추가 공백을 반환합니다. 사양은 다음과 같이 말합니다.

"나는 당신이 단어 토큰을 분리하는 방법은 신경 쓰지 않지만, 분리되어야한다"

그래도 그것은 일종의 족쇄입니다. 더 정확한 버전은

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

파이썬 :

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

또한 smalls에 십대를 포함하도록 만들 수 있습니다. if 문은 "if n <20 : return Smalls [n]"만됩니다. 스몰은 여전히 (10)에 의해 때문에 계수의의> = 20 경우에 작동합니다
존 작업복을

5
she-bang코드 골프 답변에서 (완전히 선택 사항) 을 처음 본 것 같습니다 ;-)
ChristopheD

좋은 시작 같네요 ... 확실히 조여주세요. 심지어 파이썬에도이 공백이 모두 필요하지는 않습니다. :-) 또한 Ferruccio가 지적했듯이 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매개 변수 를 취하는 것으로 가정하기 때문에 필요를 피할 수 있다고 생각합니다 . main반환을 하여 스트로크를 저장할 수도 있습니다 int.
Gabe

1

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

간단하게 유지하는 멋진 Ruby 솔루션. :-) (+1)
Platinum Azure

그것을 간단한 긴 지나치게 그것을 유지하기위한 변명하지 않습니다 유지 ;-)하지만
조이

'if n == 0'을 'if! n'으로 대체 할 수 있다고 생각합니다.
Vincent

2
루비에서? 나는 항상 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자를 저장하려면로 변경할 수도 있습니다 .
gwell

Lua에서 쉼표는 개행으로 렌더링됩니까? 내가 사용한 지 오래되었습니다.
Nick Van Brunt

쉼표는 탭으로 렌더링됩니다.
gwell

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
토마스 대한 수정 사항

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 2010-07-13

좋은 농담. :-D 프로그램이 잘되어 있습니다.
Tom Pažourek

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


참고 : 댓글에서 다른 사람의 답변을 개선하는 데 지쳤으므로 이제 욕심이 많고 여기에 변경 사항을 추가 할 수 있습니다. :) 이것은 Platinum Azure 의 답변 크레딧에서 부분적으로 Hobbs , mobrulePlatinum Azure .


$_%10&&...구조를 제거했을 때 입력 20,30,40, ...에 대한 사양을 어겼습니다.
mob

+1 잘하셨습니다. 당신은 stdin에서 args로 갔다 :-(
Platinum Azure

맞습니다 . :) 또는 ..로 ARGV채워지는 로 대체됩니다 STDIN. echo bar | xargs perl foo.pl기술적으로 echo에서 perl에 대한 args로 파이프됩니다. :)
vol7ron

0

숫자 단어가 포함 된 뻔뻔한 펄 (329 자)

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이 참 / 거짓을 반환 하는 것은 너무 나쁩니다 . 카운트를 반환하면 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}

-7
while(true)
{
    string a;
    ReadLine(a)
    WriteLine(4);

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.