Persistance additive

20

Le code le plus court pour passer toutes les possibilités l'emporte.

En mathématiques, la persistance d'un nombre mesure combien de fois une certaine opération doit être appliquée à ses chiffres jusqu'à ce qu'une certaine condition fixe soit atteinte. Vous pouvez déterminer la persistance additive d'un entier positif en ajoutant les chiffres de l'entier et en répétant. Vous continueriez d'ajouter les chiffres de la somme jusqu'à ce qu'un numéro à un seul chiffre soit trouvé. Le nombre de répétitions qu'il a fallu pour atteindre ce nombre à un chiffre est la persistance additive de ce nombre.

Exemple utilisant 84523:

84523
8 + 4 + 5 + 2 + 3 = 22
2 + 2 = 4

It took two repetitions to find the single digit number.
So the additive persistence of 84523 is 2.

Vous recevrez une séquence d'entiers positifs dont vous devez calculer la persistance additive. Chaque ligne contiendra un entier différent à traiter. L'entrée peut se faire dans n'importe quelle méthode d'E / S standard .

Pour chaque entier, vous devez sortir l'entier, suivi d'un espace unique, suivi de sa persistance additive. Chaque entier traité doit être sur sa propre ligne.

Cas de test


Entrée sortie

99999999999 3
10 1
8 0
19999999999999999999999 4
6234 2
74621 2
39 2
2677889 3
0 0
Kevin Brown
la source
1
Vos cas de test incluent des valeurs supérieures à 2 ^ 64, et votre spécification indique que le programme ne doit gérer que des valeurs allant jusqu'à 2 ^ 32. Cela pourrait valoir la peine de clarifier cela.
Peter Taylor
@Peter Taylor, a oublié de supprimer ces limites. Si un programme peut gérer l'entrée que j'ai fournie, il ne devrait pas avoir de problème avec les limites.
Kevin Brown
5
La persistance de 999999999999 n'est-elle pas 2 au lieu de 3?
Eelvex
@Evelex, c'était un changement de dernière minute incorrect, je suppose. Fixé.
Kevin Brown
Plusieurs réponses ici ne font pas de sortie sur stdout mais utilisent plutôt la sortie "interactive" de J en renvoyant les résultats après avoir pris la ligne de commande. (Cela comprend 2 autres réponses J et, je suppose, la réponse K.) Est-ce considéré comme légitime? Parce que je peux perdre des caractères de 18 ish si c'est le cas.
Jesse Millikan

Réponses:

6

K - 29 caractères

L'entrée est un nom de fichier passé en argument, 29 caractères n'incluant pas le nom de fichier.

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35 -> 31: Supprimer la fonction extérieure.
  • 31 -> 29: supprimer les parens.
isawdrones
la source
1
-1+#=>#1_
streetster
4

Python 84 caractères

while 1:
 m=n=int(raw_input());c=0
 while n>9:c+=1;n=sum(map(int,str(n)))
 print m,c
fR0DDY
la source
Cas de défi: 06234.. résultat défi réussi :-)
Quixotic
@Debanjan Merci. Corrigée.
fR0DDY
4

Haskell, 100 caractères

p[d]=0
p d=1+(p.show.sum$map((-48+).fromEnum)d)
f n=n++' ':shows(p n)"\n"
main=interact$(f=<<).lines
MtnViewMark
la source
Vous pouvez économiser 6 octets en utilisant read.pureau lieu de (-48+).fromEnum, essayez-le en ligne!
2018
4

Python (93 octets)

f=lambda n,c:n>9and f(sum(map(int,str(n))),c+1)or c
while 1:n=int(raw_input());print n,f(n,0)
Chimérique
la source
je pense que vous pouvez supprimer l'espace entre 9et and
euh
@ st0le: Merci :-)
Quixotic
et input()au lieu de int(raw_input())....
st0le
@ st0le: Essayez cette entrée avec cette modification: 06234.
2011 Quixotic
4

Husk , 10 15 octets

+5 octets pour une horrible exigence d'E / S

m(wΓ·,LU¡oΣdr)¶

Essayez-le en ligne!

Explication

Pour prendre en charge plusieurs entrées, nous devons utiliser m(₁r)¶(où est la fonction effectuant le calcul intéressant):

