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

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.

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

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

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)

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"

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.


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

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


3

Golfscript, 40 caractères

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

3

J - 45 caractères

Lit à partir de stdin

(,' ',[:":@<:@#+/&.:("."0)^:a:)&><;._2(1!:1)3

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.



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  

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

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! :)


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


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.


1

Perl - 77 caractères

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

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!


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)

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)

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)


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



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


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!


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

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.

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.