Kode Golf: 6174 - Konstanta mitos Kaprekar


24

Mengapa angka 6174 begitu menarik? Seperti yang didefinisikan oleh Wikipedia

  1. Ambil angka empat digit, menggunakan setidaknya dua digit berbeda. (Angka nol diijinkan.)
  2. Aturlah digit dalam urutan naik dan kemudian turun untuk mendapatkan dua angka empat digit, tambahkan angka nol di depan jika perlu.
  3. Kurangi angka yang lebih kecil dari angka yang lebih besar.
  4. Kembali ke langkah 2.

Proses di atas, yang dikenal sebagai rutinitas Kaprekar, akan selalu mencapai 6174 di paling banyak 7 iterasi. Setelah 6174 tercapai, proses akan terus menghasilkan itu.

Tulis program yang menjalankan rutinitas Kaprekar terhadap angka empat digit yang diberikan (lihat definisi di atas) untuk mencetak setiap langkah rutin.

Aturan:

  • Pengajuan harus merupakan program yang lengkap.
  • Input harus dibaca dari input standar. Pemipaan dari echo tidak masalah.
  • Masukan harus dalam bentuk angka.
  • Diperlukan angka nol di depan. (Lihat contoh di bawah.)
  • Baris terakhir harus mengatakan berapa banyak iterasi yang dibutuhkan. Tanda baca diperlukan.

Contoh:

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

Setiap bahasa pemrograman dipersilahkan. Poin ekstra untuk poin esoterik + hadiah kecil.

Pembaruan 1 : Sudah ada pertanyaan serupa .

Pembaruan 2 : Contoh yang ditambahkan untuk 6174 sebagai input. Terima kasih kepada Peter Taylor untuk pemberitahuannya.


Ini berita buat saya. Seseorang memanggil moderator ...

Eh ... bukankah ada tombol "migrasi"?
Dr. Rebmu

Saya telah menandai ini agar moderator melakukan migrasi. Bolehkah saya menyarankan mengubah aturan pada input input agar setuju dengan versi 3 digit sebelumnya? Dan menghubungkan ke versi sebelumnya di tubuh pertanyaan.
dmckee

@ dmckee Saya tidak tahu tentang situs ini dan tidak bisa tahu bahwa sudah ada pertanyaan serupa (pada stackoverflow tidak ada). Namun saya akan ragu mengubah aturan untuk setuju dengan versi 3 digit dan dengan demikian membuat dua pertanyaan lebih mirip. Tidak ada gunanya memposting duplikat atau sedikit variasi dari pertanyaan yang ada. Bahkan ketika dilakukan tanpa disengaja.
lunohodov

3
Silakan tambahkan 6174 sebagai contoh sehingga kita dapat melihat bagaimana output harus diformat.
Peter Taylor

Jawaban:


9

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

EDIT: Sekarang sesuai dengan kasus 6174, dengan biaya beberapa karakter ... dijalankan bersama echo -n <number> | perl kaprekar.pl

EDIT: Akhirnya kembali ke tempat saya sebelumnya: D


10

Ruby 1.9, 122 karakter

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

Doa contoh:

$ echo 1211 | ruby -ln kaprekar.rb

Saya telah menghitung -lnbendera sebagai 4 karakter (perbedaan antara doa normal ruby kaprekar.rbdan ruby -ln kaprekar.rb).


Saya menyimpan skrip ini sebagai kaprekar.rb kemudian memanggilnya dengan ruby -lp kaprekar.rb. Masukkan nomor dan tekan <Enter> tetapi outputnya adalah nomor yang dimasukkan itu sendiri. Jelas saya kehilangan sesuatu ... Mohon saran bagaimana menggunakan skrip.
lunohodov

@ lunohodov: Saya telah menambahkan contoh doa. Sekarang juga menghasilkan output yang benar untuk 6174input, yang sayangnya membawa solusi ini hingga 128 karakter.
Ventero

