코드 골프 : 6174-Kaprekar의 신화적인 상수


24

숫자 6174가 왜 그렇게 흥미로운가요? Wikipedia에서 정의 한대로

  1. 최소한 두 개의 다른 숫자를 사용하여 4 자리 숫자를 사용하십시오. (리딩 제로가 허용됩니다.)
  2. 숫자를 오름차순으로 정렬 한 다음 내림차순으로 정렬하여 필요한 경우 앞에 0을 추가하여 두 자리 숫자를 얻습니다.
  3. 큰 숫자에서 작은 숫자를 뺍니다.
  4. 2 단계로 돌아가십시오.

Kaprekar의 루틴으로 알려진 위의 프로세스는 항상 최대 7 회 반복으로 6174에 도달합니다. 6174에 도달하면 프로세스에서 계속 생성합니다.

루틴의 각 단계를 인쇄하는 주어진 4 자리 숫자 (위 정의 참조)에 대해 Kaprekar의 루틴을 실행하는 프로그램을 작성하십시오.

규칙 :

  • 제출은 완전한 프로그램이어야합니다.
  • 표준 입력에서 입력을 읽어야합니다. 에코 에서 파이핑 이 가능합니다.
  • 입력은 숫자 형식이어야합니다.
  • 선행 0을 인쇄해야합니다. (아래 예 참조)
  • 마지막 줄은 몇 번의 반복이 필요한지 말해야합니다. 문장 부호가 필요합니다.

예 :

> 2607
7620 - 0267 = 7353
7533 - 3357 = 4176
7641 - 1467 = 6174
Iterations: 3.

> 1211
2111 - 1112 = 0999
9990 - 0999 = 8991
9981 - 1899 = 8082
8820 - 0288 = 8532
8532 - 2358 = 6174
Iterations: 5.

> 6174
7641 - 1467 = 6174
Iterations: 1.

모든 프로그래밍 언어를 환영합니다. 난해한 사람 + 작은 현상금에 대한 추가 포인트.

업데이트 1 : 이미 비슷한 질문이 있습니다.

업데이트 2 : 6174에 대한 예제를 입력으로 추가했습니다. 통지 해 주신 Peter Taylor에게 감사드립니다.


이것은 나를위한 뉴스입니다. 누군가 전화 사회자 ...

어 ... "마이그레이션"버튼이 없습니까?
— Dr. Rebmu

중재자가 마이그레이션하도록 플래그를 지정했습니다. 이전 3 자리 버전과 일치하도록 입력 출력 규칙을 변경할 것을 제안 할 수 있습니까? 질문 본문에서 이전 버전으로 연결합니다.
— dmckee 2016 년

@ dmckee 나는이 사이트에 대해 몰랐고 이미 비슷한 질문이 있음을 알 수 없었습니다 (스택 오버 플로우에는 없음). 그러나 3 자리 버전에 동의하도록 규칙을 변경하여 두 가지 질문을 더 비슷하게 만드는 것을 망설이고 있습니다. 기존 질문의 복제본이나 약간의 변형을 게시하는 것은 의미가 없습니다. 의도하지 않은 경우에도 마찬가지입니다.
— lunohodov

3
출력 형식을 지정하는 방법을 볼 수 있도록 6174를 예로 추가하십시오.
— 피터 테일러

답변:


9

펄 - 147 143 134 130 129 126 129 128 126

for($_=<>;$_-6174+!$c;$c++){$_=reverse$d=join'',sort split//,"$_"
|$|x4;printf"$_ - $d = %04d\n",$_-=$d}die"Iterations: $c.\n"

편집 : 이제 몇 문자를 희생하면서 6174 사례를 준수합니다 ... echo -n <number> | perl kaprekar.pl

편집 : 마지막으로 내가 이전 위치로 돌아 가기 : D


10

루비 1.9, 122 자

puts"Iterations: #{(1..7).find{s=$_.chars.sort*"";puts [r=s.reverse,?-,s,?=,$_="%04d"%(r.to_i-s.to_i)]*" ";~/6174/}}."

예제 호출 :

