Wie funktioniert Mathematik in der Welt von Anastasiya?


44

Hintergrund:

Standardoperationsmathematik wie einfache Addition und Multiplikation in der realen Welt funktioniert folgendermaßen:

12 + 123 = 135

und

12 * 123 = 1476

Das ist nicht interessant und langweilig! Viele Schulen interpretieren dies bereits als Üben, Üben, Üben formaler Algorithmen. Dies impliziert eine ziemlich starre und langweilige mathematische Diät und ist nicht das, was in dieser Herausforderung beabsichtigt ist. Machen Sie sich bereit, um Spaß auf unserer geliebten Seite zu haben.

Betrachten Sie den Vorgang des Addierens zweier positiver ganzzahliger Zahlen und fügen Sie dann alle Ziffern des Ergebnisses erneut hinzu. Wiederholen Sie den Vorgang mit der Addition, bis nur noch eine Ziffer erhalten wird. Zum Beispiel:

  1. Das Ergebnis von 12 + 123ist 135.
  2. Addiert man alle Ziffern von 135, so erhält man 1 + 3 + 5 = 9.

Die Anzahl der Schritte, die erforderlich sind, um bei dieser wiederholten Addition einen einstelligen Wert 9 zu erhalten, beträgt 2.

Wie beim vorherigen Additionsvorgang folgt die Multiplikation zweier positiver ganzzahliger Zahlen demselben Vorgang. Multiplizieren Sie alle Ziffern des Ergebnisses und wiederholen Sie diesen Vorgang, bis nur noch eine einzige Ziffer übrig bleibt. Nehmen Sie das obige Beispiel:

  1. Das Ergebnis von 12 * 123ist 1476.
  2. Multiplizieren Sie alle Ziffern von 1476, die wir erhalten 1 * 4 * 7 * 6 = 168.
  3. Multiplizieren Sie erneut alle Ziffern von 168, die wir erhalten 1 * 6 * 8 = 48.
  4. Multiplizieren Sie noch einmal alle 48 Stellen, die wir erhalten 4 * 8 = 32.
  5. Multiplizieren Sie noch einmal alle Ziffern von 32, die wir erhalten 3 * 2 = 6.

Die Anzahl der Schritte, die erforderlich sind, um bei dieser wiederholten Multiplikation einen einstelligen Wert 6 zu erhalten, beträgt 5.

Um dieser Herausforderung willen und um einen Missbrauch von mathematischen Notationen zu vermeiden, füge ich diese beiden Dummy-Notationen ein: (+)und (*), aber Sie können jede beliebige Notation verwenden , die wie folgt funktioniert:

  1. Die Operation des wiederholten Additionsprozesses, um einen einzelnen Wert zu erhalten, ist 12 (+) 123 = 9.
  2. Die Operation des wiederholten Multiplikationsprozesses, um einen einzelnen Wert zu erhalten, ist 12 (*) 123 = 6.

Herausforderung:

Die Herausforderung besteht darin, entweder ein Programm oder eine Funktion zu schreiben, die beide im Abschnitt "Hintergrund" erläuterten Operationen ausführen kann : (+)und (*).

Eingang:

Die Eingänge des Programms oder der Funktion sind zwei positive ganze Zahlen und eine Operation entweder (+)und (*). Das Format der Eingabe ist eine willkürliche Wahl des Programmierers . Sie können die Eingabeformat zum Beispiel a (+) boder F(a, (+), b)oder ein beliebiges Format Sie wünschen.

Ausgabe:

Die Ausgabe des Programms oder der Funktion muss das Ergebnis der Operation und die Anzahl der erforderlichen Schritte im Freestyle-Format enthalten.

Testfälle (ignorieren Sie das Eingabe- und Ausgabeformat):

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

Allgemeine Regeln:

  • Das ist , also gewinnt die kürzeste Antwort in Bytes die Herausforderung.
    Lassen Sie sich nicht von Esolangs davon abhalten, eine Antwort in regulären Sprachen zu veröffentlichen. Genießen Sie diese Herausforderung, indem Sie mit Ihrer Programmiersprache eine möglichst kurze Antwort geben. Wenn Sie eine clevere Antwort und eine klare Erklärung abgeben, wird Ihre Antwort geschätzt (daher die positiven Stimmen), unabhängig davon, welche Programmiersprache Sie verwenden.
  • Für Ihre Antwort gelten Standardregeln. Daher dürfen Sie STDIN / STDOUT, Funktionen / Methoden mit den richtigen Parametern, vollständige Programme usw. verwenden. Sie haben die Wahl.
  • Wenn möglich, kann Ihr Programm große Zahlen richtig verarbeiten. Wenn nicht, ist das in Ordnung.