Menggunakan echo 1234 | ruby kaprekar.rbmemunculkan peringatan dan diakhiri dengan kesalahan undefined method 'chars' for nil:NilClass (NoMethodError). Melaksanakan echo 1234 | ruby -lp kaprekar.rbmasalah hanya peringatan dan berperilaku seperti yang diharapkan. Outputnya tidak seperti yang diharapkan, karena mengandung pesan peringatankaprekar.rb:3: warning: regex literal in condition
lunohodov

@ lunohodov: Memperbaiki peringatan dan contoh doa.
Ventero

7

Python, 141 karakter

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

+1 untuk bantalan yang licin dengan% 04d. Saya belajar sesuatu hari ini!
arrdem

3
Beberapa saran: letakkan seluruh loop pada satu baris menggunakan ;s. while n-6174. Tidak ada ruang antara printdan kutipan.
Keith Randall

@ keith-randall: terima kasih, turun ke 141 sekarang.
Martin Ueding

6

Golfscript, 74 karakter

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

5

Haskell, 197 192 182 181 karakter

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)

Menyejajarkan rdan smenyimpan 2 karakter. Juga, "000" berlebihan. "0" sudah cukup. Ini membawa kita ke 188 karakter. Saya terkejut interacttidak membantu di sini. Biasanya begitu.
Rotsor

Mengganti show x++sdengan shows x smendapatkan 2 byte lebih banyak. 186 sekarang.
Rotsor

Dengan menggunakan penjaga pola ( |k>0) seseorang dapat menyingkirkan f. Mengubah nama lebih lanjut guntuk %membuat kita menjadi 182 karakter.
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;

Tidak banyak pesaing untuk golf, tetapi menyenangkan untuk menulis. :)

Jalankan dengan./fish.py kaprekar.fish -v <number>
EDIT: Sekarang ambil input dari STDIN.


4

JavaScript, 189 182 165 karakter

Kredit ke 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+'.')

Asli:

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

Tidak Disatukan:

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
Saya berpikir bahwa Anda dapat mengubah n != 6174ke n-6174karena akan kembali nol, yang palsu (setidaknya dalam C dan Python).
Martin Ueding

Penghargaan harus diberikan kepada keith-randall yang menyarankannya untuk solusi Python saya.
Martin Ueding

Anda dapat menyimpan 5 karakter lebih banyak dengan menggantinya while(n.length<4)dengan while(!n[3]).
DocMax

1
Saya tidak bisa berhenti menatap yang satu ini! Berikut ini a) memperbaiki output ketika n = 6174, b) mengatur ulang ketika n+'\n'ditambahkan untuk menghindari persyaratan dan tambahan \n, c) menggunakan temp untuk menghindari urutan join-split-join, d) mengambil keuntungan dari fakta bahwa kami hanya perlu menambahkan satu '0' untuk padding: 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+'.')yang seharusnya 172 karakter.
DocMax

1
Impresif! Menurut spec di atas, ketika n = 6174, ia harus melalui setidaknya satu iterasi, jadi saya menambahkan cek jika i0 (+4) tetapi dikombinasikan dengan i++. Sayangnya, itu menghasilkan kesalahan satu kali, jadi saya mengganti selisih menjadi penurunan dan kemudian menggunakan sedikit tipu daya tipuan di akhir (-1). Kemudian saya mengubah i=0,o=e=''ke i=o=e=''(-2), memformat ulang forloop untuk menghindari tanda kurung tambahan (-1), (b=...,a=...,b)bit diperluas (-2), dan menyelinap a=b.joindi dalam reverse()panggilan (-1). Jadi 169, tidak buruk!
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."

Lewati semua kasus uji dari pertanyaan.


2

JavaScript, 260 byte

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 karakter