$ echo 1211 | ruby -ln kaprekar.rb

-ln플래그를 4 자로 계산했습니다 (정상 호출 ruby kaprekar.rb과와의 차이점 ruby -ln kaprekar.rb).


이 스크립트를 kaprekar.rb로 저장 한 다음로 호출했습니다 ruby -lp kaprekar.rb. 숫자를 입력하고 <Enter>를 눌렀지만 출력은 입력 된 숫자 자체입니다. 분명히 뭔가 빠졌습니다 ... 스크립트 사용법을 알려주세요.
— lunohodov 2016 년

@lunohodov : 예제 호출을 추가했습니다. 또한 6174입력으로 올바른 출력을 생성하여 불행히도이 솔루션을 최대 128 자로 만듭니다.
— Ventero

를 사용 echo 1234 | ruby kaprekar.rb하면 경고가 발생하고 오류가 발생 undefined method 'chars' for nil:NilClass (NoMethodError)합니다. 실행 echo 1234 | ruby -lp kaprekar.rb하면 경고 만 표시되고 예상대로 작동합니다. 출력은 경고 메시지를 포함하고 있기 때문에 예상대로 출력되지 않습니다kaprekar.rb:3: warning: regex literal in condition
— lunohodov

@lunohodov : 경고와 예제 호출을 수정했습니다.
— Ventero

7

파이썬, 141 자

n=input()
i=0
while n-6174:a=''.join(sorted("%04d"%n));b=a[::-1];n=int(b)-int(a);print"%s - %s = %04d"%(b,a,n);i+=1
print"Iterations: %d."%i

% 04d의 매끄러운 패딩에 +1 나는 오늘 무언가를 배웠다!
— arrdem

3
몇 가지 제안 : ;s를 사용하여 전체 루프를 한 줄에 넣으십시오 . while n-6174. print와 따옴표 사이에 공백이 없습니다 .
— Keith Randall

@ keith-randall : 감사합니다. 지금 141로 떨어졌습니다.
— Martin Ueding

6

