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

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.

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

Przypadek wyzwania: 06234.. wynik wyzwanie wyzwanie :-)
Quixotic

@Debanjan Thanks. Poprawione
fR0DDY


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)

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"

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


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

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


3

Golfscript, 40 znaków

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

3

J - 45 znaków

Czyta ze standardowego

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

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.



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  

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

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


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


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.


1

Perl - 77 znaków

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

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!


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)

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)

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)


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 bajty

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

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!


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!


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

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.