(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 karakter

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

Memanfaatkan sifat Aplikasi dari Scala 2.9.

Sunting: memberikan output yang benar untuk input awal 6174.


2

PHP, 215 259 276 karakter

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

Tidak Disatukan:

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

Saya tidak berpikir Anda membutuhkan abs, maxdan minfungsi, karena pengurutan akan selalu berarti $blebih besar dari $a. Itu bisa menghemat 20 karakter. Juga, saya pikir menempatkan semacam itu di dalam loop di atas akan berarti Anda hanya perlu memilikinya dalam kode Anda sekali yang akan menyelamatkan Anda lagi 9.
Gareth

Wow, saya kira saya terganggu oleh instruksi "kurangi angka yang lebih kecil dari angka yang lebih besar". Terima kasih.
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";} Anda dapat menyimpan 12 karakter dengan mengubah forpernyataan Anda , menyebutnya sebagai fungsi dan menggunakan joinalih-alih implode.
TwoScoopsofPig

Juga, saya benci mini-markdown.
TwoScoopsofPig

2

CoffeeScript, 233 225 karakter

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

Cobalah di sini atau dengan instruksi di sini .


Peramban saya macet - harus membatalkan eksekusi skrip.
lunohodov

Apa nomor yang Anda masukkan? Saya mencobanya di Firefox dan Chrome untuk 4711 dan 1 dan beberapa lainnya.
Jonas Elfström

Menggunakan 0(seperti yang disarankan oleh prompt) atau mengklik tombol batal menyebabkan Safari membeku.
lunohodov

Saya tidak tahu mengapa itu menyarankan itu. Anda harus memasukkan angka antara 1 dan 9998 yang digitnya tidak semuanya sama. 0 sama dengan 0000 dan akan menyebabkan infinite loop. Tampaknya sebagian besar solusi di sini melewatkan input validasi untuk menjaga jumlah karakter tetap rendah.
Jonas Elfström

Lihat i56.tinypic.com/bhhoqe.png Output Anda juga berakhir dengan "Butuh 5 iterasi untuk mencapai konstanta Kaprekar." yang tidak sesuai dengan persyaratan.
lunohodov

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

beda:

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

2

GAWK - 152 karakter

Ini adalah versi awk GNU. Ini mungkin tidak bekerja dengan versi non-gnu lainnya.

{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

Saya menerima awk: calling undefined function asort. Versi awk adalah 20070501 berjalan pada OSX 10.6.7. Jangan lupa .setelah jumlah iterasi.
lunohodov

lunohodov @: Menambahkan titik yang hilang. Juga, saya telah menggunakan gnu awk (gawk), dan itu mungkin menjelaskan fungsi yang hilang.
Dan Andreatta

Angka pengurangan adalah salah arah: mis. Seharusnya9992 - 2999 = 6993
Chris Degnen

2

Ruby, 179 karakter tetapi tetap memposting

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

ruby cukup keren
jangan terang

1

PERL

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

Thats ~ 310 chars ...
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];}

Uji kasus

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 karakter

Ini adalah programnya, 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]

Mengatur jalur sebelum menjalankan: -

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

Menjalankan program: -

$ 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 byte

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

Cobalah online!

Program lengkap, input STDIN, jalankan dengan php -nF.

Keluaran

> 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

Karat - 375 byte

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

Saya menyajikan ini sebagai "batas atas" yang mungkin, saya menantang siapa pun untuk menemukan bahasa di mana implementasi yang masuk akal dari ini lebih lama - karena di sana tidak ada yang berlebihan, tetapi juga tidak ada yang jelas bahkan jauh yang akan menyusut secara signifikan. Hal tentang Rust adalah dibutuhkan sekitar 120 karakter hanya untuk membaca dari stdin dan mengurai menjadi integer. "Oh, tapi kemudian gunakan representasi string" ... tapi aku yakin 99% itu akan lebih lama


0

Perl 6Bendera -n, 105 byte

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

Cobalah online!

Saya akhirnya bisa menggunakan {}...* trik , karena kita harus memiliki setidaknya satu iterasi untuk 6174. Saya tidak yakin mengapa saya membutuhkan pembungkus tambahan di .&{ }sekitar urutan, yang agak menyebalkan.

Penjelasan:

    .&{                         } # 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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.