퍼즐
고등학교 때 들었던 작은 수수께끼는 이런 식으로 진행되었습니다.
- 질문자는 나에게 번호를 물어볼 것입니다.
- 숫자를 듣고 질문자는 결국 숫자 4에 도달 할 때까지 (예를 들어 10은 3 이라고 말할 수 있음) 반복적으로 변형을 수행합니다 ( 4로 끝나는 시점 은 마술입니다 ).
- 어떤 숫자라도 결국 4 개로 변환 될 수있는 것 같습니다.
목표는 변형 함수를 알아 내고이 퍼즐을 스스로 확실하게 감독 할 수 있도록하는 것이 었습니다.
해결책
모든 단계에서 변환 기능은
- 문제의 번호를 가지고
- 하이픈이나 공백 또는 “and”를 무시하고 영어 단어 표현의 문자 수를 계산합니다 (예 : “ten”에는 3 개의 문자가 있고, “thirty-four”에는 10 개의 문자가 있습니다. “1 백 사십 삼”) 20 글자 포함).
- 그 수의 문자를 반환하십시오.
내가 테스트 해 본 모든 숫자에 대해, 이것은 4로 수렴됩니다. “four”도 그 안에 4 개의 문자가 있기 때문에 여기에 무한 루프가 있습니다. 대신 시퀀스를 끝내는 것은 관례 상 마법 이라고합니다 .
도전
당신의 도전은 사용자로부터 숫자를 읽을 코드 조각을 만들고 “four is magic”에 도달 할 때까지 반복적으로 적용되는 변환 함수를 보여주는 줄을 인쇄하는 것입니다.
구체적으로 특별히:
- 솔루션은 그 자체로 완전한 프로그램이어야합니다. 그것들은 단순히 숫자를 취하는 함수가 될 수 없습니다.
- 입력은 표준 입력에서 읽어야합니다. ( “echo”에서 파이핑하거나 입력 리디렉션을 사용하는 것은 stdin에서도 오기 때문에 괜찮습니다)
- 입력은 숫자 형식이어야합니다.
- 변환 함수를 적용 할 때마다 한 줄을 인쇄해야합니다.
a is b.
여기서 a와 b는 변환에서 숫자의 숫자 형식입니다. - 마침표 (마침표)가 필요합니다!
- 마지막 줄은 당연히
4 is magic.
. - 코드는 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.
우승자는 또한 정확한 소스 코드 문자 수에 의한 가장 짧은 제출 입니다.
보너스
변환 함수의 각 응용 프로그램과 함께 숫자에 대한 영어 이름을 인쇄하는 코드 버전을 작성할 수도 있습니다. 원래 입력은 여전히 숫자이지만 출력 행에는 숫자의 단어 형식이 있어야합니다.
(편집) 일부 설명 :
- 해당하는 모든 경우에 단어가 양쪽에 나타나기를 원합니다. 예 :
Nine is four. Four is magic.
- 하지만 대소 문자는 신경 쓰지 않습니다. 그리고 토큰이라는 단어를 분리하는 방법은 신경 쓰지 않습니다. 비록 분리되어야하지만 :
ninety-nine
괜찮아,ninety nine
괜찮아,ninetynine
괜찮지 않습니다.
도전과 관련하여 보너스 경쟁을위한 별도의 범주로 간주하고 있으므로,이 경우 코드가 숫자 버전보다 길다는 것에 대해 걱정하지 마십시오.
각 버전에 대해 하나의 솔루션을 자유롭게 제출하십시오.
답변
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."
답변
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
답변
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.
답변
Python 2.x, 144 150 154 166 문자
이것은 숫자를 10과 1로 분리하고 합산합니다. 의사 – 삼원 연산자의 바람직하지 못한 특성 경우 반환 0 여기 학대이다.a and b or c
c
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."
답변
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()
함수는 문자 e
와 l
(숫자 ‘1’이 아닌 소문자 ‘L’)을 그대로 출력하지만를 찾아서 M
29 번째 항목의 인덱스 (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”의 양면에 숫자 단어를 인쇄해야 함을 명확히하기 위해 요구 사항이 변경되었습니다. 이 새 버전은 해당 요구 사항을 충족하고 필요한 추가 크기를 설명하기 위해 몇 가지 더 많은 최적화를 구현합니다.
답변
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.
답변
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.