Lasst das Spiel beginnen!!


Der wiederholte Additionsteil ( digitale Wurzel ) ist im Wesentlichen ein Duplikat von codegolf.stackexchange.com/q/1128/194
Peter Taylor,

4
Tolle erste Frage! Und ich erkenne das allgemeine Regelformat und die Sätze aus meinen eigenen Fragen. ;)
Kevin Cruijssen

4
@ KevinCruijssen Yup. Stimmt. Da es kein Copyright hat, kopiere ich es ohne Ihre Erlaubnis. Hehehe: D
Anastasiya-Romanova 秀

4
@ Anastasiya-Romanova 秀 "kein Urheberrecht"? Im 21. Jahrhundert? Nee; alles hier ist CC-BY-SA 3.0. Die Erlaubnis wird erteilt, wenn der Inhalt eingereicht wird. Überprüfen Sie die Fußzeile der Site.
Mindwin

1
@ BradGilbertb2gills Ja, natürlich. Das steht übrigens in der Post. Zitat: "Das Format der Eingabe ist eine willkürliche Wahl des Programmierers".
Anastasiya-Romanova 秀

Antworten:


11

Dyalog APL , 33 32 30 29 Bytes

Dies erweitert APL um die Präfixnotation +/A n₁ n₂und ×/A n₁ n₂. (Tatsächlich können Sie eine beliebige Operation links von der /A. Verwenden .) Gibt eine Liste mit {Ergebnis, Wiederholungsanzahl} zurück.

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

A←{Definieren Sie eine Funktion höherer Ordnung in Bezug auf die linke Funktion ⍺⍺und das rechte Argument

(⊃,≢) das erste Element von, gefolgt von der Zählung von

⍺⍺{die gelieferte Funktion ( +/für Summe oder ×/für Produkt) wird der übergeordneten Funktion zugeführt

die einzigartigen Elemente von

⍵,⍨ das Argument angehängt an

⍺⍺ die gefütterte Funktion angewendet auf

⍎¨ die Bewertung jedes Zeichens von

die Charakterdarstellung von

⊃⍵ das erste Element des Arguments

}⍣≡ wiederholt angewendet, bis das Ergebnis mit dem Argument identisch ist, beginnend mit

⍺⍺⍵Die ursprünglich eingegebene Funktion ( +/oder ×/) wurde auf das ursprüngliche Argument angewendet

} [Ende der Funktionsdefinition höherer Ordnung]

TryAPL online! ( Wurde eaus Sicherheitsgründen mit emuliert .)

Vielen Dank an @ngn für das Speichern eines Bytes.


0 Bytes (im Scherz)

Dyalog APL unterstützt Anastasiyan bereits vollständig. statt (+)und (×)verwendet es +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}und ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}.

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


Danke für die Antwort (+1). Kann es eine große Anzahl von Eingaben verarbeiten?
Anastasiya-Romanova 秀

1
Bei Einstellung ⎕FR←1287(dh IEEE 754-2008 128-Bit - Dezimalzahl verwendet F loating Punkt R ePresentation) und ⎕PP←34(dh Einsatz 34 Zeichen P RINT P recision), können Sie unter ganzen Zahlen 10³⁴ verwenden.
Adám

Hmm, obwohl es volle Unterstützung hat, sind es nicht +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}und ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}immer noch einige Bytes? Ich bin verwirrt darüber, wie das 0 Bytes ist ..: S
Kevin Cruijssen

3
@KevinCruijssen Das OP erlaubt jede Eingabe-Notation. Wenn also eine Sprache die Standardnotation Anastasiyan unterstützt, wäre das Mehrzeichen-Symbol (+)das Anastasiyan. Dyalog APL unterstützt Anastasiyan-Mathematik, verwendet jedoch ein anderes Mehrzeichen-Glyphen, genau wie es *die Potenz bedeutet und Sie ×für die Multiplikation benötigen , während es /Replikation bedeutet und Sie ÷für die Division benötigen .
Adám

