Additive Persistenz


20

Der kürzeste Code, der alle Möglichkeiten erfüllt, gewinnt.

In der Mathematik misst die Persistenz einer Zahl , wie oft eine bestimmte Operation auf ihre Ziffern angewendet werden muss, bis eine bestimmte feste Bedingung erreicht ist. Sie können die additive Persistenz einer positiven Ganzzahl bestimmen, indem Sie die Ziffern der Ganzzahl addieren und wiederholen. Sie würden die Ziffern der Summe so lange addieren, bis eine einzelne Ziffer gefunden wird. Die Anzahl der Wiederholungen, die erforderlich waren, um diese einstellige Zahl zu erreichen, ist die additive Persistenz dieser Zahl.

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

Sie erhalten eine Folge positiver Ganzzahlen, deren additive Persistenz Sie berechnen müssen. Jede Zeile enthält eine andere zu verarbeitende Ganzzahl. Die Eingabe kann in beliebigen Standard-E / A-Methoden erfolgen .

Für jede Ganzzahl müssen Sie die Ganzzahl gefolgt von einem einzelnen Leerzeichen und der additiven Persistenz ausgeben. Jede verarbeitete Ganzzahl muss in einer eigenen Zeile stehen.

Testfälle


Input-Output

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

1
Ihre Testfälle enthalten einige Werte, die über 2 ^ 64 liegen, und Ihre Spezifikation besagt, dass das Programm nur Werte bis zu 2 ^ 32 verarbeiten muss. Könnte es wert sein, das aufzuklären.
Peter Taylor

@ Peter Taylor, vergessen, diese Grenzen zu entfernen. Wenn ein Programm die von mir bereitgestellten Eingaben verarbeiten kann, sollte es keine Probleme mit Einschränkungen geben.
Kevin Brown

5
Ist die Persistenz von 999999999999 nicht 2 statt 3?
Eelvex

@Evelex, das war eine falsche Änderung in letzter Minute, denke ich. Fest.
Kevin Brown

Einige Antworten hier geben nicht auf stdout aus, sondern verwenden die "interaktive" Ausgabe von J, indem sie nach Eingabe über die Befehlszeile Ergebnisse zurückgeben. (Dies beinhaltet 2 andere J-Antworten und vermutlich die K-Antwort.) Wird dies als legitim angesehen? Weil ich 18-ish Charaktere abwerfen kann, wenn ja.
Jesse Millikan

Antworten:


6

K - 29 Zeichen

Die Eingabe ist ein Dateiname, der als Argument übergeben wird, 29 Zeichen ohne Dateiname.

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35 -> 31: Außenfunktion entfernen.
  • 31 -> 29: Entfernen Sie die Parens.

1
-1+#=>#1_
Streetster

4

Python 84 Zeichen

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

Herausforderungsfall: 06234.. Ergebnis erfolgreiche Herausforderung :-)
Quixotic

@ Debanjan Danke. Korrigiert
Freitag,

4

Haskell, 100 Zeichen

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

Sie können 6 Bytes speichern , indem Sie read.purestatt (-48+).fromEnum, versuchen Sie es online!
25.

4

Python (93 Bytes)

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)

Ich denke, Sie können das Leerzeichen zwischen entfernen 9und irren ...and
st0le

@ st0le: Danke :-)
Quixotic

und input()anstelle von int(raw_input())....
st0le

@ st0le: Versuchen Sie diese Eingabe mit der Änderung: 06234.
Quixotic

4

Schale , 10 15 Bytes

+5 Byte für schreckliche E / A-Anforderungen

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

Probieren Sie es online!

Erläuterung

Um mehrere Eingaben zu unterstützen, müssen wir verwenden m(₁r)¶(wo ist die Funktion, die die interessante Berechnung durchführt):

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

Die Funktion führt Folgendes aus:

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 Zeichen

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

Eigentlich kaum Golfspielen, aber ich weiß nicht, wie ich es verbessern kann.


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

Sie können unter Verwendung von 4 Bytes speichern pureüber (:[])und definieren einen Operator statt s, versuchen Sie es online!
25.

3

Rubin, 85 Zeichen

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

Ich musste mir die Idee "sum-size * 48" von Alex ausleihen, weil sie einfach zu ordentlich ist, um sie zu verpassen (zumindest in Ruby).


3

Golfscript, 40 Zeichen

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

3

J - 45 Zeichen

Liest von stdin

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

Ich habe versucht, ^:a:mich selbst zu benutzen , konnte aber keine ordnungsgemäße Dokumentation finden ... irgendwelche Hinweise?
Eelvex

1
Der Wörterbucheintrag für u ^: n enthält Informationen zu seiner Verwendung, ist jedoch etwas dicht. ^: a: ist wie jeder andere Aufruf an die Macht, sammelt jedoch die Ergebnisse und endet, wenn das Argument für aufeinanderfolgende Aufrufe dasselbe ist (konvergiert).
Isawdrones

1
@Eelvex FWIW Ich entdeckte a:durch den ^:a:Trick in der J Reference Card [PDF]
JB

@JB: Das ist der einzige Hinweis ^:a:, den ich kannte: D
Eelvex

@Eelvex Oh. Ich hatte damals die gegenteilige Erfahrung. Ich entdeckte die Funktionalität im Wörterbuch und benutzte sie zunächst als eine Variante ^:(<'')(wahrscheinlich für Kaprekar), bis ich sie auf der Karte entdeckte und etwas darüber erfuhr a:.
JB

