Code Golf: 6174 - Kaprekar'ın efsanevi sabiti


24

6174 sayısı neden bu kadar ilginç? Wikipedia tarafından tanımlandığı gibi

  1. En az iki farklı rakam kullanarak dört basamaklı bir rakam alın. (Lider sıfırlara izin verilir.)
  2. İki dört basamaklı sayıları almak için basamakları artan düzende ve ardından azalan düzende düzenleyin, gerekirse baştaki sıfırları ekleyin.
  3. Küçük sayıyı daha büyük sayıdan çıkarın.
  4. 2. adıma geri dönün.

Kaprekar'ın rutini olarak bilinen yukarıdaki işlem en fazla 7 tekrarda 6174'e ulaşacaktır. 6174'e ulaşıldığında, süreç onu vermeye devam edecek.

Kaprekar'ın rutinini, rutinin her adımını basacak şekilde verilen dört basamaklı bir sayıya karşı çalıştıran bir program yazınız.

Kurallar:

  • Gönderimler tam program olmalıdır.
  • Giriş standart girişten okunmalıdır. Dan Boru yankı sorun yok.
  • Giriş sayısal biçimde olmalıdır.
  • Baştaki sıfırları yazdırmak gerekiyor. (Aşağıdaki örneklere bakınız.)
  • Son satırda kaç yinelemenin gerekli olduğunu söylemelisiniz. Noktalama işaretleri gereklidir.

Örnekler:

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

Herhangi bir programlama dili açıktır. Ezoterik olanlar için ekstra puan + küçük bir ödül.

Güncelleme 1 : Zaten benzer bir soru var .

Güncelleme 2 : Giriş olarak 6174 için örnek eklendi. Haberin için Peter Taylor'a teşekkürler.


Bu benim için bir haber. Biri moderatör

Uh ... "göç" butonu yok mu?
Dr. Rebmu

Bunu bir moderatörün taşınması için işaretledim. Girdi çıktısı ile ilgili kuralları 3 basamaklı eski sürüme uyacak şekilde değiştirmeyi önerebilir miyim? Ve sorunun gövdesindeki önceki sürüme bağlantı.
dmckee

@dmckee Bu siteyi bilmiyordum ve zaten benzer bir soru olduğunu bilmiyordum (stackoverflow'da hiçbiri yoktu). Bununla birlikte, kuralları 3 basamaklı versiyona uymaya karar vermekte tereddüt etmekte ve böylece iki soruyu daha benzer hale getirmekte tereddüt ediyorum. Mevcut bir sorunun bir kopyasını veya hafif bir çeşitlemesini göndermek anlamsızdır. İstemeden yapılsa bile.
lunohodov

3
Lütfen örnek olarak 6174'ü ekleyin, böylece çıktının nasıl biçimlendirilmesi gerektiğini görelim.
Peter Taylor,

Yanıtlar:


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: Şimdi 6174 dava ile uyumlu, birkaç karakter pahasına ... echo -n <number> | perl kaprekar.pl

EDIT: Sonunda önceleri bulunduğum yere: D


10

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

Örnek çağrı:

$ echo 1211 | ruby -ln kaprekar.rb

-lnBayrağı 4 karakter olarak saydım (normal başlatma ruby kaprekar.rbile normal arasındaki fark ruby -ln kaprekar.rb).


Bu betiği kaprekar.rb olarak kaydettim, sonra onu çağırdım ruby -lp kaprekar.rb. Bir numara girip <Enter> tuşuna basın ancak çıktı girilen sayının kendisidir. Açıkça bir şeyleri özlüyorum ... Lütfen betiği nasıl kullanacağınızı bildiriniz.
lunohodov

@lunohodov: Bir örnek çağırma ekledim. Şimdi 6174girdi olarak doğru çıktıyı üretiyor , bu da ne yazık ki bu çözümü 128 karaktere kadar getiriyor.
Ventero

Kullanmak echo 1234 | ruby kaprekar.rbbir uyarı verir ve bir hata ile sona erer undefined method 'chars' for nil:NilClass (NoMethodError). Çalıştırma echo 1234 | ruby -lp kaprekar.rbyalnızca bir uyarı verir ve beklendiği gibi davranır. Çıktı beklendiği gibi değil, bir uyarı mesajı içeriyorkaprekar.rb:3: warning: regex literal in condition
lunohodov 17:11

@lunohodov: Uyarı ve örnek çağırma düzeltildi.
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

% 04d ile kaygan dolgu için +1. Bugün bir şey öğrendim!
arrdem

3
Birkaç öneri: ;s ile tüm döngüyü tek bir satıra yerleştirin . while n-6174. printAlıntıyla boşluk yok .
Keith Randall,

@ keith-randall: teşekkürler, şimdi 141'e indirdi.
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)

Satır içi rve s2 karakter kaydeder. Ayrıca, "000" gereksizdir. "0" yeterli. Bu bizi 188 karaktere getiriyor. Şaşırdım interactburada yardımcı olmuyor. Genellikle yapar.
Rotsor

Değiştirme show x++sile shows x skazançlar 2 daha bayt. 186 şimdi.
Rotsor

Desen koruyucuları ( |k>0) kullanarak kişi kurtulabilirsiniz f. Daha adlandırma giçin %182 karakter bizi alır.
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;

Golf için bir rakip değil, ama yazmak için eğlenceliydi. :)

./fish.py kaprekar.fish -v <number>
EDIT ile çalıştır : Şimdi STDIN'den girdi alıyor.


4

JavaScript, 189 182 165 karakter

DocMax’a Kredi:

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

Orijinal:

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

Ungolfed:

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
Sana deðiþebilirler n != 6174için n-6174o (en azından C ve Python) yanlış olan sıfır döndürür beri.
Martin Ueding

