Jak matematyka działa w świecie Anastazji?

44

Tło:

Standardowa matematyka operacji, taka jak podstawowe dodawanie i mnożenie w świecie rzeczywistym, działa w następujący sposób:

12 + 123 = 135

i

12 * 123 = 1476

To nie jest interesujące i nudne! Wiele szkół interpretuje to już jako praktykę, praktykę, praktykę algorytmów formalnych. Oznacza to dość sztywną i nudną dietę matematyczną i nie jest to cel tego wyzwania. Przygotuj się na zabawę na naszej ukochanej stronie.

Rozważ proces dodawania dwóch dodatnich liczb całkowitych, a następnie ponownego dodawania wszystkich cyfr jego wyniku. Powtarzanie z dodawaniem, dopóki nie zostanie uzyskana tylko jedna cyfra. Na przykład:

  1. Wynik 12 + 123to 135.
  2. Dodając wszystkie cyfry 135 otrzymujemy 1 + 3 + 5 = 9.

Liczba kroków wymaganych do uzyskania wartości jednocyfrowej 9 w tym powtarzanym dodaniu wynosi 2.

Podobnie jak w poprzednim procesie dodawania, mnożenie dwóch dodatnich liczb całkowitych odbywa się w ten sam sposób. Pomnóż wszystkie cyfry wyniku, a następnie powtarzaj ten proces, aż pozostanie tylko jedna cyfra. Weź powyższy przykład:

  1. Wynik 12 * 123to 1476.
  2. Pomnóż wszystkie uzyskane liczby 1476 1 * 4 * 7 * 6 = 168.
  3. Pomnóż ponownie wszystkie otrzymane cyfry 168 1 * 6 * 8 = 48.
  4. Pomnóż ponownie wszystkie otrzymane cyfry 48 4 * 8 = 32.
  5. Pomnóżmy jeszcze raz wszystkie uzyskane cyfry 32 3 * 2 = 6.

Liczba kroków wymaganych do uzyskania wartości jednocyfrowej 6 to powtarzane mnożenie wynosi 5.

Ze względu na to wyzwanie i unikanie niewłaściwego używania notacji matematycznych przedstawiam te dwa fikcyjne notacje: (+)i (*), ale możesz użyć dowolnej notacji, którą lubisz , która działa jak poniżej:

  1. Proces powtarzanego dodawania w celu uzyskania pojedynczej wartości to 12 (+) 123 = 9.
  2. Operacja powtarzania procesu mnożenia w celu uzyskania pojedynczej wartości to 12 (*) 123 = 6.

Wyzwanie:

Wyzwanie polega na napisaniu programu lub funkcji, która może wykonywać obie operacje, jak wyjaśniono w części dotyczącej tła: (+)i (*).

Wejście:

Wejściami programu lub funkcji są dwie dodatnie liczby całkowite i jedna operacja (+)oraz (*). Format danych wejściowych jest arbitralnym wyborem programisty . Możesz formatować wejściowe, na przykład, a (+) blub F(a, (+), b)lub dowolnego formatu chcesz.

Wynik:

Dane wyjściowe programu lub funkcji muszą zawierać wynik operacji i liczbę kroków wymaganych w formacie freestyle zgodnie z życzeniem.

Przypadki testowe (zignoruj ​​format wejściowy i wyjściowy):

    81 (+) 31       -->   (4 ; 2)
    351 (+) 14568   -->   (6 ; 3)
    21 (*) 111      -->   (8 ; 3)
    136 (*) 2356    -->   (0 ; 2)

Główne zasady:

  • To jest , więc najkrótsza odpowiedź w bajtach wygrywa.
    Nie pozwól, by esolangi zniechęcały Cię do publikowania odpowiedzi w zwykłych językach. Podejmij wyzwanie, udzielając możliwie najkrótszej odpowiedzi w języku programowania. Jeśli zamieścisz sprytną odpowiedź i jasne wyjaśnienie, Twoja odpowiedź zostanie doceniona (stąd głosy poparcia) niezależnie od używanego języka programowania.
  • Odpowiedzi dotyczą standardowe zasady , więc możesz używać STDIN / STDOUT, funkcji / metody z odpowiednimi parametrami, pełnych programów itp. Wybór należy do Ciebie.
  • Jeśli to możliwe, twój program może poprawnie obsługiwać duże liczby. Jeśli nie, będzie dobrze.

Niech zacznie się gra!!

Anastasiya-Romanova 秀
źródło
Część powtarzanego dodawania ( cyfrowy katalog główny ) jest w zasadzie duplikatem codegolf.stackexchange.com/q/1128/194
Peter Taylor
4
Świetne pierwsze pytanie! I rozpoznaję ogólny format reguł i zdania z moich własnych pytań. ;)
Kevin Cruijssen
4
@KevinCruijssen Yup. Zgadza się. Ponieważ nie ma praw autorskich, powielam go bez Twojej zgody. Hehehe: D
Anastasiya-Romanova 秀
4
@ Anastasiya-Romanova 秀 „bez praw autorskich”? W XXI wieku? Nie; wszystko tutaj jest CC-BY-SA 3.0. Zezwolenie jest udzielane po przesłaniu treści. Sprawdź stopkę witryny.
Mindwin
1
@ BradGilbertb2gills Tak, oczywiście. Nawiasem mówiąc, jest napisane w poście. Cytat: „Format danych wejściowych jest arbitralnym wyborem programisty”.
Anastasiya-Romanova 秀

Odpowiedzi:

11

Dyalog APL , 33 32 30 29 bajtów

Rozszerza to APL o zapis prefiksu +/A n₁ n₂i ×/A n₁ n₂. (W rzeczywistości możesz użyć dowolnej operacji po lewej stronie /A.) Zwraca listę {wynik, liczba powtórzeń}.