3

c - 519

(oder 137, wenn Sie mir den Rahmen zuschreiben ...)

Anstatt nur diese eine Operation zu lösen, habe ich beschlossen, ein Framework für die Lösung aller Persistenzprobleme zu erstellen .

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

Nur die zwei Zeilen, die mit beginnen, char*bsind für dieses Problem eindeutig.

Der Eingang wird als Zeichenfolge behandelt, dh führende "0" werden nicht vor der Ausgangsstufe entfernt.

Kommentare, Fehlerüberprüfungen und Berichte sowie das Lesen von Dateien (Eingaben müssen von der Standardeingabe stammen) wurden entfernt aus:

/* 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;
  }
}

Ein bisschen mehr könnte gespart werden, wenn wir bereit wären, Speicher wie ein Sieb zu verlieren. Ebenso durch #defineRückkehr und dergleichen, aber an diesem Punkt ist es mir egal, es hässlicher zu machen.



2

J 74 Zeichen

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

Bearbeitungen

  • (86 → 83) Einige Caps [:zu Ats@
  • (83 → 79) Nicht benötigte Klammern
  • (79 → 75) Ändern, 0".um ".die Dinge zu vereinfachen
  • (75 → 74) Besser schneiden

Z.B

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  

Die Ausgabe ist für mehrere Eingaben falsch formatiert. Siehe "single space"
Jesse Millikan

@ Jesse: Ich sehe nichts falsches. Könnten Sie bitte ein Beispiel schreiben?
Eelvex

Ich habe keine Ahnung, ich sehe Dinge, die ich schätze.
Jesse Millikan

1

Ich denke, das ist ungefähr das Beste, was ich mir einfallen lassen kann.

Ruby 101 Zeichen

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

Eigentlich hacken! statt chomp! spart mir einen Charakter. 97 Zeichen.
Alex Bartlow

Hab gerade noch ein bisschen Golf gespielt - 91 Zeichen.
Alex Bartlow

1

PARI / GP 101 Zeichen

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

Leider gibt es keine Eingabefunktion für GP, daher fehlt hier wohl der IO-Teil. :( Behoben: Danke Eelvex! :)


Sicher gibt es: input():)
Eelvex

@Eelvex, fertig. :)
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 nicht die Multi-Lines


1
Nur bemerkt, dass dies nicht richtig ausgegeben wird.
Kevin Brown

1

J 78

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

Rekursive Lösung. Liest von stdin. Schreibt auf stdout , also hör auf damit - es sind zusätzliche 18-stellige Zeichen erforderlich.


1

Perl - 77 Zeichen

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

1

JavaScript , 57 47 Bytes

-10 Bytes dank @ l4m2!

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

Probieren Sie es online!


f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x*1+y*1),++c):c
14.

f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x- -y),++c):c
14.

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

@ l4m2 Danke! s>9und evalwaren tolle Ideen. Ich glaube, du hattest ein zusätzliches Paren, was insgesamt 10 Bytes ergibt, die du mir gerettet hast :-)
Oliver

Beachten Sie die strengen I / O;)
Shaggy

1

05AB1E , 13 Bytes

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

Eingabe als Liste von Ganzzahlen.

Probieren Sie es online aus.

Erläuterung:

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

hÅ_Σ]▀£(k ?

Probieren Sie es online!

Unglaublich ineffizient, aber das interessiert uns nicht. Grundsätzlich wird die Tatsache zugrunde gelegt, dass die additive Persistenz einer Zahl kleiner oder gleich der Zahl selbst ist.

Verwendet die Tatsache, dass die additive Persistenz kleiner oder gleich der Anzahl der Ziffern der Zahl ist. Besteht jetzt mühelos alle Testfälle.

Das Eingabeformat ist zwar für einige Sprachen nicht optimal, es ist jedoch die Standardmethode, um mehrere Testfälle als Eingabe in MathGolf zu verwenden. Jede Zeile der Eingabe wird als eigene Programmausführung verarbeitet, und die Ausgabe wird für jede Ausführung durch eine einzelne neue Zeile getrennt.

Erklärung (mit 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 Bytes

Lösung:

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

Probieren Sie es online!

Erläuterung:

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

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


0

Japt , 28 Bytes

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

Probieren Sie es online!


0

PHP, 72 + 1 Bytes

+1 für -RFlagge.

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

Als Rohr mit laufen lassen -R.

  • Wenn Sie PHP als Pipe ausführen, wird der Code für jede Eingabezeile einmal ausgeführt
  • aber es löscht nicht die Variablen dazwischen; so $imuss initialisiert werden.
    (Außerdem würde es 0ohne die Initialisierung nichts statt für einzelne Ziffern ausgeben.)

0

Bash + Coreutils, 83 Bytes

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

Probieren Sie es online!

Sollte in einem Skript gespeichert werden, das aufgerufen aund im System abgelegt wird PATH, da es sich selbst rekursiv aufruft. Nimmt Eingaben von der Kommandozeile wie a 1999. Rückgabe per Exit-Code.

TIO hat einige Einschränkungen, was Sie mit einem Skript machen können. Es gibt also einen Boilerplate-Code, mit dem dies im Header ausgeführt werden kann.

Gibt einen Fehler stderrfür Eingaben aus, die größer sind als die Bash-Ganzzahlen, die verarbeitet werden können. Da die eigentliche Berechnung jedoch mit Zeichenfolgen erfolgt, wird trotzdem das richtige Ergebnis erzielt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.