1
@Adam Ah ok, das macht Sinn. Es verstößt gegen die Regeln von OP, verstößt aber nicht dagegen. Es ist immer noch ziemlich seltsam, dass (+)Sie +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}als Eingabe haben, aber da OP in der Tat angegeben hat, dass jedes Eingabeformat ausreicht, können Sie die Funktion als Parameter verwenden. Hmm, ich frage mich, ob dies auch in anderen Programmiersprachen möglich ist, die Funktionen als Eingabe unterstützen.
Kevin Cruijssen

8

Haskell, 108 Bytes

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

Definiert die Funktion , #die zuerst kommt aund bdann den Bediener o. Unterhaltsame Tatsache: Dies funktioniert mit jedem Operator (eigentlich jeder Funktion), den Sie wollen!


Danke für die Antwort (+1). Kann es eine große Anzahl von Eingaben verarbeiten?
Anastasiya-Romanova 秀

4
@ Anastasiya-Romanova 秀 Ja, es kann Zahlen verarbeiten, die so groß sind wie Ihr Arbeitsspeicher, da Haskells IntegerTyp unbegrenzt ist.
ThreeFx

8

Pyke, 16 Bytes

RE`DltImbRoKr)oh

Probieren Sie es hier aus!

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

Nimmt multiplizieren als Bund addieren als s. Die beiden numerischen Eingaben sind durch Kommas getrennt.


1
Nett! Können wir eine Erklärung bekommen?
Emigna

Danke für die Antwort (+1). Kann es eine große Anzahl von Eingaben verarbeiten?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 es sollte in der Lage sein, beliebige Zahlen zu verarbeiten
Blue

Ich kann Ihren Code nicht testen, da das Web blockiert ist, da es gegen die Internetnutzungsrichtlinie meiner Eltern verstößt. T_T
Anastasiya-Romanova 秀

Etwa so: Webseite gesperrt! Sie haben versucht, auf eine Webseite zuzugreifen, die gegen Ihre Internetnutzungsrichtlinien verstößt. URL: pyke.catbus.co.uk/?code=RE%60DltImbRoKr%29oh&input=B%0A21%2C+111&warnings=0 Kategorie: Nicht bewertet
Anastasiya-Romanova 秀

8

JavaScript (ES6), 59

Rekursive Funktion, das Eingabeformat ist so angepasst, dass der rekursive Aufruf vereinfacht wird:

  • Betreiber: '+' oder '*'
  • Operanden: Array mit zwei Werten
f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]

Prüfung

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


Danke für die Antwort (+1). Kann es eine große Anzahl von Eingaben verarbeiten?
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀 bis zur Grenze des numerischen Javascript-Formats, 53 Bits Genauigkeit (17 Dezimalstellen)
edc65

8

Python 2, 60 Bytes

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

Die Eingabe ist wie eine Zeichenfolge 81+31, die Ausgabe ist ein Tupel einer Singleton-Zeichenfolge und eines Zählers (z ('4', 2). B..

Teste es auf Ideone .


Wenn die Eingabe als ein Array von Zeichenfolgen und eine einzelne Zeichenfolge zulässig ist, kann beispielsweise f(['81', '31'],'+')ein weiteres Byte gespeichert werden, aber das fühlt sich an, als würden die Regeln ein bisschen zu weit
Dennis


... in diesem Fall würde ich sogar so weit gehen und überlegen, ob ich gehen soll operator.addoder nicht operator.mul;)
Tobias Kienzler

7

Pyth, 16

eJ.uvjhQ`N.vQ)lJ

Übernimmt Eingaben wie "+ 123 12"zum Addieren und "* 123 12"zum Multiplizieren. Ausgänge mögen result<linefeed>steps.

Probieren Sie es hier aus oder führen Sie eine Testsuite aus . Beachten Sie jedoch, dass dies von eval abhängt, sodass im Online-Interpreter nur die Additionsvariante funktioniert. Die Multiplikation funktioniert ordnungsgemäß mit dem Offline-Interpreter.

Dies verwendet die kumulative Reduktionsfunktion, um eine Liste von Zwischenergebnissen zu erstellen, damit "+ 351 14568"wir erhalten [14919, 24, 6]. Dies funktioniert, weil einstellige Zahlen ein fester Punkt bei der Addition und Multiplikation von Anastasiya sind. Dann erhalten wir nur das letzte Element des Arrays sowie die Länge des Arrays.