Kredi Python çözümüm için öneren Keith-randall'a gitmeli.
Martin Ueding

Sen yerine 5 daha fazla karakter kaydedebilirsiniz while(n.length<4)ile while(!n[3]).
DocMax

1
Buna bakmayı kesemiyorum! Aşağıdakiler a) n = 6174, b) n+'\n'koşullu ve fazladan kaçınmak için tekrar eklendiğinde yeniden düzenlenir \n, c) bir birleşik-bölünmüş-birleştirme sekansından kaçınmak için bir sıcaklık kullanır, d) aşağıdakilerden yararlanır: Dolgu için sadece tek bir '0' eklemelisiniz: 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 karakter olmalı.
DocMax

1
Etkileyici! Yine de, yukarıdaki özelliğe göre, n = 6174 olduğunda, en az bir yinelemeden geçmesi gerekir, bu yüzden i0 (+4) olup olmadığını kontrol ettim ancak bununla birleştirdim i++. Ne yazık ki, bu bir hata ile sonuçlanıyor, bu yüzden artışı bir azalmaya çevirdim ve sonunda küçük bir bit hileci kullandım (-1). Sonra değişti i=0,o=e=''için i=o=e=''(2), yeniden yapılandırılmış forilave parantez önlemek için döngü (-1), genişletilmiş (b=...,a=...,b)bit (2), ve sinsice a=b.joinreverse()çağrısı (1). 169, fena değil!
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."

Tüm test vakalarını sorudan geçer.


2

JavaScript, 260 bayt

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

App özelliklerinden Scala 2.9'dan yararlanır.

Düzenleme: 6174'ün ilk girişi için doğru çıktıyı verir.


2

PHP, 215 259 276 karakterler

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

Ungolfed:

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

Sana ihtiyacım olduğunu sanmıyorum abs, maxve minsıralama her zaman anlamına gelecektir, çünkü işlevlerini $bdaha büyüktür $a. Bu size 20ish karakter kazandırabilir. Ayrıca, döngünün içindeki sırayı en üste koymanın, yalnızca bir kez kodunuzda olması gereken 9 anlamına geleceğini düşünüyorum.
Gareth

Vay be, sanırım "daha küçük sayıyı daha büyük sayıdan çıkar" talimatıyla dikkatimi çekti. Teşekkürler.
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";} İfadenizi değiştirerek for, bunu işlev olarak çağırıp joinyerine kullanarak 12 karakter kaydedebilirsiniz implode.
TwoScoopsofPig

Ayrıca, mini markdown'dan nefret ediyorum.
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+'.')

Burada veya burada talimatlarla deneyin .


Tarayıcım donuyor - betiğin çalışmasını iptal etmek zorunda kaldı.
lunohodov

Hangi numarayı girdiniz? Firefox ve Chrome'da 4711 ve 1 ve birkaç tanesini denedim.
Jonas Elfström

Kullanılması 0(istemde belirtildiği şekilde) veya iptal düğmesine tıklamak Safari'nin donmasına neden olur.
lunohodov

Bunu neden önerdiğini bilmiyorum. Rakamlarının tümü aynı olmayan 1 ile 9998 arasında bir sayı girmeniz gerekir. 0, 0000 ile aynıdır ve sonsuz bir döngüye neden olur. Buradaki çözümlerin çoğu, karakter sayısını düşük tutmak için girişi doğrulama işlemini atladı.
Jonas Elfström

Bkz. İ56.tinypic.com/bhhoqe.png Çıktınız, “ Kaprekar’ın sabitine ulaşmak için 5 tekrar aldı” ile de bitiyor. Bu gereksinimlere uymuyor.
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))}

diff:

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

2

GAWK - 152 karakter

Bu bir GNU awk sürümüdür. Diğer gnu olmayan versiyonlarla çalışmayabilir.

{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

Aldığım awk: calling undefined function asort. Awk sürümü, OSX 10.6.7’de çalışan 20070501’dir. .Yineleme sayısından sonra unutmayın .
lunohodov

lunohodov @: Eksik nokta eklendi. Ayrıca, gnu awk (gawk) kullandım ve bu eksik işlevi açıklayabilir.
Dan Andreatta

Çıkarma sayıları yanlış yoldur: örn. 9992 - 2999 = 6993
Olmalı

2

Ruby, 179 karakter ama yine de gönderme

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

yakut oldukça havalı
don

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 karakter ...
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];}

Test durumları

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

Bu program, 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]

Çalıştırmadan önce yolu ayarlama: -

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

Programı çalıştırmak: -

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

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

Çevrimiçi deneyin!

Komple program, giriş ile STDINçalışır php -nF.

Çıktı

> 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

Pas - 375 bayt

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

Bunu olası bir “üst sınır” olarak sunuyorum, herkese bunun makul bir uygulamasının daha uzun olduğu bir dil bulmaya zorluyorum - gereksiz bir şey olmadığı gibi, aynı zamanda onu önemli ölçüde küçültecek bariz bir şey bile olmadığı açık. Rust hakkında bir şey sadece stdin okumak ve bir tamsayı ayrıştırmak için yaklaşık 120 karakter sürer olmasıdır. "Ah ama o zaman sadece dize gösterimini kullan" ... ama% 99 daha uzun olacağına eminim


0

Perl 6 - n bayrak, 105 bayt

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

Çevrimiçi deneyin!

Sonunda {}...*numaramı kullandım , çünkü 6174 için en az bir yinelemeye ihtiyacımız var. Neden sırayla çürümeye başlayan fazladan sargıya ihtiyacım olduğundan emin değilim .&{ }.

Açıklama:

    .&{                         } # 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.