골프 스크립트, 74 자

);:|;{0):0;|$:§-1%" - "§" = ""0"4$~§~-+-4>:|n|6174`=!}do"Iterations: "0"."

5

하스켈, 197 192 182 181 자

import List
p=putStrLn.unwords
"6174"%k|k>0=p["Iterations:",shows k"."]
n%k=p[b,"-",a,"=",c]>>c%(k+1)where a=sort n;b=reverse a;c=take 4$shows(read b-read a)"0"
main=getLine>>=(%0)

인라인 r하고 s2자를 저장합니다. 또한 "000"은 중복됩니다. "0"이면 충분합니다. 이것은 우리를 188 자로 만듭니다. 나는 interact여기에 도움이되지 않습니다 놀랐습니다 . 보통 그렇습니다.
— Rotsor

교체 show x++s하면 shows x s2 바이트 더 늘어납니다. 186 명
— Rotsor

패턴 가드 ( |k>0) 를 사용 하면 제거 할 수 있습니다 f. 이름 g을 %182 자로 늘리려면 이름 을 바꿉니다 .
— Rotsor

4

> <>- 268 308

</&4pff1
v>i86*-:n&1-:&?!
>ao&        v
<v&0pff+1gff
 >&1+:4=   ?v&:a%:}-a,
 v&8[4r::0}~<
 >&1-:?!v&:@@:@(?$}&:&3%1=?}
 v      >~:}}:}@:}$:}
 \:n}:n}:n}:n}' - 'ooo:n}:n}:n}:n}' = 'ooo
 \a*+a*+a*+}a*+a*+a*+-:0&\
 v?       =4&:+1&,a-}:%a:<
/\&~~rnnnnao:29777****=   ?v
voooooooooooo"Iterations: "/
\ffgna'.'oo;

골프에 대한 경쟁자는별로 없지만 글쓰기는 재미있었습니다. :)

./fish.py kaprekar.fish -v <number>
EDIT로 실행 : 이제 STDIN에서 입력을받습니다.


4

자바 스크립트, 189 182 165 자

DocMax에 대한 크레딧 :

for(n=prompt(i=o=e='');!i--|n-6174;o+=n+' - '+a+' = '+(n=(p=n-a+e)[3]?p:0+p)+'\n')
  b=n.split(e).sort(),n=b.reverse(a=b.join(e)).join(e);
alert(o+"Iterations: "+~i+'.')

기발한:

for(n=prompt(i=o=e='');n-6174;o+=(i++?n+"\n":e)+(n=(a=n.split(e).sort().join(e)).split(e).reverse().join(e))+' - '+a+' = ',n=n-a+e)while(!n[3])n=0+n
alert(o+n+"\nIterations: "+i+'.')

언 골프 드 :

var i = 0;
var n = prompt();
var out = '';
while (n != 6174) {
    while ((n=''+n).length<4) n='0'+n // pad number
    if(i)out+=n+"\n"

    a = n.split('').sort().join('');
    n = a.split('').reverse().join('');

    out += n + ' - ' + a + ' = '
    n-=a
    i++;
}
console.log(out + "6174\nIterations: " + i + '.');

1
나는 그것이 적어도 (C와 Python에서는) 거짓 인 0을 반환 n != 6174하기 n-6174때문에로 바꿀 수 있다고 생각합니다 .
— Martin Ueding 2016 년

크레딧은 keith-randall에게 가서 내 Python 솔루션에 제안했습니다.
— Martin Ueding 2016 년

당신은 대체하여 5 개 이상의 문자를 저장할 수 있습니다 while(n.length<4)로 while(!n[3]).
— DocMax

1
이걸 쳐다볼 수 없어! 다음 a)는 n = 6174 일 때 출력을 수정합니다. b) n+'\n'조건부와 추가를 피하기 위해 추가 될 때 다시 정렬합니다 \n. c) 결합 스플릿 조인 시퀀스를 피하기 위해 temp를 사용합니다. 패딩을 위해 하나의 '0'만 추가하면됩니다 ( for(n=prompt(i=0,o=e='');n-6174;i++,o+=(n=(b=n.split(e).sort(),a=b.join(e),b).reverse().join(e))+' - '+a+' = '+(n=('0'+(n-a)).slice(-4))+'\n');alert(o+"Iterations: "+i+'.')172 자).
— DocMax

1
인상적! 그러나 위의 사양에 따르면 n = 6174 일 때 적어도 하나의 반복을 거쳐야하므로 i0 (+4) 인지 확인 했지만i++ . 불행히도, 그것은 하나의 오류로 인해 떨어져 나옵니다. 그래서 나는 증가를 감소로 바꾸고 마지막에 약간의 속임수를 사용했습니다 (-1). 그런 다음 (-2)로 변경 i=0,o=e=''하고 여분의 괄호 (-1), 확장 된 비트 (-2) 를 피하고 호출 내부에서 몰래 들어가는 것을 피하기 위해 루프를 i=o=e=''다시 포맷했습니다 (-1). 그래서 169, 나쁘지 않습니다! for(b=...,a=...,b)a=b.joinreverse()
— Casey Chu

3

PowerShell을 125 128 130 131

for($a,$OFS=$input+'';$b-6174;++$i){$a=$b=+($c=''+($x="$a 000"[0..4]|sort)[4..0])-"$x"
"$c-$x = {0:d4}"-f$a}"Iterations: $i."

질문의 모든 테스트 사례를 통과합니다.


2

자바 스크립트, 260 바이트

function z(c){for(u=c+y;u.length<4;)u=0+u;return u}for(p=prompt(i=0,r=y="");;)
if(s=(p+y).split(y).sort(),t=s.concat().reverse(),a=s.join(y),b=t.join(y),q=a<b?b:a,
w=a<b?a:b,p=z(q-w),i++,r+=z(q)+" - "+z(w)+" = "+p+"\n",p==6174)break;alert(r+
"Iterations: "+i+".")

2

클로저, 256 자

(let[i #(Integer/parseInt%)f #(format"%04d"%)a #(->>% f sort(apply str)i)d #(->>% f sort reverse(apply str)i)k #(let[u(d %)l(a %)n(- u l)](println(f u)"-"(f l)"="(f n))n)](while true(println"Iterations:"(count(take-while #(not=% 6174)(iterate k(read)))))))

2

스칼라 2.9, 194 자

object K extends App{var(c,s)=(0,args(0));do{var d=s.sorted;var e=d.reverse.toInt-d.toInt;s="%04d".format(e);println(d.reverse+" - "+d+" = "+s);c+=1}while(s!="6174");print("Iterations: "+c+".")}

Scala 2.9의 앱 특성을 사용합니다.

편집 : 6174의 초기 입력에 대한 올바른 출력을 제공합니다.


2

PHP, 215 259 276 문자

<?php echo">";$n=str_split(str_pad(trim(fgets(STDIN)),4,0,0));for($k=0,$z=0;$k-6174;$z++){sort($n);$a=implode($n);$b=strrev($a);$k=str_pad($b-$a,4,0,0);echo"$b - $a = $k\n";$n=str_split($k);}echo"Iterations: $z\n";

언 골프 드 :

<?php
echo ">";
$n = str_split(str_pad(trim(fgets(STDIN)),4,0,0));
for($k=0, $z=0; $k-6174; $z++) {
    sort($n);
    $a = implode($n);
    $b = strrev($a);
    $k = str_pad($b-$a,4,0,0);
    echo "$b - $a = $k\n";
    $n = str_split($k);
}
echo "Iterations: $z\n";

정렬이 항상 그보다 큼을 의미하기 때문에 abs, max및 min함수 가 필요하다고 생각하지 않습니다 . 20 문자를 절약 할 수 있습니다. 또한 루프의 맨 위에 정렬을 넣으면 코드에 한 번만 저장하면 다른 9를 저장할 수 있다고 생각합니다.$b$a
— Gareth

와우, 나는 "큰 숫자에서 작은 숫자를 빼라"라는 지시에 산만 해졌다. 감사.
— rintaun

<?function k($c){echo"> $c\n";$n=str_split(str_pad($c,4,0,0));for(;$k-6174;$z++){sort($n);$a=join($n);$b=strrev($a);$k=str_pad($b-$a,4,0,0);echo"$b - $a = $k\n";$n=str_split($k);}echo"Iterations: $z\n";}for명령문 을 변경 하고 함수로 호출하고 join대신을 사용하여 12자를 저장할 수 있습니다 implode.
— TwoScoopsofPig

또한, 나는 미니 마크 다운이 싫어.
— TwoScoopsofPig

2

커피 스크립트, 233 개 (225) 문자

o=e='';i=0;n=prompt()
while n!=6174
  n=e+n;q=(n='0'+n if !n[3]) for x in [0..2];n?=q;o+=n+"\n" if i;a=n.split(e).sort().join(e);n=a.split(e).reverse().join(e);o+=n+' - '+a+' = ';n-=a;i++
alert(o+"6174\nIterations: "+i+'.')

그것을 시도 여기 또는 지침 여기에 .


브라우저가 멈췄습니다. 스크립트 실행을 취소해야했습니다.
— lunohodov 2016 년

어떤 번호를 입력 했습니까? Firefox 및 Chrome에서 4711 및 1 및 다른 몇 가지를 시도했습니다.
— Jonas Elfström 2016 년

사용 0(프롬프트에 의해 제안) 또는 취소 버튼을 클릭하면 사파리가 동결됩니다.
— lunohodov 2016 년

왜 그런 제안인지 모르겠습니다. 숫자가 모두 같지 않은 1에서 9998 사이의 숫자를 입력해야합니다. 0은 0000과 동일하며 무한 루프를 발생시킵니다. 여기에서 대부분의 솔루션은 문자 수를 유지하기 위해 입력 유효성 검사를 건너 뛰었습니다.
— Jonas Elfström 2016 년

i56.tinypic.com/bhhoqe.png를 참조하십시오. 또한 출력은 "Kaprekar 상수에 도달하는 데 5 번의 반복이 필요했습니다"로 끝납니다. 요구 사항을 준수하지 않습니다.
— lunohodov 2016 년

2

스칼라 276

object o{var i=0;def a(v:String){val c=v.toList.sortWith(_>_).mkString;val b=c.reverse;val d=c.toInt-b.toInt;val e="0"*(4-(d+"").length)+d;val p=c+" - "+b+" = "+e;if(d!=6174){println(p);i=i+1;a(e)}else{println(p+"\nIterations: "+(i+1)+".")}};def main(s:Array[String])=a(s(0))}

스칼라 283

object o{var i=0;def a(v:String){val c=v.toList.sortWith(_>_).mkString;val b=c.reverse;val d=c.toInt-b.toInt;val e="0"*(4-(d+"").length)+d;val p=c+" - "+b+" = "+e;if(d!=6174){println(p);i=i+1;a(e)}else{println(p);println("Iterations: "+(i+1)+".")}};def main(s:Array[String])=a(s(0))}

차이점 :

else{println(p);println("Iterations: "+(i+1)+".")}};
// to
else{println(p+"\nIterations: "+(i+1)+".")}};

2

GAWK-152 자

이것은 GNU awk 버전입니다. gnu 이외의 다른 버전에서는 작동하지 않을 수 있습니다.

{for(z=$1;z-6174+!c;++k){split(z,a,"");asort(a);for(b=c=i=0;i<4;z=c-b){c+=a[i+1]*10^i;b=b*10+a[++i]}printf c" - %.4d = "z"\n",b}print"Iterations: "k"."}

$ awk -f k.awk <<< 9992
2999 - 9992 = 6993
3699 - 9963 = 6264
2466 - 6642 = 4176
1467 - 7641 = 6174
Iterations: 4

나는받습니다 awk: calling undefined function asort. Awk 버전은 OSX 10.6.7에서 실행되는 20070501입니다. .반복 횟수 이후를 잊지 마십시오 .
— lunohodov 2016 년

lunohodov @ : 누락 된 지점이 추가되었습니다. 또한 gnu awk (gawk)를 사용했는데 누락 된 기능을 설명 할 수 있습니다.
— Dan Andreatta

빼기 숫자는 잘못된 길입니다 : 예 :9992 - 2999 = 6993
— Chris Degnen

2

루비, 179 자이지만 어쨌든 게시

s=gets.chomp
n=0
begin
  s=s.to_s.chars.sort.reduce{|s,c|s+c}.rjust(4,'0')
  a=s.reverse
  puts"#{a} - #{s} = #{'%04d'%(s=a.to_i-s.to_i)}"
  n+=1
end while s!=6174
puts"Iterations: #{n}."

루비는 꽤 시원합니다
— 밝게

1

펄

chomp($n=<STDIN>);
    do{
       $t++;
       $desc=join('',reverse sort split(//,$n));
       $asc=join('', sort split(//,$n));
       $n=($desc - $asc);
       for($i=4;$i>length $n;$i--){
          $n="0".$n;
       }
       print $desc." - ".$asc." = ".$n."\n";
       $n="6174" if $n eq "0000";
    }while($n ne "6174");
    print "Iterations: $t.\n";

그 ~ 310 자 ...
— Aman ZeeK Verma

1

K, 104

{b::();{b,:,k," = ",r:"0"^(-:4)$$. k:(x@>x)," - ",x@<x;r}\[$x];-1'c,,"Iterations: ",$#c:$[1=#b;b;-1_b];}

테스트 사례

k){b::();{b,:,k," = ",r:"0"^(-:4)$$. k:(x@>x)," - ",x@<x;r}\[$x];-1'c,,"Iterations: ",$#c:$[1=#b;b;-1_b];}'2607 1211 6174;
7620 - 0267 = 7353
7533 - 3357 = 4176
7641 - 1467 = 6174
Iterations: 3
2111 - 1112 = 0999
9990 - 0999 = 8991
9981 - 1899 = 8082
8820 - 0288 = 8532
8532 - 2358 = 6174
Iterations: 5
7641 - 1467 = 6174
Iterations: 1

1

수학, 314 291 자

이것은 kaprekar.m 프로그램입니다.

SetOptions[$Output,FormatType->OutputForm];
x=$ScriptCommandLine[[2]];
f[x_]:=(a=Characters@x;
b=Sort@ToExpression@a;
c=Sort[FromDigits/@{#,Reverse@#}&@b];
{c,{b,a}}=IntegerString[{#2-#&@@c,c},10,4];
Print[a," - ",b," = ",c];c)
x=f@x;
e=NestWhileList[f,x,#!="6174"&];
Print["Iterations: ",N@Length@e]

실행하기 전에 경로 설정 :-

$ PATH=${PATH}:/Applications/Mathematica.app/Contents/MacOS ; export PATH

프로그램 실행 :-

$ MathematicaScript -script kaprekar.m 2607
7620 - 0267 = 7353
7533 - 3357 = 4176
7641 - 1467 = 6174
Iterations: 3.
$ MathematicaScript -script kaprekar.m 1211
2111 - 1112 = 0999
9990 - 0999 = 8991
9981 - 1899 = 8082
8820 - 0288 = 8532
8532 - 2358 = 6174
Iterations: 5.
$ MathematicaScript -script kaprekar.m 6174
7641 - 1467 = 6174
Iterations: 1.

0

PHP , 160 바이트

function k($n,$d=1){$o=str_split($n);sort($o);echo$q=strrev($r=join($o))," - $r = ",$n=str_pad($q-$r,4,0,0),"
",$n==6174?"Iterations: $d.":k($n,++$d);}k($argn);

온라인으로 사용해보십시오!

전체 프로그램, 입력은 STDIN로 실행됩니다 php -nF.

산출

> echo 2607|php -nF kap.php
7620 - 0267 = 7353
7533 - 3357 = 4176
7641 - 1467 = 6174
Iterations: 3.

> echo 1211|php -nF kap.php
2111 - 1112 = 0999
9990 - 0999 = 8991
9981 - 1899 = 8082
8820 - 0288 = 8532
8532 - 2358 = 6174
Iterations: 5.

> echo 6174|php -nF kap.php
7641 - 1467 = 6174
Iterations: 1.

0

녹-375 바이트

use std::io::{self,BufRead};fn main() {let mut x=io::stdin().lock().lines().next().unwrap().unwrap().parse::<i16>().unwrap();let mut n=0;println!("Iterations: {}.",loop {let mut v=[x/1000%10,x/100%10,x/10%10,x%10];v.sort();let j=v.iter().fold(0,|a,i|a*10+i);let k=v.iter().rev().fold(0,|a,i|a*10+i);x=k-j;n+=1;println!("{:04} - {:04} = {:04}",k,j,x);if x==6174{break n};});}

나는 이것을 가능한 "상한"으로 제시하며, 합리적인 구현이 더 긴 언어를 찾도록 요구합니다. Rust에 대한 것은 stdin에서 읽고 정수로 구문 분석하는 데 약 120자가 필요하다는 것입니다. "아, 그러면 그냥 문자열 표현을 사용하십시오"...하지만 99 %는 더 길 것이라고 확신합니다


0

Perl 6 -n 플래그, 105 바이트

say "Iterations: "~+.&{{{say $!=.flip~" - $_"," = ",($/=$!.EVAL.fmt("%04d"));$/}([~] .comb.sort)}...6174}

온라인으로 사용해보십시오!

나는 마침내 내 것을 사용해야합니다 {}...*6174에 대해 하나 이상의 반복이 필요하기 때문에 트릭 왜 .&{ }시퀀스 주위에 여분의 랩핑이 필요한지 잘 모르겠습니다 .

설명:

    .&{                         } # Call a function on the input
       {                }...6174  # Create a sequence that goes until 6174
        {           }([~] .comb.sort) # Get the sorted digits of the number
         say $!=.flip~" - $_"," = "~($/=$!.EVAL.fmt("%04d"))  # Print the iteration
                        ;$/  # Return the result
say "Iterations: "~+.&{      }     # Print the number of iterations
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.