Dies funktioniert für beliebig große Zahlen, zumindest bis Ihnen der Speicher ausgeht.


7

R, 175 167 164 140 134 127 126 119 Bytes

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

Ungolfed:

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

ifelseist zurück ! Ja!
Nein

Verwendungszweck :

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

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

Vielen Dank an @plannapus für die 24 Bytes!
-7 Bytes dank einer guten Idee von @Vlo !


Ja, bitte füge Erklärungen hinzu, da ich R liebe! Dies ist meine zweite Sprache nach VBA. (+1)
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀: Fertig!
Frédéric

@plannapus: Wirklich schön! Danke vielmals !
Frédéric

1
@ Frédéric schön benutzt strtoi! 4 weitere Bytes hast du mir geschlagen.
Plannapus

1
Sieht so aus, als könnten Sie ein Byte weiter vertiefen, indem Sie die Definition von O in die Zuweisung von x in der ersten Operation aufnehmen: x = (O = Schalter (S, Summe, `*`)) (G, D) ;.
Rturnbull

6

05AB1E , 20 15 Bytes

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

Erläuterung

[       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 ist 1 für Addition, 0 für Multiplikation.

Probieren Sie es online aus


Danke für die Antwort (+1). Kann es eine große Anzahl von Eingaben verarbeiten?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Ich sehe keinen Grund, warum nicht. Hast du ein Beispiel?
Emigna

Ihr Programm wurde auf diese Art von Eingaben getestet, daher ist es perfekt :)
Anastasiya-Romanova 秀

6

Jelly , 11 bis 10 Bytes

Dj⁹VµÐĿḊĖṪ

Die Eingabe ist ein Zahlenpaar und entweder +oder ×.

Probieren Sie es online! oder überprüfen Sie alle Testfälle .

Wie es funktioniert

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.

6

ARM-Maschinencode, 48 Byte

Hex-Dump:

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

Diese Funktion hängt nicht von Systemaufrufen oder Bibliotheksfunktionen ab. Dies ist der Thumb-2-Code, bei dem es sich um eine Befehlscodierung variabler Länge (2 oder 4 Byte) für 32-Bit-ARM handelt. Der maximale Wert, den es verarbeiten kann, ist 2 ^ 32-1. Es könnten 2 Bytes gelöscht werden, wenn es nicht dem AAPCS ( 46 Bytes ) entspricht, da wir zu Beginn keine Register stapeln müssten.

Ungolfed-Assembly (GNU-Syntax):

.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

Testskript in 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));
}

4

R, 130 124 Zeichen

Ein etwas anderer Ansatz als bei @ Frédéric :

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

Eingerückt, mit Zeilenumbrüchen:

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
    }

Zeile 4 benötigt wahrscheinlich weitere Erklärungen:

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

Testfälle:

> f(12,"(+)",123)
[1] 9 2
> f(12,"(*)",123)
[1] 6 5
> f(351,"(+)",14568)
[1] 6 3

Sehr bedauerlich, dass Sie mit dieser Antwort zu spät gekommen sind, aber Sie haben meine Zustimmung. Vielen Dank für die Erstellung in R.
Anastasiya-Romanova

Warum unglücklich?
Plannapus

Denn wenn du zuerst gekommen wärst, hättest du mehr Gegenstimmen
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Fair genug :)
Plannapus

Bonuspunkte für fden Funktionsnamen und eines seiner Argumente :)
JDL

4

Oktave, 85 Bytes MATLAB, 123, 114, 105, 94 Bytes

Beschlossen, dies in Octace zu übersetzen, um die direkte Indizierung zu nutzen und die Fähigkeiten zu erhöhen. Übernimmt die Eingabe in das Formular:, f(a,operator)where a = [number1, number2], und operator==1gibt das Produkt und operator==2die Summe an.

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

Erklärungen:

g={@prod,@sum}{o} : Wählt die entsprechende Funktion, das Produkt oder die Summe aus und weist sie zu g

x=g(a) Nimmt die Summe oder das Produkt der Eingaben

i=1; ... i++ : Inkrementierer zum Zählen der Anzahl der Schritte

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

Zwei Zeilenumbrüche, ein Leerzeichen, wurden entfernt und beide Eingabenummern in einem Vektor anstelle von separaten Argumenten platziert. Dies sparte dank pajonk 9 Bytes! Entfernt k=@(x)..., um dank Becher weitere 11 Bytes zu speichern =) Zum Schluss haben wir das Ganze in Octave übersetzt, um weitere 9 Bytes zu speichern ...


