Persistenza additiva


20

Vince il codice più corto per superare tutte le possibilità.

In matematica, la persistenza di un numero misura quante volte una determinata operazione deve essere applicata alle sue cifre fino a quando non viene raggiunta una certa condizione fissa. È possibile determinare la persistenza additiva di un numero intero positivo aggiungendo le cifre dell'intero e ripetendo. Continueresti ad aggiungere le cifre della somma fino a quando non viene trovato un numero a una cifra. Il numero di ripetizioni necessarie per raggiungere quel numero a singola cifra è la persistenza aggiuntiva di quel numero.

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

Ti verrà data una sequenza di numeri interi positivi di cui devi calcolare la persistenza additiva. Ogni riga conterrà un intero diverso da elaborare. L'ingresso può essere in qualsiasi metodo I / O standard .

Per ogni numero intero, è necessario generare l'intero, seguito da un singolo spazio, seguito dalla sua persistenza additiva. Ogni numero intero elaborato deve essere sulla propria riga.

Casi test


Input Output

99999999999 3
10 1
8 0
19999999999999999999999 4
6234 2
74621 2
39 2
2677889 3
0 0

1
I casi di test includono alcuni valori superiori a 2 ^ 64 e le specifiche indicano che il programma deve gestire solo valori fino a 2 ^ 32. Potrebbe valere la pena chiarirlo.
Peter Taylor,

@Peter Taylor, ho dimenticato di rimuovere quei limiti. Se un programma è in grado di gestire l'input fornito, non dovrebbe avere problemi con i limiti.
Kevin Brown,

5
La persistenza di 999999999999 non è 2 invece di 3?
Eelvex,

@Evelex, credo sia stata una modifica dell'ultimo minuto errata. Fisso.
Kevin Brown,

Diverse risposte qui non stanno producendo output su stdout ma piuttosto usano l'output "interattivo" di J restituendo risultati dopo aver eseguito l'input dalla riga di comando. (Ciò include altre 2 risposte J e, immagino, la risposta K.) È considerato legittimo? Perché in questo caso posso liberare personaggi di 18 anni.
Jesse Millikan il

Risposte:


6

K - 29 caratteri

L'input è un nome file passato come argomento, 29 caratteri non incluso il nome file.

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35 -> 31: rimuove la funzione esterna.
  • 31 -> 29: rimuove le parentesi.

1
-1+#=>#1_
streetster

4

Python 84 Chars

while 1:
 m=n=int(raw_input());c=0
 while n>9:c+=1;n=sum(map(int,str(n)))
 print m,c

Caso di sfida: 06234.. risultato sfida riuscita :-)
Quixotic,

@Debanjan Grazie. Corretto.
fR0DDY,

4

Haskell, 100 personaggi

p[d]=0
p d=1+(p.show.sum$map((-48+).fromEnum)d)
f n=n++' ':shows(p n)"\n"
main=interact$(f=<<).lines

Puoi salvare 6 byte usando read.pureinvece di (-48+).fromEnum, provalo online!
ბიმო

4

Python (93 byte)

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)

penso che puoi rimuovere lo spazio tra 9ed err ...and
st0le

@ st0le: Grazie :-)
Quixotic,

e input()invece di int(raw_input())...
st0le

@ st0le: Prova questo ingresso con quella modifica: 06234.
Chisciotte

4

Buccia , 10 15 byte

+5 byte per requisiti I / O orribili

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

Provalo online!

Spiegazione

Per supportare più input, dobbiamo usare m(₁r)¶(dove sta eseguendo la computazione interessante la funzione):

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 funzione procede come segue:

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 caratteri

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

Quasi nessun golf effettivamente coinvolto, ma non riesco a vedere come migliorarlo.


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

Puoi salvare 4 byte usando pureover (:[])e definendo un operatore invece di s, provalo online!
ბიმო

3

Rubino, 85 caratteri

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

Ho dovuto prendere in prestito l'idea di "sum-size * 48" da Alex, perché è troppo bello per mancare (almeno in Ruby).


3

Golfscript, 40 caratteri

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

3

J - 45 caratteri

Legge da stdin

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

Stavo cercando di usare ^:a:me stesso ma non sono riuscito a trovare una documentazione adeguata ... qualche suggerimento?
Eelvex,

1
La voce del dizionario per u ^: n ha informazioni sul suo utilizzo ma è un po 'densa. ^: a: è come qualsiasi altra chiamata al potere ma raccoglie i risultati e termina quando l'argomento per le chiamate consecutive è lo stesso (converge).
isawdrones,

1
@Eelvex FWIW l'ho scoperto a:attraverso il ^:a:trucco nella J Reference Card [PDF]
JB

@JB: Questo è l'unico riferimento su ^:a:quello che sapevo: D
Eelvex

