コードゴルフ:6174-カプレカーの神話上の定数


24

なぜ6174という数字がとても面白いのですか?以下のように定義ウィキペディアで

  1. 少なくとも2桁の数字を使用して、4桁の数字を入力します。(先行ゼロは許可されます。)
  2. 必要に応じて先行ゼロを追加して、2つの4桁の数字を取得するために、数字を昇順および降順で並べます。
  3. 大きい数字から小さい数字を引きます。
  4. 手順2に戻ります。

Kaprekarのルーチンとして知られる上記のプロセスは、最大7回の反復で常に6174に達します。6174に達すると、プロセスはそれを譲り続けます。

所定の4桁の数字(上記の定義を参照)に対してKaprekarのルーチンを実行するプログラムを作成し、ルーチンの各ステップを印刷します。

ルール:

  • 提出は完全なプログラムでなければなりません。
  • 入力は標準入力から読み取る必要があります。エコーからの配管は問題ありません。
  • 入力は数値形式でなければなりません。
  • 先行ゼロを印刷する必要があります。(以下の例を参照してください。)
  • 最後の行には、必要な反復回数が記載されている必要があります。句読点が必要です。

例:

> 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に感謝します。


これは私にとってニュースです。誰かが...司会を呼び出す

ええと…「移行」ボタンはありませんか?
レブム博士

モデレーターが移行するためにこれにフラグを立てました。以前の3桁バージョンと一致するように、入力出力のルールを変更することをお勧めしますか?また、質問の本文の以前のバージョンへのリンク。
dmckee

@dmckee私はこのサイトについて知らなかったし、すでに同様の質問があることを知ることができませんでした(stackoverflowには何もありませんでした)。ただし、3桁バージョンに一致するようにルールを変更することをheし、2つの質問をさらに類似させます。既存の質問の複製またはわずかなバリエーションを投稿することは無意味です。意図せずに行った場合でも。
ルノホドフ

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

Ruby 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:呼び出しの例を追加しました。また6174、入力として正しい出力が生成されるようになりました。残念ながら、このソリューションは最大128文字になります。
ヴェンテロ

を使用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:警告と呼び出し例を修正しました。
ヴェンテロ

7

Python、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 を使用してループ全体を1行に配置します。while n-6174printと引用符の間にスペースはありません。
キースランドール

@ keith-randall:おかげで、今では141個になりました。
マーティンUeding

6

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

2文字をインライン化rしてs保存します。また、「000」は冗長です。「0」で十分です。これにより、188文字になります。私はinteractここで助けていないことに驚いています。通常はそうです。
ローター

置換するshow x++sと、shows x sさらに2バイト増えます。186今。
ローター

パターンガード(|k>0)を使用することで、取り除くことができますf。さらに名前gを変更する%と、182文字になります。
ローター

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

JavaScript、 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
私はあなたが変えることができると思いますn != 6174n-6174、それは(少なくともCとPythonで)偽である、0を返しますので、。
マーティンUeding

クレジットは、私のPythonソリューションのためにそれを提案したkeith-randallに行くべきです。
マーティンUeding

に置き換えることでwhile(n.length<4)、さらに5文字を保存できますwhile(!n[3])
DocMax

1
これを見つめるのは止められません!以下は、a)n = 6174の場合に出力を修正し、b)n+'\n'条件付きおよび追加を回避するために追加された場合に再配置し\nます。パディングに単一の「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の場合、少なくとも1回の反復処理が必要なので、if if iが0(+4)であるが、それと組み合わせてチェックしi++ます。残念ながら、それは1つのエラーを発生させるため、増分を減分に切り替え、最後に少しビットごとのトリックを使用しました(-1)。その後i=0,o=e=''i=o=e=''(-2)に変更し、for余分な括弧を避けるためにループを再フォーマット(-1)、(b=...,a=...,b)ビットを拡張(-2)し、呼び出しa=b.join内に潜入しましたreverse()(-1)。だから169、悪くない!
ケーシーチュウ

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

JavaScript、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

Clojure、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

Scala 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のApp特性を利用します。

編集: 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";

私はあなたが必要とは思わないabsmaxminソートは常にそれが意味することから、機能を$bより大きくなります$a。これにより、20人のキャラクターを節約できます。また、ソートを先頭のループ内に配置すると、コード内にソートを1回行うだけで別の9を節約できると思います。
Gareth

うわー、「大きい数字から小さい数字を引く」命令に気を取られたと思います。ありがとう。
リンタウン

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

CoffeeScript、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+'.')

ここで、またはこちらの手順試してください。


ブラウザがフリーズする-スクリプトの実行をキャンセルする必要がありました。
ルノホドフ

何番に入ったの?FirefoxとChromeで4711と1、その他2、3で試しました。
ジョナスエルフストローム

使用する0(プロンプトにより示唆されるように)、または[キャンセル]ボタンをクリックするとSafariがフリーズする原因となります。
ルノホドフ

なぜそれが示唆されたかは分かりません。1〜9998の数字を入力する必要がありますが、数字はすべて同じではありません。0は0000と同じであり、無限ループを引き起こします。ここでのソリューションのほとんどは、文字数を抑えるために入力の検証をスキップしたようです。
ジョナスエルフストローム

i56.tinypic.com/bhhoqe.pngを参照してください。出力は、「Kaprekarの定数に達するまでに5回の反復が必要でした」で終了します。要件に準拠していません。
ルノホドフ

2

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

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

diff:

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 @:欠落点を追加しました。また、私はgnu awk(gawk)を使用しましたが、それは欠落している機能を説明するかもしれません。
ダンアンドレッタ

減算数は間違った方法です:例9992 - 2999 = 6993
クリスデグネン14年

2

Ruby、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の文字...
アマン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

Mathematica、 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を少なくとも1回繰り返す必要があるため、ようやく自分のトリックを使用するようになりました.&{ }

説明:

    .&{                         } # 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.