4

Java, 164 159 146 Bytes

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

Das erste Argument ist nur der Zähler, immer 0

Das zweite Argument ist die Methode 0 für ADD und 1 für MULTIPLY.

Das dritte Argument ist ein Array von Strings, das die zu addierenden / multiplizierenden Werte enthält.

Ungolfed

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

danke an @Kevin Cruijssen für das Schneiden einiger Bytes.

danke an @milk für das rasieren von 5 bytes.

Testprogramm

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

Schön, kürzer als meine Java-Antwort . Sie sollten jedoch auch die Schritte sowie die Antwort ausdrucken, die derzeit in Ihrer Antwort fehlt.
Kevin Cruijssen

@ KevinCruijssen Ahh. Das ist langweilig. Ich werde versuchen, das jetzt zu beheben.
Shaun Wild

Übrigens können Sie Ihre aktuelle Antwort ein wenig Golf spielen. m==0kann sein m<1, und Integer.parseIntkann sein Integer.decode.
Kevin Cruijssen

Ich benutze Java nicht viel, aber brauchst du das jvar am Ende? Zweimaliges Inlining (r+"")scheint ein paar Bytes zu sparen.
Milch

1
Können wir meine Posts zukünftig nicht mehr ändern? Wenn Sie eine Bearbeitung vorschlagen möchten, tun Sie dies in den Kommentaren.
Shaun Wild

3

Gelee , 17 Bytes

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

Probieren Sie es online!

Bei solchen Argumenten x y 1wird die Anastasiya-Summe berechnet x (+) y.

Mit solchen Argumenten x y 0wird das Anastasiya-Produkt berechnet x (*) y.

Die Ausgabe erfolgt als [number of steps, result].


Vielen Dank für die Antwort, aber Ihre Programmausgabe enthält nicht die Anzahl der erforderlichen Schritte. Vermisse ich hier etwas?
Anastasiya-Romanova 秀

3

Python, 160 146 129 Bytes

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

Werde bald eine Erklärung posten.

Die Eingabe erfolgt in der Form 12+12oder 5*35(mit Normalen +und *Vorzeichen) und setzt voraus, dass dies die einzigen beiden Operatoren sind.

Es kann Zahleneingaben verarbeiten, die so groß sind, wie es der Arbeitsspeicher Ihres Computers zulässt.

Ich bin fast sicher, dass dies weiter gehen kann.

EDIT: 16 31 Bytes dank @Copper gespeichert.


Danke für die Antwort (+1). Kann es eine große Anzahl von Eingaben verarbeiten?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Uhmmm ... ich bin ziemlich sicher, dass sie können. Können Sie mir Beispiele für große Eingaben geben? Ich werde versuchen, daraus zu rechnen.
Clismique

Vielleicht: 3218753647208435810122106 * 29349566754?
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀 Ja, es hat in ca. 0,5 Sekunden funktioniert, es wurde nicht richtig eingestellt.
Clismique

Sie können ändern , "+" if "+" in s else "*"zu "*+"["+"in s], und dann , anstatt es die Zuordnung zu t, fügen Sie ihn einfach inline im execAufruf.
Kupfer

3

R, 110 Bytes

Verwendung des Splitters von @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

Ausgabe

> 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

edit: Ich kann nicht zählen.


R ist fantastisch, weil es uns erlaubt, seine Funktion zu verkürzen, was beim Golfen von großem Wert ist. (+1)
Anastasiya-Romanova 秀

3

Clojure 126 Bytes

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

Funktion heißt so:

(f + 81 31)

Hier ist der Code ungolfed:

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

Denken Sie daran, dass Clojure für mich noch neu ist. Dies ist wahrscheinlich nicht die beste Lösung. Die Herausforderung hat trotzdem Spaß gemacht. Außerdem lief der Code problemlos mit sehr großen Zahlen.


Dies ist sehr spät, aber Sie können die meisten Räume dort reduzieren.
Clismique

2

Perl 6 53 Bytes

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

Da ( 12, &[+], 123 )die Eingabe akzeptabel ist, kann ich sie auf 53 Byte reduzieren.
( &[+]ist eine Abkürzung für &infix:<+>"Verehrung" für den numerischen Infix-Additionsoperator)