m(₁r)¶  -- expects newline-separated inputs: "x₁␤x₂␤…␤xₙ"
     ¶  -- split on newlines: ["x₁","x₂",…,"xₙ"]
m(  )   -- map over each string
 ( r)   -- | read integer: [x₁,x₂,…,xₙ]
 (₁ )   -- | apply the function described below

La fonction effectue les opérations suivantes:

wΓ·,LU¡(Σd)  -- input is an integer, eg: 1234
      ¡(  )  -- iterate the following forever and collect results in list:
       ( d)  -- | digits: [1,2,3,4]
       (Σ )  -- | sum: 10
             -- : [1234,10,1,1,1,…
     U       -- keep longest prefix until repetition: [1234,10,1]
 Γ           -- pattern match (x = first element (1234), xs = tail ([10,1])) with:
  · L        -- | length of xs: 2
   ,         -- | construct tuple: (1234,2)
w            -- join with space: "1234 2"
ბიმო
la source
3

bash, 105 caractères

while read x
do
for((i=0,z=x;x>9;i++))do
for((y=0;x>0;y+=x%10,x/=10))do :
done
x=$y
done
echo $z $i
done

Presque aucun golf n'est réellement impliqué, mais je ne vois pas comment l'améliorer.

Peter Taylor
la source
3

Haskell - 114

s t n|n>9=s(t+1)$sum$map(read.(:[]))$show n|1>0=show t
f n=show n++" "++s 0n++"\n"
main=interact$(f.read=<<).lines
Joey Adams
la source
Vous pouvez économiser 4 octets en utilisant pureover (:[])et en définissant un opérateur au lieu de s, essayez-le en ligne!
2018
3

Rubis, 85 caractères

puts $<.map{|n|v=n.chop!;c=0;[c+=1,n="#{n.sum-n.size*48}"] while n[1];[v,c]*' '}*"\n"

J'ai dû emprunter l'idée de "somme-taille * 48" à Alex, parce que c'est juste trop beau pour être raté (en Ruby au moins).

Ezran
la source
3

Golfscript, 40 caractères

n%{.:${;${48-}%{+}*`:$,}%.,1>\1?+' '\n}%
VOUS
la source
3

J - 45 caractères

Lit à partir de stdin

(,' ',[:":@<:@#+/&.:("."0)^:a:)&><;._2(1!:1)3
isawdrones
la source
J'essayais de ^:a:m'utiliser mais je n'ai pas trouvé de documentation appropriée ... des indices?
Eelvex
1
L' entrée du dictionnaire pour u ^: n contient des informations sur son utilisation, mais elle est un peu dense. ^: a: est comme tout autre appel au pouvoir mais il recueille les résultats et se termine lorsque l'argument des appels consécutifs est le même (converge).
isawdrones
1
@Eelvex FWIW J'ai découvert a:grâce à l' ^:a:astuce dans la carte de référence J [PDF]
JB
@JB: C'est la seule référence ^:a:que je connaissais: D
Eelvex
@Eelvex Oh. J'ai alors vécu l'expérience inverse. J'ai découvert la fonctionnalité dans le dictionnaire, et je l'ai utilisée comme variante ^:(<'')au début (probablement pour Kaprekar), jusqu'à ce que je la repère dans la carte et que j'en apprenne a:l'occasion.
JB
3

c - 519

(ou 137 si vous me remerciez pour le cadre ...)

Plutôt que de résoudre cette seule opération, j'ai décidé de produire un cadre pour résoudre tous les problèmes de persistance .

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char*(*O)(char*);
char*b(char*s){long long int v=0,i,l=0;char*t=0;l=strlen(s);t=malloc(l+2);
for(i=0;i<l;i++)v+=s[i]-'0';snprintf(t,l+2,"%lld",v);return t;}
int a(char**s,O o){int r;char*n;n=o(*s);r=!strcmp(*s,n);free(*s);
*s=n;return r;}
int main(int c, char**v){size_t l, m=0;char *d,*n=0;O o=b;FILE*f=stdin;
while(((l=getline(&n,&m,f))>1)&&!feof(f)){int i=0;n=strsep(&n,"\n");
d=strdup(n);while(!a(&n,o))i++;printf("%s %d\n",d,i);free(d);free(n);n=0;m=0;}}

Seules les deux lignes à partir de char*bsont uniques à ce problème.

Il traite l'entrée comme des chaînes, ce qui signifie que les "0" en tête ne sont pas supprimés avant l'étage de sortie.

Les commentaires ci-dessus, la vérification des erreurs et la génération de rapports, et la lecture de fichiers (l'entrée doit provenir de l'entrée standard) ont été supprimés:

/* persistence.c
 *
 * A general framework for finding the "persistence" of input strings
 * on opperations.
 *
 * Persistence is defined as the number of times we must apply
 *
 *    value_n+1 <-- Opperation(value_n)
 *
 * before we first reach a fixed point.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../getline.h"

/* A function pointer type for operations */
typedef char*(op_func)(char*);
typedef op_func* op_ptr;
/* Op functions must
 * + Accept the signature above
 * + return a point to a newly allocated buffer containing the updated str
 */

char* addop(char*s){
  int i,l=0;
  long long int v=0;
  char *t=NULL;
  /* protect against bad input */
  if (NULL==s) return s;
  /* allocate the new buffer */
  l = strlen(s);
  t = malloc(l+2);
  if (NULL==t) return t;
  /* walk the characters of the original adding as we go */
  for (i=0; i<l; i++) v += s[i]-'0';
  //fprintf(stderr,"   '%s' (%d) yields %lld\n",s,l,v);
  snprintf(t,l+2,"%lld",v);
  //fprintf(stderr,"   %lld is converted to '%s'\n",v,t);
  return t;
}

/* Apply op(str), return true if the argument is a fixed point fo
 * falsse otherwise,
 */ 
int apply(char**str, op_ptr op){ 
  int r;
  char*nstr;
  /* protect against bad input */
  if ( NULL==op ) exit(1); 
  if ( NULL==*str ) exit(4); 
  /* apply */
  nstr = op(*str); 
  /* test for bad output */
  if ( NULL==nstr ) exit(2); 
  r = !strcmp(*str,nstr); 
  /* free previous buffer, and reasign the new one */
  free(*str); 
  *str = nstr; 
  return r; 
}

int main(int argc, char**argv){
  size_t len, llen=0;
  char *c,*line=NULL;
  op_ptr op=addop;
  FILE *f=stdin;
  if (argc > 1) f = fopen(argv[1],"r");
  while( ((len=getline(&line,&llen,f))>1) && line!=NULL && !feof(f) ){
    int i=0;
    line=strsep(&line,"\n"); // Strip the ending newline
    /* keep a copy for later */
    c = strdup(line);
    /* count necessary applications */
    while(!apply(&line,op)) i++;
    printf("%s %d\n",c,i);
    /* memory management */
    free(c);
    free(line);
    line=NULL;
    llen=0;
  }
}

Un peu plus pourrait être économisé si nous voulions fuir la mémoire comme un tamis. De même, #defineen retour et autres, mais à ce stade, je ne tiens pas à le rendre plus laid.

dmckee
la source
273 octets
plafond
2

J, 74 caractères

i=:<;._2(1!:1)3
i&((],' ',":@(0 i.~9<[:".([:":[:+/"."0)^:(i.9)))@>@{~)i.#i

Modifications

  • (86 → 83) Quelques majuscules [:en ats@
  • (83 → 79) Parenthèses inutiles
  • (79 → 75) Changer 0".pour ".simplifier les choses
  • (75 → 74) Meilleure coupe

Par exemple

i=:<;._2(1!:1)3
74621
39
2677889
0
i&((],' ',":@(0 i.~9<[:".([:":[:+/"."0)^:(i.9)))@>@{~)i.#i
74621 2  
39 2     
2677889 3
0 0  
Eelvex
la source
La sortie est mal formatée pour plusieurs entrées. Voir "single space"
Jesse Millikan
@Jesse: Je ne vois rien de mal. Pourriez-vous écrire un exemple s'il vous plaît?
Eelvex
Je n'en ai aucune idée, je vois des choses je suppose.
Jesse Millikan
1

Je pense que c'est à peu près le meilleur que je puisse trouver.

Ruby 101 Chars

f=->(n){n.sum-n.size*48}
$<.each{|l|i=0;i+=1 while(i+=1;n=f[(n||l.chop!).to_s])>10
puts "#{l} #{i}"}
Alex Bartlow
la source
En fait, hachez! au lieu de chomp! me donne une économie d'un caractère. 97 caractères.
Alex Bartlow
Je viens de jouer encore au golf - 91 caractères.
Alex Bartlow
1

Caractères PARI / GP 101

s(n)=r=0;while(n>0,r+=n%10;n\=10);r
f(n)=c=0;while(n>9,c++;n=s(n));c
while(n=input(),print(n," ",f(n)))

Malheureusement, il n'y a pas de fonction d'entrée pour GP, donc je suppose que cela manque la partie IO. :( Correction: Merci Eelvex! :)

st0le
la source
Bien sûr, il y a: input():)
Eelvex
@Eelvex, c'est fait. :)
st0le
1

Javascript - 95

i=prompt();while(i>9){i=''+i;t=0;for(j=0;j<i.length;j++)t+=parseInt(i.charAt(j));i=t;}alert(t);

EDIT: Whoops ne fait pas les multi-lignes

t123
la source
1
Je viens de remarquer que cela ne le produit pas correctement.
Kevin Brown
1

J, 78

f=:[:+/"."0&":
r=:>:@$:@f`0:@.(=f)
(4(1!:2)~LF,~[:":@([,r)".@,&'x');._2(1!:1)3

Solution récursive. Lit à partir de stdin. Écrit sur stdout , alors coupez-moi un peu - cela prend 18 caractères supplémentaires.

Jesse Millikan
la source
1

Perl - 77 caractères

sub'_{split//,shift;@_<2?0:1+_(eval join'+',@_)}chop,print$_,$",(_$_),$/for<>
jho
la source
1

JavaScript , 57 47 octets

-10 octets grâce à @ l4m2!

f=(s,c=0)=>s>9?f(eval([...s+""].join`+`),++c):c

Essayez-le en ligne!

Oliver
la source
f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x*1+y*1),++c):c
l4m2
f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x- -y),++c):c
l4m2
1
f=(s,c=0)=>s>9?f(eval([...s+""].join`+`)),++c):c
l4m2
@ l4m2 Merci! s>9et evalétaient de grandes idées. Je pense que vous aviez un paren supplémentaire, ce qui en fait un total de 10 octets que vous m'avez sauvé :-)
Oliver
Notez les E / S strictes;)
Shaggy
1