A←{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺⍎¨⍕⊃⍵}⍣≡⍺⍺⍵}

A←{zdefiniuj funkcję wyższego rzędu pod względem funkcji po lewej stronie ⍺⍺i argumentu po prawej stronie

(⊃,≢) pierwszy element, po którym następuje liczba

⍺⍺{dostarczona funkcja ( +/dla sumy lub ×/dla produktu) dostarczona do funkcji wyższego rzędu

unikalne elementy

⍵,⍨ argument dołączony do

⍺⍺ zastosowana funkcja fed

⍎¨ ocena każdej postaci

reprezentacja postaci

⊃⍵ pierwszy element argumentu

}⍣≡ stosowane wielokrotnie, aż wynik będzie identyczny z argumentem, zaczynając od

⍺⍺⍵pierwotnie wprowadzona funkcja ( +/lub ×/) zastosowana do oryginalnego argumentu

} [koniec definicji funkcji wyższego rzędu]

Wypróbuj APL online! ( został emulowany ze ewzględów bezpieczeństwa.)

Dzięki @ngn za zapisanie bajtu.


0 bajtów (w jest)

Dyalog APL faktycznie ma już pełne wsparcie matematyki Anastasiyan; zamiast (+)i (×)używa +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}i ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}.

Spróbuj 81 +{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺e¨⍕⊃⍵}⍣≡⍺⍺/⍺⍵} 31i 21 ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/e¨⍕⍵}⍣=⍵⍺⍺⍨⍺} 111.

Adám
źródło
Dzięki za odpowiedź, (+1). Czy poradzi sobie z wprowadzaniem dużej liczby?
Anastasiya-Romanova 秀
1
Jeśli ustawisz ⎕FR←1287(tj użyć IEEE 754-2008 128-bitowy dziesiętny F loating-punktową R ePresentation) oraz ⎕PP←34(tj naciśnij 34 bohaterów P rukuj P recision), można użyć liczb całkowitych poniżej 10³⁴.
Adám
Hmm, mimo że ma pełne wsparcie, to nie jest +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}i ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}wciąż sporo bajtów? Jestem zdezorientowany, jak to jest 0 bajtów ..: S
Kevin Cruijssen
3
@KevinCruijssen PO umożliwia dowolną notację wejściową. Tak więc, jeśli język obsługiwałby domyślną notację matematyczną Anastasiyan po wyjęciu z pudełka, wieloznakowym glifem (+)byłby Anastasiyan +. Dyalog APL obsługuje matematykę Anastasiyan, ale wykorzystuje inny wieloznakowy glif, tak samo jak *moc i potrzeba ×namnażania, podczas gdy /replikacja i potrzeba ÷dzielenia.
Adám
1
@ Adám Ah ok, to ma sens. To trochę naginanie zasad OP, ale ich nie łamanie. Nadal jest dość dziwne, że zamiast (+)ciebie masz +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}jako dane wejściowe, ale ponieważ OP rzeczywiście stwierdził, że zrobi to dowolny format wejściowy, możesz użyć tej funkcji jako parametru. Hmm, zastanawiam się, czy jest to również możliwe w innych językach programowania, które obsługują funkcje jako dane wejściowe.
Kevin Cruijssen
8

Haskell, 108 bajtów

f=map(read.pure).show
g h=(\x->(h.f$last x,length x+1)).takeWhile(>10).iterate(h.f)
(a#b)o=g(foldr1 o)$o a b

Określa funkcję #, która pierwsza przyjmuje ai bi operatora o. Ciekawostka: działa z dowolnym operatorem (właściwie dowolną funkcją)!

ThreeFx
źródło
Dzięki za odpowiedź, (+1). Czy poradzi sobie z wprowadzaniem dużej liczby?
Anastasiya-Romanova 秀
4
@ Anastasiya-Romanova 秀 Tak, może obsługiwać liczby tak duże, jak pamięć RAM, ponieważ Integertyp Haskella jest nieograniczony.
ThreeFx
8

Pyke, 16 bajtów

RE`DltImbRoKr)oh

Wypróbuj tutaj!

RE               - evaluate the input as Pyke code
                 -  (`B` is product and `s` is sum, the second line is a tuple)
  `              - i = str(^)
    ltI      )   - if len(i) != 1:
       mb        -   map(i, int)
         R       -   get the `B` or `s` from input
          oK     -   o++
            r    -   goto_start()
              oh - o++ + 1

Pobiera mnożenie jako Bi dodawanie jako s. Dwa wejścia numeryczne są oddzielone przecinkami.

niebieski
źródło
1
Miły! Czy możemy uzyskać wyjaśnienie?
Emigna
Dzięki za odpowiedź, (+1). Czy poradzi sobie z wprowadzaniem dużych liczb?
Anastasiya-Romanova 秀
@ Anastasiya-Romanova 秀powinna być w stanie obsłużyć dowolne numery
Blue
Nie mogę przetestować Twojego kodu, ponieważ sieć jest zablokowana, ponieważ narusza zasady korzystania z Internetu przez moich rodziców. T_T
Anastasiya-Romanova 秀
Coś w tym stylu: Strona internetowa zablokowana! Próbowałeś uzyskać dostęp do strony internetowej, która narusza twoje zasady korzystania z Internetu. URL: pyke.catbus.co.uk/?code=RE%60DltImbRoKr%29oh&input=B%0A21%2C+111&warnings=0 Kategoria: Bez oceny
Anastasiya-Romanova 秀
8

JavaScript (ES6), 59

Funkcja rekurencyjna, format wejściowy jest dostosowany w celu uproszczenia wywołania rekurencyjnego:

  • operator: „+” lub „*”
  • operandy: tablica dwóch wartości
f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]

