Trwałość addytywna

20

Wygrywa najkrótszy kod, który przejdzie wszystkie możliwości.

W matematyce trwałość liczby mierzy, ile razy dana operacja musi być zastosowana do jej cyfr, dopóki nie zostanie osiągnięty pewien ustalony warunek. Można ustalić addytywne utrzymywanie dodatniej liczby całkowitej, dodając cyfry liczby całkowitej i powtarzając. Dodawalibyśmy cyfry sumy, dopóki nie zostanie znaleziona liczba jednocyfrowa. Liczba powtórzeń potrzebnych do osiągnięcia tej liczby jednocyfrowej jest addytywnym utrzymywaniem się tej liczby.

Przykład z użyciem 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.

Otrzymasz ciąg dodatnich liczb całkowitych, które musisz obliczyć addytywną trwałość. Każda linia będzie zawierać inną liczbę całkowitą do przetworzenia. Dane wejściowe mogą być dowolnymi standardowymi metodami We / Wy .

Dla każdej liczby całkowitej należy wypisać liczbę całkowitą, po której następuje pojedyncza spacja, a następnie jej trwałość addytywna. Każda przetwarzana liczba całkowita musi znajdować się w osobnym wierszu.

Przypadki testowe


Wejście wyjście

99999999999 3
10 1
8 0
19999999999999999999999 4
6234 2
74621 2
39 2
2677889 3
0 0
Kevin Brown
źródło
1
Twoje przypadki testowe zawierają wartości przekraczające 2 ^ 64, a Twoja specyfikacja mówi, że program musi obsługiwać tylko wartości do 2 ^ 32. Może warto to wyjaśnić.
Peter Taylor,
@Peter Taylor, zapomniałem usunąć te ograniczenia. Jeśli program obsługuje podane przeze mnie dane wejściowe, nie powinien mieć problemu z ograniczeniami.
Kevin Brown
5
Czy uporczywość 999999999999 wynosi 2 zamiast 3?
Eelvex
@Evelex, to chyba nieprawidłowa zmiana w ostatniej chwili. Naprawiony.
Kevin Brown
Kilka odpowiedzi tutaj nie robi wyjścia na standardowym wyjściu, ale raczej używa „interaktywnego” wyjścia J, zwracając wyniki po wprowadzeniu danych z wiersza poleceń. (Obejmuje to 2 inne odpowiedzi J i, jak sądzę, odpowiedź K.) Czy to jest uważane za uzasadnione? Bo jeśli tak, mogę zrzucić 18-znakowe postacie.
Jesse Millikan

Odpowiedzi:

6

K - 29 znaków

Dane wejściowe to nazwa pliku przekazywana jako argument, 29 znaków bez nazwy pliku.

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35 -> 31: Usuń funkcję zewnętrzną.
  • 31 -> 29: Usuń pareny.
izawdrony
źródło
1
-1+#=>#1_
streetster,
4

Python 84 znaki

while 1:
 m=n=int(raw_input());c=0
 while n>9:c+=1;n=sum(map(int,str(n)))
 print m,c
fR0DDY
źródło
Przypadek wyzwania: 06234.. wynik wyzwanie wyzwanie :-)
Quixotic
@Debanjan Thanks. Poprawione
fR0DDY
4

Haskell, 100 znaków

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
źródło
Możesz zapisać 6 bajtów, read.purezamiast tego (-48+).fromEnum, spróbuj online!
ბიმო
4

Python (93 bajty)

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)
Donkiszotowski
źródło
myślę, że możesz usunąć spację między 9i err ...and
st0le
@ st0le: Dzięki :-)
Quixotic
i input()zamiast int(raw_input())....
st0le
@ st0le: Spróbuj to wejście z tą modyfikacją: 06234.
Kichot,
4

Łuska , 10 15 bajtów

+5 bajtów za okropne wymagania We / Wy

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

Wypróbuj online!

Wyjaśnienie

Aby obsłużyć wiele danych wejściowych, musimy użyć m(₁r)¶(gdzie funkcja wykonuje interesujące obliczenia):

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

Funkcja wykonuje następujące czynności:

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"
ბიმო
źródło
3

bash, 105 znaków

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

Prawie nie gra w golfa, ale nie widzę, jak to poprawić.

Peter Taylor
źródło
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
źródło
Możesz zaoszczędzić 4 bajty, używając pureponad (:[])i definiując operatora zamiast s, spróbuj online!
ბიმო
3