05AB1E , 13 octets

ε.µΔSO¼}¾}<ø»

Entrée sous forme de liste d'entiers.

Essayez-le en ligne.

Explication:

ε     # Map each integer in the (implicit) input to:
    #  Reset the counter variable to 0
 Δ    #  Loop until the integer no longer changes:
  S   #   Convert it to a list of digits
   O  #   And take the sum of those
  ¼   #   Increase the counter variable by 1
    #  After the inner loop: Push the counter variable
}<    # After the map: decrease each value by 1
  ø   # Zip/transpose it with the (implicit) input to create a paired list
   »  # Join each pair by a space, and then each string by newlines
      # (after which the result is output implicitly)
Kevin Cruijssen
la source
1

MathGolf , 11 octets

hÅ_Σ]▀£(k ?

Essayez-le en ligne!

Incroyablement inefficace, mais cela nous importe peu. Fondamentalement, en utilisant le fait que la persistance additive d'un nombre est inférieure ou égale au nombre lui-même.

Utilise le fait que la persistance additive est inférieure ou égale au nombre de chiffres du nombre. Réussit tous les cas de test avec facilité maintenant.

Le format d'entrée, bien que sous-optimal pour certaines langues, est en fait la méthode standard pour prendre plusieurs cas de test en entrée dans MathGolf. Chaque ligne de l'entrée est traitée comme sa propre exécution de programme et la sortie est séparée par une seule nouvelle ligne pour chaque exécution.

Explication (utilisation n = 6234)

h             push length of number without popping (6234, 4)
 Å            loop 4 times using next 2 operators
  _           duplicate TOS
   Σ          get the digit sum
    ]         wrap stack in array
              this gives the array [6234, 15, 6, 6, 6]
     ▀        unique elements of string/list ([6234, 15, 6])
      £       length of array/string with pop (3)
       (      decrement (2)
        k ?   push input, space, and rotate top 3 elements to produce output (6234 2)
maxb
la source
1

K (ngn / k) , 16 octets

Solution:

{x,#1_(+/10\)\x} 

Essayez-le en ligne!

Explication:

{x,#1_(+/10\)\x} / the solution
{              } / lambda taking implicit x
      (     )\x  / iterate until convergence
         10\     / split into base-10 (123 => 1 2 3)
       +/        / sum
    1_           / drop first result (iterate returns input as first result)
   #             / count length of result
 x,              / prepend x (original input)
streetster
la source
1

Stax , 8 11 octets

ªwæMε∞ö?îm⌐

Exécuter et déboguer

+3 octets grâce à @Khuldraeseth (la première réponse n'avait pas de sortie conforme)

récursif
la source
1
J'ai atteint la même solution, mais avec ià la place de u. Adhérant aux spécifications draconiennes d'E / S, cela devient 11 octets .
Khuldraeseth na'Barya
Oups. Je suppose que je n'ai pas très bien lu les exigences d'E / S. Je mettrai à jour ma réponse.
récursif
0

scala 173:

def s(n:BigInt):BigInt=if(n<=9)n else n%10+s(n/10)
def d(n:BigInt):Int=if(n<10)0 else 1+d(s(n))
Iterator.continually(readInt).takeWhile(_>0).foreach(i=>println(i+" "+d(i)))
Utilisateur inconnu
la source
0

Java (OpenJDK 8) , 79 octets

a->{int d=0;while(a/10>0){int c=0;d++;while(a>0){c+=a%10;a/=10;}a=c;}return d;}

Essayez-le en ligne!

Il y a un potentiel probable pour jouer au golf plus loin, mais j'examinerai cela à l'avenir, mais pour l'instant, je suis assez content de ce petit résultat.

X1M4L
la source
1
70 octets .
Jonathan Frech
S'appuyant sur @JonathanFrech 67 octets
plafondcat
0

Python 3 , 82 octets

while 1:f=lambda n:n//10and 1+f(sum(map(int,str(n))));i=input();print(i,f(int(i)))
PieCot
la source
0

Tcl , 95 octets

proc P {v n\ 0} {set V $v
while \$v>9 {set v [expr [join [split $v ""] +]]
incr n}
puts $V\ $n}

Essayez-le en ligne!

sergiol
la source
3
Parce que la prochaine réponse la plus récente est un
enfant de
0

Japt , 28 octets

Ë+S+(@D=X©A<D©ì x ªD D<AÃa÷
Ë                            // Map over the inputs and return each, followed by
 +S+                         // a space, followed by the number's persistence.
      D=     ©ì x            // To find it, fold the number up
        X©A<D     ªD         // if we can (handles unfoldable cases),
    (@               D<AÃa   // until it can't be folded up any further.
                          ÷ // Then, join everything up with newlines.

Essayez-le en ligne!

Lente
la source
0

PHP, 72 + 1 octets

+1 pour le -Rdrapeau.

for($i=0,$a=$argn;$a>9;$i++)$a=array_sum(str_split($a));echo"$argn $i
";

Exécuter en tant que tuyau avec -R.

  • exécuter PHP en tant que pipe exécutera le code une fois pour chaque ligne d'entrée
  • mais il ne désactive pas les variables entre elles; $idoit donc être initialisé.
    (De plus, il n'imprimerait rien au lieu de 0chiffres uniques sans l'initialisation.)
Titus
la source
0

Bash + coreutils, 83 octets

[ $1 -le 9 ]&&exit $2
let x=$2+1
for z in `fold -w1<<<$1`
do let y+=$z
done
a $y $x

Essayez-le en ligne!

Doit être enregistré dans un script appelé aet placé dans le système PATH, car il s'appelle récursivement. Prend l'entrée de la ligne de commande, commea 1999 . Renvoie par code de sortie.

TIO a certaines limites sur ce que vous pouvez faire avec un script, il y a donc du code passe-partout pour faire fonctionner cela dans l'en-tête.

Imprime une erreur pour stderrune entrée supérieure à ce que les entiers bash peuvent gérer, mais puisque le calcul réel est effectué avec des chaînes, il donne quand même le bon résultat.

Chris
la source