Code Golf: 6174 - Constante mythique de Kaprekar


24

Pourquoi le numéro 6174 est-il si intéressant? Tel que défini par Wikipedia

  1. Prenez n'importe quel nombre à quatre chiffres, en utilisant au moins deux chiffres différents. (Les zéros non significatifs sont autorisés.)
  2. Organisez les chiffres en ordre croissant puis décroissant pour obtenir deux nombres à quatre chiffres, en ajoutant des zéros de tête si nécessaire.
  3. Soustrayez le plus petit nombre du plus grand nombre.
  4. Revenez à l'étape 2.

Le processus ci-dessus, connu sous le nom de routine de Kaprekar, atteindra toujours 6174 en au plus 7 itérations. Une fois que 6174 est atteint, le processus continuera de le produire.

Écrivez un programme qui exécute la routine du Kaprekar contre un nombre à quatre chiffres donné (voir la définition ci-dessus) imprimant chaque étape de la routine.

Règles:

  • Les soumissions doivent être des programmes complets.
  • L'entrée doit être lue à partir de l'entrée standard. La tuyauterie de l' écho est OK.
  • L'entrée doit être sous forme numérique.
  • L'impression des zéros non significatifs est requise. (Voir les exemples ci-dessous.)
  • La dernière ligne doit indiquer le nombre d'itérations nécessaires. La ponctuation est requise.

Exemples:

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

Tout langage de programmation est le bienvenu. Des points supplémentaires pour les ésotériques + une petite prime.

Mise à jour 1 : il y a déjà une question similaire .

Mise à jour 2 : ajout d'un exemple pour 6174 en entrée. Merci à Peter Taylor pour l'avis.


Ce sont des nouvelles pour moi. Quelqu'un appelle un modérateur ...

Euh ... il n'y a pas de bouton "migrer"?
Dr.Rebmu

J'ai signalé cela pour qu'un modérateur migre. Puis-je suggérer de modifier les règles de sortie d'entrée pour qu'elles correspondent à la version antérieure à 3 chiffres? Et un lien vers la version précédente dans le corps de la question.
dmckee

@dmckee Je ne connaissais pas ce site et je ne pouvais pas savoir qu'il y avait déjà une question similaire (sur stackoverflow il n'y en avait pas). Cependant, j'hésiterais à modifier les règles pour être d'accord avec la version à 3 chiffres et ainsi rendre les deux questions encore plus similaires. Il est inutile de poster un double ou une légère variation d'une question existante. Même lorsque cela n'est pas intentionnel.
lunohodov

3
Veuillez ajouter 6174 comme exemple afin que nous puissions voir comment la sortie doit être formatée.
Peter Taylor

Réponses:


9

Perl - 147 143 134 134 130 129 126 129 128 126 126

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

EDIT: est maintenant conforme au cas 6174, au prix de quelques caractères ... exécuté avec echo -n <number> | perl kaprekar.pl

EDIT: Enfin de retour à l'endroit où j'étais avant: D


10

Ruby 1.9, 122 caractères

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

Exemple d'appel:

$ echo 1211 | ruby -ln kaprekar.rb

J'ai compté le -lndrapeau comme 4 caractères (différence entre l'invocation normale ruby kaprekar.rbet ruby -ln kaprekar.rb).


J'ai enregistré ce script sous kaprekar.rb, puis je l'ai invoqué avec ruby -lp kaprekar.rb. Entré un nombre et appuyé sur <Entrée> mais la sortie est le numéro entré lui-même. De toute évidence, il me manque quelque chose ... Veuillez indiquer comment utiliser le script.
lunohodov

@lunohodov: J'ai ajouté un exemple d'invocation. Il génère désormais également la sortie correcte pour l' 6174entrée, ce qui porte malheureusement cette solution à 128 caractères.
Ventero

L'utilisation echo 1234 | ruby kaprekar.rbgénère un avertissement et se termine par une erreur undefined method 'chars' for nil:NilClass (NoMethodError). L'exécution des echo 1234 | ruby -lp kaprekar.rbproblèmes n'est qu'un avertissement et se comporte comme prévu. La sortie n'est pas celle attendue, car elle contient un message d'avertissementkaprekar.rb:3: warning: regex literal in condition
lunohodov

@lunohodov: correction de l'avertissement et de l'exemple d'appel.
Ventero

7

Python, 141 caractères

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 pour un rembourrage lisse avec% 04d. J'ai appris quelque chose aujourd'hui!
arrdem

3
Quelques suggestions: mettre toute la boucle sur une seule ligne en utilisant ;s. while n-6174. Pas d'espace entre printet le devis.
Keith Randall

@ keith-randall: merci, je suis descendu à 141 maintenant.
Martin Ueding

6

Golfscript, 74 caractères

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

5

Haskell, 197 192 182 181 caractères

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)

Inline ret senregistre 2 caractères. "000" est également redondant. "0" suffit. Cela nous amène à 188 caractères. Je suis surpris interactn'aide pas ici. C'est généralement le cas.
Rotsor

Remplacer show x++spar shows x sgagne 2 octets supplémentaires. 186 maintenant.
Rotsor

En utilisant les gardes de motif ( |k>0), on peut s'en débarrasser f. Un nouveau changement gde nom %nous amène à 182 caractères.
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;

Pas beaucoup de compétiteur pour le golf, mais c'était amusant d'écrire. :)

Exécuter avec./fish.py kaprekar.fish -v <number>
EDIT: prend maintenant l'entrée de STDIN.


4

JavaScript, 189 182 165 caractères

Crédit à 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+'.')

Original:

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

