코드 골프 : 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, maxmin함수 가 필요하다고 생각하지 않습니다 . 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.