Ruby, 85 znaków

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

Musiałem pożyczyć od Alexa pomysł „suma wielkości * 48”, ponieważ jest zbyt fajny, by go przegapić (przynajmniej w Ruby).

Ezran
źródło
3

Golfscript, 40 znaków

n%{.:${;${48-}%{+}*`:$,}%.,1>\1?+' '\n}%
TY
źródło
3

J - 45 znaków

Czyta ze standardowego

(,' ',[:":@<:@#+/&.:("."0)^:a:)&><;._2(1!:1)3
izawdrony
źródło
Próbowałem się wykorzystać, ^:a:ale nie mogłem znaleźć odpowiedniej dokumentacji ... żadnych wskazówek?
Eelvex
1
Słowniku wejście dla u ^ n ma informacji na temat jego pracy, ale jest nieco gęsta. ^: a: jest jak każde inne wezwanie do władzy, ale zbiera wyniki i kończy się, gdy argument kolejnych wywołań jest taki sam (zbieżny).
isawdrones
1
@Eelvex FWIW odkryłem a:przez ^:a:podstęp w J karta referencyjna [PDF]
JB
@JB: To jedyne odniesienie ^:a:, jakie znałem: D
Eelvex
@Eelvex Oh. Miałem wtedy odwrotne doświadczenie. Odkryłem funkcjonalność w słowniku i użyłem jej ^:(<'')początkowo jako pewnej odmiany (prawdopodobnie dla Kaprekara), dopóki nie zauważyłem jej na karcie i nie dowiedziałem się o a:tej okazji.
JB
3

c - 519

(lub 137, jeśli uznają mnie za ramy ...)

Zamiast rozwiązać tylko tę jedną operację, postanowiłem stworzyć ramy dla rozwiązania wszystkich problemów związanych z trwałością .

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

Tylko dwie linie zaczynające się od char*bsą unikalne dla tego problemu.

Traktuje dane wejściowe jako ciągi, co oznacza, że ​​wiodące „0” nie są usuwane przed etapem wyjściowym.

Powyższe zawierało komentarze, sprawdzanie błędów i raportowanie oraz odczyt plików (dane wejściowe muszą pochodzić ze standardowego wejścia) z następujących elementów:

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

Trochę więcej można by zaoszczędzić, gdybyśmy chcieli wyciec pamięć jak sito. Podobnie poprzez #definepowrót i tym podobne, ale w tym momencie nie dbam o to, aby było brzydsze.

dmckee
źródło
273 bajtów
ceilingcat
2

J, 74 znaki

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

Edycje

  • (86 → 83) Niektóre czapki [:na ataki@
  • (83 → 79) Niepotrzebne nawiasy
  • (79 → 75) Zmiana 0".do ".upraszcza rzeczy
  • (75 → 74) Lepsze cięcie

Na przykład

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
źródło
Wyjście jest źle sformatowane dla wielu wejść. Zobacz „single space”
Jesse Millikan
@Jesse: Nie widzę nic złego. Czy mógłbyś napisać przykład?
Eelvex
Nie mam pojęcia, myślę, że widzę rzeczy.
Jesse Millikan
1

Myślę, że jest to najlepsze, co mogę wymyślić.

Ruby 101 znaków

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
źródło
Właściwie, posiekaj! zamiast chomp! daje mi oszczędności jednej postaci. 97 znaków.
Alex Bartlow
Po prostu trochę więcej grałem w golfa - 91 znaków.
Alex Bartlow
1

PARI / GP 101 znaków

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

Niestety, nie ma funkcji wprowadzania danych dla GP, więc myślę, że brakuje w niej części IO. :( Naprawiono: Dzięki Eelvex! :)

st0le
źródło
Na pewno jest: input():)
Eelvex
@Eelvex, gotowe. :)
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);

EDYCJA: Whoops nie robi wielu linii

t123
źródło
1
Zauważyłem, że nie wyświetla to poprawnie.
Kevin Brown
1

J, 78

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

Rozwiązanie rekurencyjne. Czyta ze standardowego. Zapisuje na standardowe wyjście , więc zmniejsz mi trochę luzu - zajmuje to dodatkowe 18 znaków.

Jesse Millikan
źródło
1

Perl - 77 znaków

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

JavaScript , 57 47 bajtów

-10 bajtów dzięki @ l4m2!

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

Wypróbuj online!

Oliver
źródło
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 Dzięki! s>9i evalbyły świetne pomysły. Myślę, że miałeś tam dodatkowy paren, dzięki czemu zaoszczędziłeś w sumie 10 bajtów :-)
Oliver
Zwróć uwagę na surowe operacje wejścia / wyjścia;)
Kudłaty
1

05AB1E , 13 bajtów

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

Wprowadź jako listę liczb całkowitych.

Wypróbuj online.

Wyjaśnienie:

ε     # 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
źródło
1

MathGolf , 11 bajtów

hÅ_Σ]▀£(k ?

Wypróbuj online!

Niesamowicie nieefektywny, ale nie dbamy o to. Zasadniczo, wykorzystując fakt, że addytywna trwałość liczby jest mniejsza lub równa samej liczbie.

Wykorzystuje fakt, że trwałość addytywna jest mniejsza lub równa liczbie cyfr liczby. Teraz z łatwością przechodzi wszystkie przypadki testowe.

Format wejściowy, choć nieoptymalny dla niektórych języków, jest w rzeczywistości standardową metodą przyjmowania wielu przypadków testowych jako danych wejściowych w MathGolf. Każdy wiersz danych wejściowych jest przetwarzany jako wykonanie własnego programu, a dane wyjściowe są oddzielone pojedynczym nowym wierszem dla każdego wykonania.

Objaśnienie (za pomocą 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
źródło
1

K (ngn / k) , 16 bajtów

Rozwiązanie:

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

Wypróbuj online!

Wyjaśnienie:

{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
źródło
1

Stax , 8 11 bajtów

ªwæMε∞ö?îm⌐

Uruchom i debuguj

+3 bajty dzięki @Khuldraeseth (pierwsza odpowiedź nie miała zgodnego wyniku)

rekurencyjny
źródło
1
Osiągnąłem to samo rozwiązanie, ale izamiast u. Zgodnie z drakońskimi specyfikacjami We / Wy staje się 11 bajtów .
Khuldraeseth na'Barya
Ups Chyba nie przeczytałem zbyt dobrze wymagań IO. Zaktualizuję moją odpowiedź.
rekurencyjny
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)))
nieznany użytkownik
źródło
0

Java (OpenJDK 8) , 79 bajtów

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

Wypróbuj online!

Istnieje duży potencjał, aby pograć w golfa dalej, ale przyjrzę się temu w przyszłości, ale na razie jestem bardzo zadowolony z tego małego wyniku.

X1M4L
źródło
1
70 bajtów .
Jonathan Frech,
Opierając się na @JonathanFrech 67 bajtów
ceilingcat
0

Python 3 , 82 bajty

while 1:f=lambda n:n//10and 1+f(sum(map(int,str(n))));i=input();print(i,f(int(i)))
PieCot
źródło
0

Tcl , 95 bajtów

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

Wypróbuj online!

sergiol
źródło
3
Ponieważ następna najnowsza odpowiedź to pełne 6 lat, które, jak sądzę, istniały zanim TIO istniało
fəˈnɛtɪk
0

Japt , 28 bajtów

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

Wypróbuj online!

Gnida
źródło
0

PHP, 72 + 1 bajtów

+1 za -Rflagę.

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

Uruchom jako potok z -R.

  • uruchomienie PHP jako potoku spowoduje wykonanie kodu raz dla każdej linii wejściowej
  • ale nie rozbija zmiennych między nimi; więc $imusi zostać zainicjowany.
    (Ponadto nie wydrukowałby niczego zamiast 0pojedynczych cyfr bez inicjalizacji).
Tytus
źródło
0

Bash + coreutils, 83 bajty

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

Wypróbuj online!

Powinny być zapisane w skrypcie wywoływanym ai umieszczanym w systemie PATH, ponieważ wywołuje się rekurencyjnie. Pobiera dane wejściowe z wiersza poleceń, np a 1999. Zwraca kod zakończenia.

TIO ma pewne ograniczenia co do tego, co można zrobić ze skryptem, dlatego w nagłówku znajduje się kod, który może go uruchomić.

Wyświetla błąd stderrdla wejścia większego niż liczby całkowite, które może obsłużyć bash, ale ponieważ faktyczne obliczenia są wykonywane za pomocą łańcuchów, i tak daje właściwy wynik.

Chris
źródło