Test

f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]

;[
  [81,'+',31,     /* -> */ 4, 2]
, [351,'+',14568, /* -> */ 6, 3]
, [21,'*',111,    /* -> */ 8, 3]
, [136,'*',2356,  /* -> */ 0, 2]
].forEach(t=>{
  var [a,o,b,k1,k2] = t,
      [r,s]=f(o,[a,b]);
  console.log(k1==r && k2==s ? 'OK':'KO',a,o,b,'->',r,s)
})  
  

edc65
źródło
Dzięki za odpowiedź, (+1). Czy poradzi sobie z wprowadzaniem dużych liczb?
Anastasiya-Romanova 秀
1
@ Anastasiya-Romanova 秀 do limitu formatu liczbowego javascript, 53 bity dokładności (17 cyfr dziesiętnych)
edc65
8

Python 2, 60 bajtów

f=lambda s,c=0:s[1:]and f(min(s).join(`eval(s)`),c+1)or(s,c)

Dane wejściowe są ciągami typu 81+31, dane wyjściowe to krotka ciągu singletonów i licznik (np ('4', 2).

Przetestuj na Ideone .

Dennis
źródło
Jeśli przyjmowanie danych wejściowych w postaci tablicy ciągów i pojedynczego ciągu jest dozwolone, np. f(['81', '31'],'+')Można zapisać kolejny bajt, ale wydaje się, że rozciąganie reguł jest nieco za daleko ...
Dennis
... w takim razie posunęłbym się nawet tak daleko i zastanowiłem się nad zaliczeniem operator.addlub operator.mulodpowiednio;)
Tobias Kienzler,
7

Pyth, 16 lat