Wenn das zweite Argument eine Zeichenfolge (+)sein müsste, wären es 87 Byte

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

Erläuterung:

# 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
  +$/
}

Prüfung:

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

Normale Nutzung:

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

2

Python 2, 107 97 Bytes

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)

Eine anonyme Funktion, die Eingaben über ein Argument eines ersten Operanden a, eines Operators o( '+'oder '*') und eines zweiten Operanden entgegennimmt bund eine Liste des Formulars zurückgibt [result, steps].

Wie es funktioniert

Die anonyme Funktion erstellt eine Zeichenfolge, indem die Operanden mit dem Operator dazwischen verkettet und dann ausgewertet werden. Dies ist der erste in der Frage beschriebene Schritt. Dieser Wert und der Operator werden dann an die rekursive Funktion übergeben g. Hier wird ein Zähler verwendet i, der für jeden rekursiven Aufruf inkrementiert wird. Ist die Eingabe kleiner als 10, muss eine einzelne Ziffer erreicht worden sein, damit diese und izurückgegeben werden. Ist dies nicht der Fall, wird die Eingabe in eine Zeichenfolge konvertiert und jedes Zeichen in dieser Zeichenfolge wird mit dem Operator verknüpft. Dabei wird die gewünschte Berechnung angegeben, die dann ausgewertet und rekursiv an die Funktion übergeben wird.

Probieren Sie es auf Ideone


(+1) während auf die Erklärung gewartet wird :)
Anastasiya-Romanova 秀

2

Groovy, 102 Bytes

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

Entgolft

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

Erläuterung

Basiert auf der exzellenten Lösung von @Sean Bean für Java.

  • p: Der Verschluss (Funktion, Lambda, was auch immer), der die Lösung implementiert
  • t: Die aktuelle Aufruftiefe (Anzahl der Iterationen) psollte immer mit aufgerufen werdent=1
  • m: Die auszuführende Operation 0für "Addieren" und 1"Multiplizieren"
  • d: Die Liste der Operanden, jeder Operand ist ein String-Objekt
  • e: Die Elemente von dwerden jeweils in eine Ganzzahl umgewandelt
  • r: Die Summe oder das Produkt von e, abhängig von der Operationm
  • Ergebnisaussage, beginnend mit r > 9:
    • Bei mehrstelligen r > 9Zeichen ( ) wird erneut aufgerufen, die Tiefe erhöht tund rin eine Liste von Zeichenfolgen konvertiert (und das Ergebnis zurückgegeben).
    • Wenn es sich um eine einstellige Zahl handelt, geben Sie rund tals Liste zurück.

Testprogramm

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

Ergebnisse

[9, 2]
[6, 5]
[5, 1]

2

Haskell, 76-70 Bytes

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

Gibt eine Liste mit zwei Elementen mit dem Ergebnis und der Anzahl der Schritte zurück. Funktioniert für beliebige große Zahlen. Anwendungsbeispiel: (351#14568)(+)-> [6,3].

Edit: Danke an @BlackCap für 6 Bytes.


Sie können (-48+).fromEnummitread.pure
BlackCap

2

R, 91 Bytes

Unter Verwendung des @ Vlo-Codes, der den @ plannapus-Splitter verwendet, und einiger Ideen, die ich beim Golfen mit @ Frédérics Antwort generiert habe, ist dies die bisher kürzeste R-Antwort. (Eine ungewöhnlich große Anzahl von R-Antworten hier heute ...)

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

Entscheidend ist, dass die Eingabe für den Operator entweder sumfür (+) oder prodfür (*) ist. Nach den Regeln der Herausforderung scheint dies in Ordnung zu sein.

Mit Einrückung:

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

Die Hauptunterschiede zu @ Vlos Antwort sind:

  1. Anstatt zu verwenden Reduce, verlassen wir uns darauf, dass das Eingabeargument eine Funktion ist, und rufen es einfach explizit auf. (Yay für Funktionen als erstklassige Objekte!)
  2. Anstatt eine neue Variable als unseren Zähler zu initialisieren, missbrauchen wir die eingebauten und verwendeten Funktionen von R T, die zu TRUE(aka 1) ausgewertet werden. Da es sich jedoch nicht um eine reservierte Variable handelt, können wir sie ändern. So T+Tist es 2. Also benutzen wir das als unsere Theke.
  3. Anstatt catdie Ausgabe zurückzugeben, geben wir sie einfach als Vektor mit zurück c. Die Tatsache, dass die Ausgabe in einen Vektor gezwungen wird, spart nicht nur zwei Bytes, sondern stellt auch sicher, dass die Ausgabe Tvon Klasse ist numeric. Wenn wir verwenden catund Tnicht inkrementiert wurden, erhalten wir eine fehlerhafte Ausgabe wie 1 TRUE.

Sie können die Umstrukturierung whileSchleife wie folgt zu ändern , Fetwas anderes zu vermeiden Namenskonflikte sein: 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)}}. Es ist erstaunlich, wie viele R-Golf-Tricks wir uns in den letzten Jahren ausgedacht haben :)
Giuseppe

