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.