@Eelvex Oh. Ho avuto l'esperienza opposta allora. Ho scoperto la funzionalità nel dizionario e ^:(<'')inizialmente l'ho usata come una variante (probabilmente per Kaprekar), fino a quando non l'ho individuata nella scheda e ho imparato a:per l'occasione.
JB

3

c - 519

(o 137 se mi accrediti per il framework ...)

Invece di risolvere solo questa operazione, ho deciso di produrre un framework per risolvere tutti i problemi di persistenza .

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

Solo le due righe a partire da char*bsono uniche per questo problema.

Tratta l'input come stringhe, il che significa che gli "0" iniziali non vengono rimossi prima dello stadio di output.

Quanto sopra ha avuto commenti, controllo degli errori e report e lettura dei file (l'input deve provenire dall'input standard) rimosso da:

/* 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 po 'di più potrebbe essere salvato se fossimo disposti a perdere memoria come un setaccio. Allo stesso modo #defineing e return, ma a questo punto non mi interessa renderlo più brutto.



2

J, 74 caratteri

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

Le modifiche

  • (86 → 83) Alcuni limiti [:per Ats@
  • (83 → 79) Parentesi non necessarie
  • (79 → 75) Cambiare 0".per ".semplificare le cose
  • (75 → 74) Taglio migliore

Per esempio

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  

L'output è formattato in modo errato per più input. Vedi "spazio singolo"
Jesse Millikan il

@Jesse: non vedo nulla di male. Potresti scrivere un esempio per favore?
Eelvex,

Non ne ho idea, vedo cose che immagino.
Jesse Millikan il

1

Penso che questo sia il meglio che posso inventare.

Charts di Ruby 101

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

In realtà, tagliare! invece di chomp! mi fa risparmiare un personaggio. 97 caratteri.
Alex Bartlow,

Ho appena giocato a golf - 91 caratteri.
Alex Bartlow,

1

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

Sfortunatamente, non esiste una funzione di input per GP, quindi immagino che questo non abbia la parte IO. :( Risolto: Grazie Eelvex! :)


Certo che c'è: input():)
Eelvex,

@Eelvex, fatto. :)
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 non esegue le linee multiple


1
Ho appena notato che questo non viene prodotto correttamente.
Kevin Brown,

1

J, 78

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

Soluzione ricorsiva. Legge da stdin. Scrive su stdout , quindi tagliami un po 'di calma - ci vogliono altri 18 caratteri extra.


1

Perl - 77 caratteri

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

1

JavaScript , 57 47 byte

-10 byte grazie a @ l4m2!

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

Provalo online!


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 Grazie! s>9ed evalerano grandi idee. Penso che tu abbia un paren in più, rendendolo un totale di 10 byte che mi hai salvato :-)
Oliver

Nota l'I / O rigoroso;)
Shaggy

1

05AB1E , 13 byte

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

Inserire come un elenco di numeri interi.

Provalo online.

Spiegazione:

ε     # 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 byte

hÅ_Σ]▀£(k ?

Provalo online!

Incredibilmente inefficiente, ma non ci interessa. Fondamentalmente, usando il fatto che la persistenza additiva di un numero è minore o uguale al numero stesso.

Utilizza il fatto che la persistenza additiva è inferiore o uguale al numero di cifre del numero. Passa tutti i casi di test con facilità ora.

Il formato di input, sebbene non ottimale per alcune lingue, è in realtà il metodo standard per prendere più casi di test come input in MathGolf. Ogni riga dell'input viene elaborata come esecuzione del proprio programma e l'output è separato da una singola riga per ogni esecuzione.

Spiegazione (utilizzo 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 byte

Soluzione:

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

Provalo online!

Spiegazione:

{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 byte

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

0

Tcl , 95 byte

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

Provalo online!


3
Perché la prossima risposta più recente è un pieno di 6 anni, che penso sia prima
dell'esistenza di

0

Japt , 28 byte

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

Provalo online!


0

PHP, 72 + 1 byte

+1 per la -Rbandiera.

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

Esegui come pipe con -R.

  • l'esecuzione di PHP come pipe eseguirà il codice una volta per ogni riga di input
  • ma non disinserisce le variabili tra di loro; quindi $ideve essere inizializzato.
    (Inoltre, non stamperebbe nulla invece che 0per singole cifre senza l'inizializzazione.)

0

Bash + coreutils, 83 byte

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

Provalo online!

Dovrebbe essere salvato in uno script chiamato ae inserito nel sistema PATH, come si chiama ricorsivamente. Accetta input dalla riga di comando, ad esempioa 1999 . Restituisce per codice di uscita.

TIO ha alcune limitazioni su cosa puoi fare con uno script, quindi c'è del codice boilerplate per farlo funzionare nell'intestazione.

Stampa un errore stderrper input di dimensioni superiori a quelli che possono essere gestiti da interi bash, ma poiché il calcolo effettivo viene eseguito con le stringhe, fornisce comunque comunque il risultato giusto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.