eJ.uvjhQ`N.vQ)lJ

Pobiera dane wejściowe jak "+ 123 12"do dodawania i "* 123 12"mnożenia. Wyjścia jak result<linefeed>steps.

Wypróbuj tutaj lub uruchom pakiet testowy , ale pamiętaj, że zależy to od eval, więc tylko wariant dodatkowy będzie działał w tłumaczu online. Mnożenie działa poprawnie z tłumaczem offline.

Korzysta z funkcji skumulowanej redukcji, aby utworzyć listę wyników pośrednich, więc "+ 351 14568"otrzymujemy [14919, 24, 6]. Działa to, ponieważ liczby jednocyfrowe są stałym punktem dodawania i mnożenia Anastasiya. Następnie otrzymujemy ostatni element tablicy oraz jej długość.

Będzie to działać dla dowolnie dużych liczb, przynajmniej do momentu wyczerpania pamięci.

FryAmTheEggman
źródło
7

R, 175 167 164 140 134 127 126 119 119 bajtów

function(G,S,D){i=1;O=switch(S,"+"=sum,prod);x=O(G,D);while(x>9){i=i+1;x=O(strtoi(strsplit(paste(x),"")[[1]]))};c(x,i)}

Nie golfowany:

f=function(G,S,D) #The function takes : the left operand, the operation symbol (between quote marks)
                  #and then the right operand
i=1               #That's the counter

O=switch(S,"+"=sum,prod)     #`O` takes the value `sum` if `S` matches `+`, `prod` 
                             #(which is the next agument) if not. 

x=O(G,D)                     #Does the first operation

while(nchar(x)>1)                 #While the number of character of the result 
                                  #of the operation is not of length 1, i.e., an integer :

    i=i+1                                    #Increase the counter
    x=O(strtoi(strsplit(paste(x),"")[[1]]))  #Apply the operation `O` to the first operation and 
                                             #the eventual subsequent ones

c(x,i)                                 #Outputs the result and the counter

ifelsewrócił ! Tak !
Nie

Stosowanie :

Special addition
> f(31,"+",81)
[1] 4 2

Special multiplication
> f(136,"*",2356)
[1] 0 2

Bardzo dziękuję @plannapus za grę w golfa na 24 bajty!
-7 bajtów dzięki dobrym pomysłem @Vlo !

Frédéric
źródło
Tak, proszę dodaj wyjaśnienia, ponieważ kocham R! To jest mój drugi język po VBA. (+1)
Anastasiya-Romanova 秀
1
@ Anastasiya-Romanova 秀: Gotowe!
Frédéric
@plannapus: Naprawdę fajnie! Wielkie dzięki !
Frédéric
1
@ Frédéric ładne wykorzystanie strtoi! Jeszcze 4 bajty, że mnie pobiłeś.
plannapus
1
Wygląda na to, że możesz dalej grać w golfa poza bajtem, włączając definicję O w przypisaniu x w pierwszej operacji: x = (O = przełącznik (S, suma, `*`)) (G, D) ;.
rturnbull
6

05AB1E , 20 15 bajtów

[¼¹iOëP}Dg#S]¾‚

Wyjaśnienie

[       Dg# ]    # loop until number is single digit
 ¼               # increase counter
  ¹iO            # if operation is addition, sum list
     ëP}         # else take product of list
           S     # split into a list of digits
             ¾‚  # pair final number with counter and output

Operator to 1 za dodanie, 0 za pomnożenie.

Wypróbuj online

Emigna
źródło
Dzięki za odpowiedź, (+1). Czy poradzi sobie z wprowadzaniem dużych liczb?
Anastasiya-Romanova 秀
@ Anastasiya-Romanova 秀 Nie widzę powodu, dla którego nie. Czy masz przykład?
Emigna
Twój program został przetestowany pod kątem tego rodzaju danych wejściowych, więc jest idealny :)
Anastasiya-Romanova 秀
6

Galaretka , 11 10 bajtów

Dj⁹VµÐĿḊĖṪ

Dane wejściowe to para cyfr i albo +albo ×.

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

Dj⁹VµÐĿḊĖṪ  Main link. Left argument: [x, y] (integers). Right argument: + or ×

    µÐĿ     Repeatedly execute the chain to the left, initially with argument
            [x, y], then with the previous return value. Stop when the results are
            no longer unique, and return the array of all intermediate results.
D           Decimal; convert the integers [x, y] or the return value z to base 10.
 j⁹         Join, separating by the link's right argument, i.e., '+' or '×'.
   V        Evaluate the result. This casts the previous return value to string,
            so, e.g., [8, 1, '+', 3, 1] becomes "81+31" before evaluation.
       Ḋ    Dequeue; discard the first intermediate result, i.e., [x, y].
        Ė   Enumerate; prefix each integer in the array with its 1-based index.
         Ṫ  Tail; extract the last index-value pair.
Dennis
źródło
6

Kod maszynowy ARM, 48 bajtów

Zrzut szesnastkowy:

b570 2a00 bf0c 1840 4348 2101 230a e00c 3101 0015 fbb0 f6f3 fb06 0413 2a00 bf0c 192d 4365 0030 d1f5 0028 280a d2f0 bd70

Ta funkcja nie zależy od wywołań systemowych ani funkcji bibliotecznych. Jest to kod Thumb-2, który jest kodowaniem instrukcji o zmiennej długości (2 lub 4 bajty) dla 32-bitowego ARM. Zatem maksymalna wartość, którą może przetworzyć, to 2 ^ 32-1. 2 bajty mogłyby zostać upuszczone, gdyby nie były zgodne z AAPCS ( 46 bajtów ), ponieważ nie musielibyśmy układać rejestrów na początku.

Zestaw bez golfa (składnia GNU):

.syntax unified
.text
.global anastasiya
.thumb_func
anastasiya:
    @Input:
    @r0 - First number
    @r1 - Second number
    @r2 - 0 for add, 1 for multiply
    @Output:
    @r0 - Resultant value
    @r1 - Number of steps
    push {r4,r5,r6,lr}
    cmp r2,#0
    ite eq @if r2==0
    addeq r0,r0,r1 @r0+=r1
    mulne r0,r0,r1 @else r0*=r1
    movs r1,#1 @r1 is the number of steps
    movs r3,#10
    b endloop
    loop:
        adds r1,r1,#1 @Increment number of steps
        movs r5,r2 @r5=1 if multiply, 0 if add
        parseDigits:
            udiv r6,r0,r3 @r6=r0/r3
            mls r4,r6,r3,r0 @r4=r0 - r6*r3
            @Last two operations were r4=r0%r3 (r3==10)
            cmp r2,#0
            ite eq @if r2==0
            addeq r5,r5,r4 @r5+=r4
            mulne r5,r5,r4 @else r5*=r4
            movs r0,r6 @r0=r6 (Set r0 to r0/10)
            bne parseDigits @while (r0!=0)
        @Now our new total is in r5
        movs r0,r5 @Put it in r0
    endloop:
        cmp r0,#10
        bhs loop @while (r0 >=10)
    pop {r4,r5,r6,pc} @Return

Skrypt testowy w C:

#include <stdio.h>
unsigned long long anastasiya(unsigned,unsigned,unsigned);

int main(void) {
    unsigned x,y,op;
    printf("Enter first operand, second operand, and 0 for addition or 1 for multiplication.\n");
    scanf("%u%u%u",&x,&y,&op);
    unsigned long long res = anastasiya(x,y,op);
    printf("Result = %u, steps = %u\n",(unsigned)res ,(unsigned)(res >> 32));
}
Ian Chew
źródło
4

R, 130 124 znaki

Nieco inne podejście niż @ Frédérica :

f=function(a,f,b){b=c(a,b);n=1;while((m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)))>1){b=d%%10^(1:m)%/%10^(1:m-1);n=n+1};c(d,n)}

Wcięte, z nowymi liniami:

f=function(a,f,b){
    b=c(a,b) # Take both numbers
    n=1 #Counter
    while((m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)))>1){
#My own special digit splitter! (d is the result and m is the nb of char of d)
        b=d%%10^(1:m)%/%10^(1:m-1)
        n=n+1
    }
    c(d,n) #Print results
    }

Linia 4 prawdopodobnie potrzebuje więcej wyjaśnień:

switch(f,'(+)'=sum,prod) #pick which operator to use
switch(f,'(+)'=sum,prod)(b) # apply it to b
d<-switch(f,'(+)'=sum,prod)(b) #Saves the result in d
nchar(d<-switch(f,'(+)'=sum,prod)(b))#Measures the number of character of d
m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)) #Saves it in m
(m<-nchar(d<-switch(f,'(+)'=sum,prod)(b)))>1 #Checks if it is more than 1

Przypadki testowe:

> f(12,"(+)",123)
[1] 9 2
> f(12,"(*)",123)
[1] 6 5
> f(351,"(+)",14568)
[1] 6 3
plannapus
źródło
Całkiem niefortunne, że spóźniłeś się z tą odpowiedzią, ale masz moje poparcie. Dzięki za utworzenie tego w R.
Anastasiya-Romanova 秀
Dlaczego niefortunny?
plannapus
Ponieważ gdybyś był pierwszy, miałbyś więcej głosów pozytywnych
Anastasiya-Romanova 秀
@ Anastasiya-Romanova enough Wystarczająco :)
plannapus
Punkty bonusowe za fbycie zarówno nazwą funkcji, jak i jednym z jej argumentów :)
JDL
4

Oktawa, 85 bajtów MATLAB, 123, 114, 105, 94 bajtów

Postanowiłem przetłumaczyć to na Octace, skorzystać z bezpośredniego indeksowania i zwiększyć możliwości. Pobiera dane wejściowe z formularza:, f(a,operator)gdzie a = [number1, number2]i operator==1podaje produkt i operator==2podaje sumę.

function[x,i]=f(a,o)
g={@prod,@sum}{o};x=g(a);i=1;while(x=g(num2str(x)-48))>9;i++;end

Objaśnienia:

g={@prod,@sum}{o} : Wybiera odpowiednią funkcję, produkt lub sumę i przypisuje ją do g

x=g(a) przyjmuje sumę lub iloczyn nakładów

i=1; ... i++ : Inkrementator zliczający liczbę kroków

while(x=g(num2str(x)-48))>9;
          num2str(x)-48)     % turns a number 123 into an array [1 2 3].
        g(num2str(x)-48))    % Takes the sum or product of the array
      x=g(num2str(x)-48))    % Assign that value to the variable x
      x=g(num2str(x)-48))>9  % Checks if x > 9, continue looping if yes

Usunięto dwie nowe linie, spację i umieściłem obie liczby wejściowe w wektorze zamiast osobnych argumentów. Zaoszczędzono 9 bajtów dzięki pajonk! Usunięto, k=@(x)...aby zapisać kolejne 11 bajtów dzięki zlewce =) Wreszcie przetłumaczono całą rzecz na Octave, aby zapisać kolejne 9 bajtów ...

Stewie Griffin
źródło
4

Java, 164 159 146 bajtów

int[]p(int t,int m,String[]d){int r=m;for(String i:d){int x=Integer.decode(i);r=m<1?r+x:r*x;}return r>9?p(++t,m,(r+"").split("")):new int[]{r,t};}

Pierwszy argument to tylko licznik, zawsze 0

Drugi argument to metoda, 0 dla ADD i 1 dla MULTIPLY.

Trzeci argument to tablica ciągów znaków, która zawiera wartości do dodania / pomnożenia.

Nie golfił

public static int[] p(int t, int m, String[] d) {
    int r = m;
    for (String i : d) {
        int x = Integer.decode(i);
        r = m < 1 ? r + x : r * x;
    }
    return (r + "").length() > 1 ? p(++t, m, (r + "").split("")) : new int[]{r, t};
}

dzięki @Kevin Cruijssen za skrócenie kilku bajtów.

dzięki @milk za golenie 5 bajtów.

Program testowy

public static final int ADD = 0;
public static final int MULTIPLY = 1;

public static void main(String[] args) {
    System.out.println(Arrays.toString(p(0, ADD, new String[]{"12", "123"}))); //9
    System.out.println(Arrays.toString(p(0, MULTIPLY, new String[]{"12", "123"}))); //6
}

public static int[] p(int t, int m, String[] d) {
    int r = m;
    for (String i : d) {
        int x = Integer.decode(i);
        r = m < 1 ? r + x : r * x;
    }
    return (r + "").length() > 1 ? p(++t, m, (r + "").split("")) : new int[]{r, t};
}
Shaun Wild
źródło
Ładne, krótsze niż moja odpowiedź Java . Jednak należy również wydrukować kroki, a także odpowiedź, której obecnie brakuje w Twojej odpowiedzi.
Kevin Cruijssen
@KevinCruijssen Ahh. To nudne ... Spróbuję to teraz naprawić.
Shaun Wild,
Btw, możesz trochę pograć w golfa z obecną odpowiedzią. m==0może być m<1i Integer.parseIntmoże być Integer.decode.
Kevin Cruijssen
Nie używam dużo Java, ale czy jna końcu potrzebujesz tego var? Inlining (r+"")dwukrotny wygląda, jakby ogolił kilka bajtów.
mleko
1
Czy nie możemy w przyszłości zmieniać moich postów? Jeśli chcesz zasugerować edycję, zrób to w komentarzach.
Shaun Wild,
3

Galaretka , 17 bajtów

+×⁵?µDSP⁵?$ÐĿµL;Ṫ

Wypróbuj online!

Biorąc pod uwagę takie argumenty x y 1, oblicza to sumę Anastasiya x (+) y.

Biorąc pod uwagę takie argumenty x y 0, oblicza to produkt Anastasiya x (*) y.

Dane wyjściowe są podane jako [number of steps, result].

Lynn
źródło
Dzięki za odpowiedź, ale twój wynik programu nie zawiera wymaganej części kroków? Czy coś mi umyka?
Anastasiya-Romanova 秀
3

Python, 160 146 129 bajtów

def r(s):
 n=str(eval(s));c=0
 while n[1:]:exec("n=str(reduce(lambda a,b:a%sb,map(int,list(n))))"%"*+"["+"in s]);c+=1
 return n,c

Wkrótce opublikuje wyjaśnienie.

Dane wejściowe mają postać 12+12lub 5*35(z normalnym +i *znakami) i zakładają, że są to jedyne dwa operatory.

Może obsłużyć tak duże liczby, jak pozwala na to pamięć komputera.

Jestem prawie na pewno przekonany, że może być dalej.

EDYCJA: 16 31 bajtów zapisanych dzięki @Copper.

clismique
źródło
Dzięki za odpowiedź, (+1). Czy poradzi sobie z wprowadzaniem dużych liczb?
Anastasiya-Romanova 秀
@ Anastasiya-Romanova 秀 Uhmmm ... Jestem całkiem pewien, że mogą. Czy możesz podać mi przykłady dużych nakładów? Spróbuję na ich podstawie obliczyć.
clismique
Może: 3218753647208435810122106 * 29349566754?
Anastasiya-Romanova 秀
1
@ Anastasiya-Romanova 秀 Tak, zadziałało w ~ 0,5 sekundy, nie odpowiednio go czas.
clismique
Możesz zmienić "+" if "+" in s else "*"na "*+"["+"in s], a następnie zamiast przypisywać go t, po prostu dodaj go bezpośrednio w execpołączeniu.
Miedzi
3

R, 110 bajtów

Korzystanie z rozdzielacza @plannapus.

function(A,F,B){r=Reduce;x=r(F,A,B);y=1;while(x>9){m=nchar(x);x=r(F,x%%10^(1:m)%/%10^(1:m-1));y=y+1};cat(x,y)}

f=function(A,F,B){
  r=Reduce                                  # Shortcut for Reduce
  x=r(F,A,B)                                # A operator B
  y=1                                       # Initiate counter
  while(x>9)                                # If number of digits > 2, or number > 9
  {m=nchar(x)                               # Count number of digits
    x=r(F,x%%10^(1:m)%/%10^(1:m-1))         # @plannapus's splitter, then feed into the A operator B operator C, etc while condition true
    y=y+1}                                  # Increment counter
  cat(x,y)}                                 # Print

Wynik

> f(136,"*",2356)
0 2
> f(31,"+",81)
4 2
> f(2,"+",3)
5 1
> (function(A,F,B){r=Reduce;x=r(F,A,B);y=1;while(x>9){m=nchar(x);x=r(F,x%%10^(1:m)%/%10^(1:m-1));y=y+1};cat(x,y)})(21,"*",111)
8 3

edycja: Nie mogę liczyć.

Vlo
źródło
R jest fantastyczny, ponieważ pozwala nam skrócić jego funkcję, co jest cenne w golfie. (+1)
Anastasiya-Romanova 秀
3

Clojure 126 bajtów

(defn f [o a b] (loop [n (o a b) c 1] (if (< n 10) [n c] (recur (reduce #(o %1 %2) (map #(- (int %) 48) (str n))) (inc c)))))

Funkcja nazywa się tak:

(f + 81 31)

Oto kod niepoddany golfowi:

(defn f [o a b]
  (loop [n (o a b) c 1]
    (if (< n 10)
      [n c]
      (recur (reduce #(o %1 %2)
                     (map #(- (int %) 48) (str n)))
             (inc c)))))

(def test-cases [[+ 81 31]
                 [+ 351 14568]
                 [* 21 111]
                 [* 136 2356]])

(map #(apply f %) test-cases)
;;=> ([4 2] [6 3] [8 3] [0 2])

Pamiętaj, że Clojure wciąż jest dla mnie nowy, więc prawdopodobnie nie jest to najlepsze rozwiązanie. Mimo wszystko wyzwanie było fajne. Dodatkowo kod działał z bardzo dużymi liczbami bez żadnych trudności.

James B.
źródło
Jest bardzo późno, ale możesz zmniejszyć większość dostępnych tam miejsc.
clismique
2

Perl 6 53 bajtów

{$/=(&^b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}

Ponieważ ( 12, &[+], 123 )jest to akceptowalne dla danych wejściowych, mogę sprowadzić je do 53 bajtów.
( &[+]jest skrótem od &infix:<+>„czci” dla operatora dodawania przyrostków numerycznych)

Gdyby drugi argument miał być łańcuchem (+), miałby 87 bajtów

{my&b=::("&infix:<$^b.substr(1,1)>");$/=(b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}

Wyjaśnienie:

# bare block lambda with 3 parameters declared using placeholder syntax
{
  # store list into 「$/」
  # ( used 「$/」 so that I don't have to declare a variable )
  $/ = (

    # declare second placeholder parameter, and call it
    &^b(
      # with the first and third placeholder parameters
      $^a, $^c
    ),

    # bare block lambda with implicit parameter 「$_」
    {
      # list reduce using the second parameter from outer block
      [[&b]]

      # a list of the digits of 「$_」 (implicit method call)
      .comb
    }

    # keep doing that until
    ...

    # it produces something smaller than 10
    # ( Whatever lambda )
    10 > *
  );

  # returns

  # final result ( last value from list )
  $/[ * - 1 ],
  # and count of values in list
  +$/
}

Test:

#! /usr/bin/env perl6
use v6.c;
use Test;

my &anastasiya-math = {$/=(&^b($^a,$^c),{[[&b]] .comb}...10>*);$/[*-1],+$/}

my @test = (
  (  81, &[+], 31    ) => (4, 2),
  ( 351, &[+], 14568 ) => (6, 3),
  (  21, &[*], 111   ) => (8, 3),
  ( 136, &[*], 2356  ) => (0, 2),
);

plan +@test;

for @test -> $_ ( :key(@input), :value(@expected) ) {
  cmp-ok anastasiya-math(|@input), &[»==«], @expected;
}

Normalne użycie:

# override built-in Bag operator 「(+)」 in current lexical scope
my &infix:<(+)> = &anastasiya-math.assuming: *, &[+], *;

# add a new operator
my &infix:<(*)> = &anastasiya-math.assuming: *, &[*], *;

say 12 (+) 123; # (9 2)
say 12 (*) 123; # (6 5)
Brad Gilbert b2gills
źródło
2

Python 2, 107 97 bajtów

g=lambda x,o,i=1:x<10and[x,i]or g(eval(o.join(`x`)),o,i+1)
lambda a,o,b:g(eval('%s'*3%(a,o,b)),o)

Anonimowa funkcja, która pobiera dane wejściowe za pomocą argumentu pierwszego operandu a, operatora o( '+'lub '*') i drugiego operandu bi zwraca listę formularza [result, steps].

Jak to działa

Funkcja anonimowa tworzy ciąg, łącząc operandy z operatorem między nimi, a następnie ocenia go; jest to pierwszy krok opisany w pytaniu. Następnie ta wartość i operator są przekazywane do funkcji rekurencyjnej g. Tutaj iużywany jest licznik , który jest zwiększany dla każdego połączenia rekurencyjnego. Jeśli wartość wejściowa jest mniejsza niż 10, musi zostać osiągnięta pojedyncza cyfra, więc to i isą zwracane. Jeśli nie, dane wejściowe są konwertowane na ciąg znaków, a każdy znak w tym ciągu jest łączony z operatorem, co daje pożądane obliczenia, które są następnie oceniane i przekazywane do funkcji rekurencyjnie.

Wypróbuj na Ideone

TheBikingViking
źródło
(+1) podczas oczekiwania na wyjaśnienie :)
Anastasiya-Romanova 秀
2

Groovy, 102 bajty

def p,e,r;p={t,m,d->e=d*.toInteger();r=m<1?e.sum():e.inject{a,b->a*b};r>9?p(++t,m,""+r as List):[r,t]}

Degolfed

def p,e,r
p = { t, m, d ->
    e = d*.toInteger()
    r = (
            m<1
                ? e.sum()
                : e.inject { a, b -> a * b }
        )
    r > 9
        ? p(++t, m, "" + r as List)
        : [r,t]
}

Wyjaśnienie

Na podstawie doskonałego rozwiązania @Sean Bean dla Java.

  • p: Zamknięcie (funkcja, lambda, cokolwiek), które implementuje rozwiązanie
  • t: pZawsze należy wywoływać bieżącą głębokość połączenia (liczbę iteracji)t=1
  • m: Operacja do wykonania, 0„dodaj”, 1„pomnóż”
  • d: Lista operandów, każdy operand jest obiektem typu String
  • e: Elementy dkażdego z nich przekonwertowane na liczbę całkowitą
  • r: Suma lub iloczyn e, zależnie od operacjim
  • instrukcja wynikowa, zaczynająca się od r > 9:
    • Jeśli jest wielocyfrowy ( r > 9), ponownie wywołaj, zwiększając głębokość ti konwertując rna listę ciągów cyfr (i zwracaj wynik).
    • Jeśli są jednocyfrowe, zwróć ri tjako listę.

Program testowy

final ADD = 0
final MULTIPLY = 1
println p(1, ADD, ["12", "123"]) //9, 2
println p(1, MULTIPLY, ["12", "123"]) //6, 5
println p(1, ADD, ["2", "3"]) //5, 1

Wyniki

[9, 2]
[6, 5]
[5, 1]
Roger Glover
źródło
2

Haskell, 76 70 bajtów

 (x#y)f=until(<[10])(\[s,i]->[foldr(f.read.pure)0$show s,i+1])[f x y,1]

Zwraca listę dwóch elementów z wynikiem i liczbą kroków. Działa dla dowolnych dużych liczb. Przykład użycia: (351#14568)(+)-> [6,3].

Edycja: Dzięki @BlackCap na 6 bajtów.

nimi
źródło
Można wymienić (-48+).fromEnumzread.pure
Gajówka
2

R, 91 bajtów

Używając kodu @ Vlo, który korzysta z rozdzielacza @ plannapus, oraz kilku pomysłów, które wygenerowałem podczas gry w golfa w odpowiedzi @ Frédéric, jest to najkrótsza jak dotąd odpowiedź R. (Niezwykle duża liczba odpowiedzi R dzisiaj tutaj ...)

function(A,F,B){x=F(A,B);while(x>9){m=nchar(x);x=F(x%%10^(1:m)%/%10^(1:m-1));T=T+1};c(x,T)}

Co najważniejsze, wymaga to, aby dane wejściowe dla operatora były albo sumdla (+) albo proddla (*). Zgodnie z zasadami wyzwania wydaje się to w porządku.

Z wcięciem:

function(A,F,B){
  x=F(A,B);
  while(x>9){
    m=nchar(x);
    x=F(x%%10^(1:m)%/%10^(1:m-1));
    T=T+1
  };
  c(x,T)
}

Główne różnice w stosunku do odpowiedzi @ Vlo to:

  1. Zamiast używać Reduce, polegamy na tym, że argument wejściowy jest funkcją i po prostu wywołujemy go jawnie. (Tak, dla funkcji będących obiektami pierwszej klasy!)
  2. Zamiast inicjowania nowej zmiennej w naszej kasie, mamy nadużywanie pomocy poleceń wbudowanych i korzystanie grupę R T, co ocenia się TRUE(aka 1), ale ponieważ nie jest to zmienna Reserved możemy go modyfikować. Tak T+Tjest 2. Używamy tego jako naszego licznika.
  3. Zamiast cating wyjściowy, po prostu zwracamy go jako wektor z c. Oprócz oszczędzania dwóch bajtów, fakt, że wyjście jest wtłaczane do wektora, zapewnia Tklasę numeric. Jeśli użyjemy cat, a Tnie zwiększono, otrzymamy błędne dane wyjściowe jak 1 TRUE.
rturnbull
źródło
można zrestrukturyzować whilepętlę w następujący sposób zmienia Fsię coś innego, aby uniknąć konfliktów nazw: function(A,O,B){x=O(A,B);while({F=F+1;x>9})x=O(x%/%10^(1:nchar(x)-1)%%10;c(x,F)}}. To niesamowite, ile sztuczek w golfa R wymyśliliśmy w ciągu ostatnich kilku lat :)
Giuseppe,
@Giuseppe Nice restrukturyzacja! W tej chwili nie mogę znaleźć meta-konsensusu, ale jestem dość pewny, że użycie funkcji Ti Fcounter-trick w funkcji jest w rzeczywistości nieprawidłowe, ponieważ oznacza to, że funkcję można wywołać tylko raz. Więc ta odpowiedź (i kilka innych moich!) Jest nieprawidłowa, chyba że rm(T)na końcu jest wyraźne . Będę nadal szukał tego meta postu, aby mieć pewność, że nie wymyśliłem go.
rturnbull
Uważam, że sztuczka Ti Ftrik jest całkowicie poprawna, o ile nie modyfikujesz Tani Fw środowisku globalnym. na przykład f=function(){T=T+1;T}konsekwentnie zwraca 2. Myślę, że to jest meta słup, do którego odnoszą.
Giuseppe,
@Giuseppe Ah tak, masz rację w obu kwestiach. Dzięki!
rturnbull
1

Rubinowy, 55 bajtów

Połączenie rekurencyjne. Kiedyś bardzo różnił się od odpowiedzi JavaScript @ edc65, ale kiedy zoptymalizowałem, ostatecznie stał się portem bezpośrednim opracowanym prawie niezależnie od ich odpowiedzi, minus jedna końcowa optymalizacja polegająca na sprawdzeniu ewaluowanego wyniku zamiast długości przekazywanej listy argumentów , co pozwoliło mi przekroczyć liczbę bajtów.

Dane wejściowe to ciąg znaków reprezentujący operator oraz tablica zawierająca operandy.

Wypróbuj online.

f=->o,x,i=1{y=eval x*o;y>9?f[o,y.to_s.chars,i+1]:[y,i]}
Wartość tuszu
źródło
Wynik jest prawidłowy, ale liczba kroków wymaganych do uzyskania wartości jednocyfrowej jest nieprawidłowa. Czy możesz poprawić swój kod?
Anastasiya-Romanova 秀
@ Anastasiya-Romanova 秀 ah, masz rację. Moja stara logika wymagała, aby zaczynała się i=0i zapomniałem przy refaktoryzacji.
Wartość tuszu
1

Perl, 38 bajtów

Obejmuje +2 za -ap

Uruchom z danymi wejściowymi STDIN i odstępami wokół operatora:

amath.pl <<< "12 + 123"
amath.pl <<< "12 * 123"

Wyjście to cyfra, a kroki oddzielone są +A

amath.pl:

#!/usr/bin/perl -ap
1while++$\,$_=eval."+A",s/\B/$F[1]/g

Jeśli wyprowadzanie kroków w unary jest prawidłowe, ta 35-bajtowa wersja działa lepiej:

#!/usr/bin/perl -lap
1while$\.=1,$_=eval,s/\B/$F[1]/g
Ton Hospel
źródło
1

Mathematica, 105 94 bajtów

Kod.

{x,y}=(c=0;f//.a_:>(c++;t=o@@IntegerDigits@a);{t,c})&/.{{f->#1+#2,o->Plus},{f->#1#2,o->Times}}

Stosowanie.

x[81, 31]
(* {4, 2} *)

x[351, 14568]
(* {6, 3} *)

y[21, 111]
(* {8, 3} *)

y[136, 2356]
(* {0, 2} *)

Wyjaśnienie.

Dwie funkcje x(dla (+)) i y(dla (*)) są tworzone jednocześnie, zastępując parametry fi ow

(c = 0;
 f //. a_ :> (c++; t = o@@ IntegerDigits@a);
 {t, c}
)&

z ich odpowiednimi wartościami. Na x, fstaje się #1 + #2i ostaje Plus; bo yodpowiednio stają się #1 #2i Times. Przepisanie funkcji xdla ostatniej części objaśnienia:

x = (
  c = 0;
  #1 + #2 //. a_ :> (c++; t = Plus@@IntegerDigits@a); 
  {t, c}
) &;

(* The symbol //. stands for ReplaceRepeated. 
   The rule a_ :> (c++; t = Plus@@IntegerDigits@a) is applied until the result no longer 
changed. Specifically, the rule increments the counter of 1 at each step (this is c++), 
then takes the sum of the digits of the previous result (this is Plus@@IntegerDigits@a). 
The rule stops to apply when the variable t is less than 10. We return the final result and 
the number of steps with {t, c}. *)

źródło
1

Java 7, 203 195 192 bajtów

int c=1;String c(long a,long b,int o){return p(((o<1?a+b:a*b)+"",o)+","+c;}long p(String n,int o){long x=o,q;for(String s:n.split("")){q=new Long(s);x=o<1?x+q:x*q}c++;return x<10?x:p(x+"",o);}

Wykorzystuje long(maksymalna wartość 2 63 -1). Jeśli intzamiast tego użyje (maksymalna wartość 2 31 -1), będzie to tylko 1 bajt mniej ( 191 bajtów ):

int c=1;String c(int a,int b,int o){return p(((o<1?a+b:a*b)+"",o)+","+c;}int p(String n,int o){int x=o,q;for(String s:n.split("")){q=new Integer(s);x=o<1?x+q:x*q}c++;return x<10?x:p(x+"",o);}

Najprawdopodobniej można go nieco pograć w golfa. Konieczność wydrukowania kroków oraz odpowiedzi dla obu operatorów zajmuje jednak trochę bajtów.
Używa 0 (dla (+)) i 1 (dla (*)).

Kod niepoznany i testowy:

Wypróbuj tutaj.

class Main{
  static int c = 1;
  static String c(long a, long b, int o){
    return p((o < 1 ? a+b : a*b) + "", o) + "," + c;
  }

  static long p(String n, int o){
    long x = o,
         q;
    for(String s : n.split("")){
      q = new Long(s);
      x = o < 1
           ? x + q
           : x * q;
    }
    c++;
    return x < 10
            ? x
            : p(x+"", o);
  }

  public static void main(String[] a){
    System.out.println(c(81, 31, true));
    c = 1;
    System.out.println(c(351, 14568, true));
    c = 1;
    System.out.println(c(21, 111, false));
    c = 1;
    System.out.println(c(136, 2356, false));
  }
}

Wynik:

4,2
6,3
8,3
0,2
Kevin Cruijssen
źródło