Non golfé:

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
Je pense que vous pouvez changer n != 6174à n-6174puisqu'il retournera zéro, ce qui est faux (au moins en C et Python).
Martin Ueding

Le mérite devrait revenir à Keith-Randall qui l'a suggéré pour ma solution Python.
Martin Ueding

Vous pouvez enregistrer 5 caractères supplémentaires en les remplaçant while(n.length<4)par while(!n[3]).
DocMax

1
Je ne peux pas arrêter de regarder celui-ci! Ce qui suit a) fixe la sortie lorsque n = 6174, b) réorganise quand n+'\n'est ajouté pour éviter le conditionnel et un extra \n, c) utilise un temp pour éviter une séquence de jointure-séparation-jointure, d) tire parti du fait que nous n'a jamais besoin d'ajouter un seul «0» pour le remplissage: 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+'.')qui devrait être 172 caractères.
DocMax

1
Impressionnant! Selon la spécification ci-dessus cependant, lorsque n = 6174, il doit passer par au moins une itération, j'ai donc ajouté une vérification si iest 0 (+4), mais j'ai combiné cela avec le i++. Malheureusement, cela donne une erreur de désactivation d'une unité, j'ai donc changé l'incrément en décrément, puis j'ai utilisé une petite ruse au niveau du bit à la fin (-1). Ensuite, je suis passé i=0,o=e=''à i=o=e=''(-2), j'ai reformaté la forboucle pour éviter les parenthèses supplémentaires (-1), le (b=...,a=...,b)bit développé (-2) et je me suis glissé a=b.joinà l'intérieur de l' reverse()appel (-1). Alors 169, c'est pas mal!
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."

Réussit tous les cas de test de la question.


2

JavaScript, 260 octets

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 caractères

(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 caractères

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

Utilise le trait App de Scala 2.9.

Edit: donne une sortie correcte pour l'entrée initiale de 6174.


2

PHP, 215 259 276 personnages

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

Non golfé:

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

Je ne pense pas que vous avez besoin abs, maxet les minfonctions, puisque le genre toujours signifie $best supérieure $a. Cela pourrait vous faire économiser 20 caractères. De plus, je pense que mettre le tri à l'intérieur de la boucle en haut signifie que vous n'aurez besoin de l'avoir dans votre code qu'une seule fois, ce qui vous fera économiser encore 9.
Gareth

Wow, je suppose que j'ai été distrait par l'instruction "soustrayez le plus petit nombre du plus grand nombre". Merci.
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";} Vous pouvez enregistrer 12 caractères en modifiant votre forinstruction, en l'appelant en tant que fonction et en utilisant joinau lieu de implode.
TwoScoopsofPig

De plus, je déteste les mini-démarques.
TwoScoopsofPig

2

CoffeeScript, 233 225 caractères

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

Essayez-le ici ou avec des instructions ici .


Mon navigateur se bloque - a dû annuler l'exécution du script.
lunohodov

Quel numéro avez-vous entré? Je l'ai essayé dans Firefox et Chrome pour 4711 et 1 et quelques autres.
Jonas Elfström

L'utilisation 0(comme suggéré par l'invite) ou le clic sur le bouton Annuler provoque le gel de Safari.
lunohodov

Je ne sais pas pourquoi cela a suggéré cela. Vous devez saisir un nombre compris entre 1 et 9998 dont les chiffres ne sont pas tous identiques. 0 est identique à 0000 et provoquera une boucle infinie. Il semble que la plupart des solutions ici ont ignoré la validation de l'entrée pour limiter le nombre de caractères.
Jonas Elfström

Voir i56.tinypic.com/bhhoqe.png Votre sortie se termine également par "Il a fallu 5 itérations pour atteindre la constante de Kaprekar." qui n'est pas conforme aux exigences.
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 caractères

Il s'agit d'une version GNU awk. Il peut ne pas fonctionner avec d'autres versions non 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

Je reçois awk: calling undefined function asort. La version Awk est 20070501 exécutée sur OSX 10.6.7. N'oubliez pas .après le nombre d'itérations.
lunohodov

lunohodov @: Ajout d'un point manquant. De plus, j'ai utilisé gnu awk (gawk), et cela peut expliquer la fonction manquante.
Dan Andreatta

Les nombres de soustraction sont dans le mauvais sens: par exemple devrait être9992 - 2999 = 6993
Chris Degnen

2

Ruby, 179 caractères mais affiche quand même

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 est assez cool
Don Bright

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

C'est ~ 310 caractères ...
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];}

Cas de test

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 caractères

Voici le programme, 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]

Définition du chemin d'accès avant l'exécution: -

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

Exécution du programme: -

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

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

Essayez-le en ligne!

Programme complet, l'entrée est STDINexécutée avec php -nF.

Sortie

> 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

Rouille - 375 octets

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

Je présente cela comme une possible «borne supérieure», je mets au défi quiconque de trouver un langage où une mise en œuvre raisonnable de celui-ci est plus longue - car il n'y a rien de superflu, mais aussi rien de même à distance évident qui le réduirait considérablement. La chose à propos de Rust est qu'il faut environ 120 caractères pour lire à partir de stdin et analyser en un entier. "Oh mais alors utilisez simplement la représentation des chaînes" ... mais je suis sûr à 99% que ce serait encore plus long


0

Indicateur Perl 6 -n, 105 octets

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

Essayez-le en ligne!

J'ai finalement pu utiliser mon {}...*astuce, car nous devons avoir au moins une itération pour 6174. Je ne sais pas pourquoi j'ai besoin de l'encapsulation supplémentaire .&{ }autour de la séquence, ce qui est un peu nul.

Explication:

    .&{                         } # 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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.