@ Giuseppe Schöne Umstrukturierung! Ich kann den Metakonsens derzeit nicht finden, bin jedoch ziemlich sicher, dass die Verwendung des Tricks Tund Fcounter in einer Funktion tatsächlich ungültig ist, da die Funktion nur einmal aufgerufen werden kann. Diese Antwort (und einige meiner anderen!) Ist ungültig, es sei denn, rm(T)am Ende steht eine explizite . Ich werde weiter nach diesem Meta-Post suchen, damit ich sicher sein kann, dass ich es mir nicht nur ausgedacht habe.
Rturnbull

Ich glaube, dass der Tund- FTrick vollkommen gültig ist, solange Sie nichts ändern Toder Fin der globalen Umgebung. f=function(){T=T+1;T}kehrt zum Beispiel konsequent zurück 2. Ich denke, das ist der Meta-Post, auf den Sie verweisen.
Giuseppe

@ Giuseppe Ah ja, du hast in beiden Punkten Recht. Vielen Dank!
Rturnbull

1

Ruby, 55 Bytes

Rekursiver Aufruf. Früher war es ein großer Unterschied zur JavaScript-Antwort von @ edc65, aber als ich sie optimierte, wurde sie schließlich zu einem direkten Port, der fast unabhängig von ihrer Antwort entwickelt wurde , was mir erlaubte, ihre Byteanzahl zu übertreffen.

Die Eingabe ist eine Zeichenfolge, die den Operator darstellt, und ein Array, das die Operanden enthält.

Probieren Sie es online aus.

f=->o,x,i=1{y=eval x*o;y>9?f[o,y.to_s.chars,i+1]:[y,i]}

Das Ergebnis ist korrekt, aber die Anzahl der Schritte, die erforderlich sind, um einen einstelligen Wert zu erhalten, ist falsch. Könnten Sie Ihren Code korrigieren?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 ah, du hast recht. Meine alte Logik verlangte, dass es anfängt, i=0und ich vergaß es irgendwie, als ich umgestaltete.
Value Ink

1

Perl, 38 Bytes

Beinhaltet +2 für -ap

Führen Sie mit der Eingabe von STDIN und Leerzeichen um den Operator Folgendes aus:

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

Die Ausgabe erfolgt durch Ziffern und Schritte getrennt +A

amath.pl:

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

Wenn die Ausgabe der Schritte in Unary in Ordnung ist, funktioniert diese 35-Byte-Version besser:

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

1

Mathematica, 105 94 Bytes

Code.

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

Verwendungszweck.

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

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

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

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

Erläuterung.

Die beiden Funktionen x(für (+)) und y(für (*)) werden gleichzeitig durch Ersetzen der Parameter fund oin erstellt

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

mit ihren entsprechenden Werten. Denn x, fwird #1 + #2und owird Plus; denn ysie werden #1 #2und Times. Umschreiben der Funktion xfür den letzten Teil der Erklärung:

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

1

Java 7, 203 195 192 Bytes

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

Es verwendet long(maximaler Wert von 2 63 -1). Wenn es intstattdessen verwenden würde (Maximalwert von 2 31 -1), wäre es nur 1 Byte weniger ( 191 Bytes ):

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

Es kann höchstwahrscheinlich ein bisschen mehr golfen werden. Das Drucken der Schritte sowie der Antwort für beide Operatoren erfordert jedoch einige Bytes.
Verwendet 0 (für (+)) und 1 (für (*)).

Ungolfed & Testcode:

Probieren Sie es hier aus.

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

Ausgabe:

4,2
6,3
8,3
0,2
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.