Come funziona la matematica nel mondo di Anastasiya?


44

Sfondo:

La matematica delle operazioni standard come l'aggiunta e la moltiplicazione di base nel mondo reale funzionano in questo modo:

12 + 123 = 135

e

12 * 123 = 1476

Non è interessante e noioso! Molte scuole lo stanno già interpretando come pratica, pratica, pratica di algoritmi formali. Ciò implica una dieta matematica piuttosto rigida e noiosa e non è ciò che si intende in questa sfida. Preparati a divertirti sul nostro amato sito.

Considera il processo di aggiunta di due numeri interi positivi, quindi l'aggiunta di tutte le cifre del suo risultato. Ripetendo con l'aggiunta fino a ottenere una sola cifra. Per esempio:

  1. Il risultato di 12 + 123è 135.
  2. Aggiungendo tutte le cifre di 135 otteniamo 1 + 3 + 5 = 9.

Il numero di passaggi richiesti per ottenere un valore di una cifra singola in questa aggiunta ripetuta è 2.

Come nel precedente processo di addizione, la moltiplicazione di due numeri interi positivi segue lo stesso processo. Moltiplicare tutte le cifre del suo risultato e quindi ripetere questo processo fino a quando rimane una sola cifra. Prendi l'esempio sopra:

  1. Il risultato 12 * 123è 1476.
  2. Moltiplica tutte le cifre del 1476 che otteniamo 1 * 4 * 7 * 6 = 168.
  3. Moltiplica nuovamente tutte le cifre di 168 che otteniamo 1 * 6 * 8 = 48.
  4. Moltiplica nuovamente tutte le cifre di 48 che otteniamo 4 * 8 = 32.
  5. Moltiplica ancora una volta tutte le cifre di 32 che otteniamo 3 * 2 = 6.

Il numero di passaggi richiesti per ottenere un valore a singola cifra 6 questa moltiplicazione ripetuta è 5.

Per il bene di questa sfida ed evitando qualsiasi uso improprio delle notazioni matematiche, presento queste due notazioni fittizie: (+)e (*), ma puoi usare qualsiasi notazione che ti piace , che funziona come le seguenti:

  1. L'operazione del processo di addizione ripetuta per ottenere un singolo valore è 12 (+) 123 = 9.
  2. L'operazione del processo di moltiplicazione ripetuta per ottenere un singolo valore è 12 (*) 123 = 6.

Sfida:

La sfida è scrivere un programma o una funzione in grado di eseguire entrambe le operazioni, come spiegato nella sezione di sfondo: (+)e (*).

Ingresso:

Gli ingressi del programma o della funzione sono due numeri interi positivi e un'operazione sia (+)e (*). Il formato dell'input è una scelta arbitraria del programmatore . Si può formattare l'ingresso, per esempio, a (+) bo di F(a, (+), b)o qualsiasi formato che si desidera.

Produzione:

L'output del programma o della funzione deve contenere il risultato dell'operazione e il numero di passaggi richiesti con il formato freestyle come desiderato.

Casi di prova (ignora il formato di input e output):

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

Regole generali:

  • Questo è , quindi la risposta più breve in byte vince la sfida.
    Non lasciare che esolang ti scoraggi dal pubblicare una risposta con lingue regolari. Goditi questa sfida fornendo una risposta il più breve possibile con il tuo linguaggio di programmazione. Se pubblichi una risposta intelligente e una chiara spiegazione, la tua risposta sarà apprezzata (da qui i voti positivi) indipendentemente dal linguaggio di programmazione che usi.
  • Per la tua risposta valgono regole standard , quindi puoi usare STDIN / STDOUT, funzioni / metodo con i parametri corretti, programmi completi, ecc. La scelta è tua.
  • Se possibile, il programma può gestire correttamente numeri di grandi dimensioni. In caso contrario, andrà bene.

Che il gioco abbia inizio!!


La parte aggiunta aggiuntiva ( radice digitale ) è essenzialmente un duplicato di codegolf.stackexchange.com/q/1128/194
Peter Taylor,

4
Ottima prima domanda! E riconosco il formato delle regole generali e le frasi dalle mie domande. ;)
Kevin Cruijssen,

4
@KevinCruijssen Yup. giusto. Dal momento che non ha copyright quindi lo duplico senza la tua autorizzazione. Hehehe: D
Anastasiya-Romanova 秀

4
@ Anastasiya-Romanova 秀 "nessun copyright"? Nel XXI secolo? No; tutto qui è CC-BY-SA 3.0. L'autorizzazione è concessa quando viene inviato il contenuto. Controlla il piè di pagina del sito.
Mindwin,

1
@ BradGilbertb2gills Sì, certo. A proposito, è indicato nel post. Citazione: "Il formato dell'input è una scelta arbitraria del programmatore".
Anastasiya-Romanova 秀

Risposte:


11

Dyalog APL , 33 32 30 29 byte

Questo estende APL per includere la notazione del prefisso +/A n₁ n₂e ×/A n₁ n₂. (In effetti, è possibile utilizzare qualsiasi operazione a sinistra di /A.) Restituisce un elenco di {risultato, conteggio ripetizioni}.

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

A←{definire una funzione di ordine superiore in termini di funzione per mano sinistra ⍺⍺e argomento per mano destra

(⊃,≢) il primo elemento di, seguito dal conteggio di

⍺⍺{la funzione fornita ( +/per somma o ×/per prodotto) alimentata alla funzione di ordine superiore

gli elementi unici di

⍵,⍨ l'argomento è stato aggiunto

⍺⍺ la funzione di alimentazione applicata a

⍎¨ la valutazione di ogni personaggio di

la rappresentazione del personaggio di

⊃⍵ il primo elemento dell'argomento

}⍣≡ applicato ripetutamente fino a quando il risultato è identico all'argomento, a cominciare da

⍺⍺⍵la funzione originariamente alimentata ( +/o ×/) applicata all'argomento originale

} [fine della definizione della funzione di ordine superiore]

ProvaAPL online! ( è stato emulato eper motivi di sicurezza.)

Grazie a @ngn per aver salvato un byte.


0 byte (per scherzo)

Dyalog APL in realtà ha già il pieno supporto per la matematica Anastasiyan; invece di (+)e (×), usa +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}e ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}.

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


Grazie per la risposta, (+1). Può gestire input di grandi numeri?
Anastasiya-Romanova 秀

1
Se si imposta ⎕FR←1287(cioè usa IEEE 754-2008 128 bit decimale F loating punto R ePresentation) e ⎕PP←34(cioè, usare 34 personaggi P tampa P recision), è possibile utilizzare interi sotto 10³⁴.
Adám,

Hmm, anche se ha il pieno supporto, non sono +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}e sono ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}ancora abbastanza pochi byte? Sono confuso su come questo sia 0 byte ..: S
Kevin Cruijssen,

3
@KevinCruijssen L'OP consente qualsiasi notazione di input. Quindi, se una lingua dovesse supportare la notazione predefinita Anastasiyan per impostazione predefinita, il glifo multi-carattere (+)sarebbe l'Anastasiyan +. Dyalog APL supporta la matematica Anastasiyan, ma utilizza un glifo multi-carattere diverso, proprio come *significa potere e hai bisogno ×di moltiplicazione, mentre /significa replicazione e hai bisogno ÷di divisione.
Adám,

1
@ Adám Ah ok, ha senso. È un po 'piegare le regole di OP, ma non infrangerle. È ancora piuttosto strano che invece di (+)avere +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}come input, ma poiché OP ha effettivamente dichiarato che qualsiasi formato di input funzionerà, è possibile utilizzare la funzione come parametro. Hmm, mi chiedo se ciò sia possibile anche in altri linguaggi di programmazione che supportano le funzioni come input.
Kevin Cruijssen,

8

Haskell, 108 byte

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

Definisce la funzione #che prende prima ae bquindi l'operatore o. Curiosità: funziona con qualsiasi operatore (in realtà, qualsiasi funzione) tu voglia!


Grazie per la risposta, (+1). Può gestire input di grandi numeri?
Anastasiya-Romanova 秀

4
@ Anastasiya-Romanova 秀 Sì, può gestire numeri grandi quanto la tua RAM poiché il Integertipo di Haskell è illimitato.
ThreeFx

8

Pyke, 16 byte

RE`DltImbRoKr)oh

Provalo qui!

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

Prende moltiplicare come Be aggiungere come s. I due ingressi numerici sono separati da virgole.


1
Bello! Possiamo avere una spiegazione?
Emigna,

Grazie per la risposta, (+1). Può gestire input di grandi numeri?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀dovrebbe essere in grado di gestire numeri arbitrari
Blue

Non riesco a testare il tuo codice perché il Web è bloccato poiché vìola la politica di utilizzo di Internet dei miei genitori. T_T
Anastasiya-Romanova 秀

Qualcosa del genere: pagina Web bloccata! Hai tentato di accedere a una pagina Web che viola le tue norme sull'utilizzo di Internet. URL: pyke.catbus.co.uk/?code=RE%60DltImbRoKr%29oh&input=B%0A21%2C+111&warnings=0 Categoria: Non classificato
Anastasiya-Romanova 秀

8

JavaScript (ES6), 59

Funzione ricorsiva, il formato di input è personalizzato per semplificare la chiamata ricorsiva:

  • operatore: '+' o '*'
  • operandi: matrice di due valori
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)
})  
  


Grazie per la risposta, (+1). Può gestire input di grandi numeri?
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀 fino al limite del formato numerico javascript, 53 bit di precisione (17 cifre decimali)
edc65

8

Python 2, 60 byte

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

Input è una stringa come 81+31, output è una tupla di una stringa singleton e un contatore (es ('4', 2).

Provalo su Ideone .


Se si accetta l'input come una matrice di stringhe e una singola stringa, ad esempio, è f(['81', '31'],'+')possibile salvare un ulteriore byte, ma sembra che si stiano allungando un po 'troppo le regole ...
Dennis


... nel qual caso andrei persino lontano e prenderei in considerazione la possibilità di passare operator.addo operator.mulrispettivamente;)
Tobias Kienzler,

7

Pyth, 16

eJ.uvjhQ`N.vQ)lJ

Accetta input come "+ 123 12"per addizione e "* 123 12"per moltiplicazione. Uscite come result<linefeed>steps.

Provalo qui o esegui una Test Suite , ma nota che questo si basa su eval, quindi solo la variante di aggiunta funzionerà nell'interprete online. La moltiplicazione funziona correttamente con l'interprete offline.

Questo utilizza la funzione di riduzione cumulativa per creare un elenco di risultati intermedi, quindi per "+ 351 14568"noi [14919, 24, 6]. Questo funziona perché i numeri a una cifra sono un punto fisso dell'aggiunta e della moltiplicazione Anastasiya. Quindi otteniamo solo l'ultimo elemento dell'array e la lunghezza dell'array.

Questo funzionerà per numeri arbitrariamente grandi, almeno fino a quando non si esaurisce la memoria.


7

R, 175 167 164 140 134 127 126 119 byte

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

ifelseè tornato ! Si !
Nop

Utilizzo:

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

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

Grazie mille a @plannapus per il golf di 24 byte!
-7 byte grazie a una buona idea di @Vlo !


Sì, per favore aggiungi delle spiegazioni poiché adoro R! Questa è la mia seconda lingua dopo VBA. (+1)
Anastasiya-Romanova 秀

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

@plannapus: davvero bello! Molte grazie !
Frédéric,

1
@ Frédéric buon uso di strtoi! 4 byte in più mi hai battuto.
plannapus,

1
Sembra che puoi golf ulteriormente fuori da un byte includendo la definizione di O all'interno dell'assegnazione di x nella prima operazione: x = (O = switch (S, sum, `*`)) (G, D) ;.
rturnbull,

6

05AB1E , 20 15 byte

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

Spiegazione

[       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

L'operatore è 1 per addizione, 0 per moltiplicazione.

Provalo online


Grazie per la risposta, (+1). Può gestire input di grandi numeri?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Non vedo un motivo per cui no. Hai un esempio?
Emigna,

Il tuo programma è stato testato per quel tipo di input, quindi è perfetto :)
Anastasiya-Romanova 秀

6

Gelatina , 11 10 byte

Dj⁹VµÐĿḊĖṪ

L'input è una coppia di numeri e uno +o ×.

Provalo online! o verifica tutti i casi di test .

Come funziona

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

Codice macchina ARM, 48 byte

Discarica esadecimale:

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

Questa funzione non dipende da alcuna chiamata di sistema o funzione di libreria. Questo è il codice Thumb-2, che è una codifica di istruzioni a lunghezza variabile (2 o 4 byte) per ARM a 32 bit. Pertanto, il valore massimo che può elaborare è 2 ^ 32-1. 2 byte potrebbero essere eliminati se non fossero conformi agli AAPCS ( 46 byte ), poiché all'inizio non avremmo dovuto impilare i registri.

Ungolfed assembly (sintassi 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

Test di script 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 caratteri

Un approccio un po 'diverso da quello di @ 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)}

Rientrato, con nuove righe:

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
    }

La riga 4 probabilmente ha bisogno di più spiegazioni:

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

Casi test:

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

Abbastanza sfortunato sei arrivato in ritardo con questa risposta, ma hai il mio voto. Grazie per averlo creato in R.
Anastasiya-Romanova 秀

Perché sfortunato?
plannapus,

Perché se tu fossi venuto per primo, allora avresti ottenuto più voti
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Abbastanza giusto :)
plannapus

Punti bonus per avere fsia il nome della funzione che uno dei suoi argomenti :)
JDL,

4

Ottava, 85 byte MATLAB, 123, 114, 105, 94 byte

Ha deciso di tradurre questo in Octace, per sfruttare l'indicizzazione diretta e incrementare le capacità. Prende l'input nel modulo:, f(a,operator)dove a = [number1, number2], operator==1fornisce il prodotto e operator==2fornisce la somma.

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

spiegazioni:

g={@prod,@sum}{o} : Sceglie la funzione, il prodotto o la somma appropriati e lo assegna a g

x=g(a) prende la somma o il prodotto degli input

i=1; ... i++ : Incrementatore per contare il numero di passaggi

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

Rimosse due nuove righe, uno spazio e posizionato entrambi i numeri di input in un vettore anziché in argomenti separati. Ciò ha consentito di risparmiare 9 byte, grazie a pajonk! Rimosso k=@(x)...per salvare altri 11 byte grazie a becher =) Infine, tradotto tutto in Octave per salvare altri 9 byte ...


4

Java, 164 159 146 byte

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

Il primo argomento è solo il contatore, sempre 0

Il secondo argomento è il metodo, 0 per ADD e 1 per MULTIPLY.

Il terzo argomento è un array di stringhe, che contiene i valori da aggiungere / moltiplicare.

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

grazie a @Kevin Cruijssen per aver tagliato alcuni byte.

grazie a @milk per la rasatura di 5 byte.

Programma di test

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

Bello, più corto della mia risposta Java . Tuttavia, dovresti anche stampare i passaggi e la risposta che al momento manca nella tua risposta.
Kevin Cruijssen,

@KevinCruijssen Ahh. È noioso .. Ora proverò a risolverlo.
Shaun Wild,

A proposito, puoi golf un po 'la tua risposta attuale. m==0può essere m<1e Integer.parseIntpuò essere Integer.decode.
Kevin Cruijssen,

Non uso molto Java, ma alla fine hai bisogno di quel jvar? L'allineamento (r+"")due volte sembra che dovrebbe radere qualche byte.
latte

1
Non possiamo cambiare i miei post in futuro? Se vuoi suggerire una modifica, fallo nei commenti.
Shaun Wild

3

Gelatina , 17 byte

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

Provalo online!

Dati argomenti come x y 1questi, calcola la somma di Anastasiya x (+) y.

Dato argomenti del genere x y 0, questo calcola il prodotto Anastasiya x (*) y.

L'output è dato come [number of steps, result].


Grazie per la risposta, ma l'output del programma non contiene il numero di passaggi richiesti? Mi sto perdendo qualcosa qui?
Anastasiya-Romanova 秀

3

Python, 160 146 129 byte

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

Pubblicherà presto una spiegazione.

L'input è nella forma 12+12o 5*35(con normale +e *segni) e presuppone che questi siano gli unici due operatori.

Può gestire input di numeri grandi quanto la memoria del tuo computer lo consente.

Sono quasi sicuramente fiducioso che questo possa essere ulteriore.

EDIT: 16 31 byte salvati grazie a @Copper.


Grazie per la risposta, (+1). Può gestire input di grandi numeri?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Uhmmm ... Sono abbastanza sicuro che possano. Potete darmi esempi di input di grandi dimensioni? Proverò a calcolare da quelli.
clismique,

Forse: 3218753647208435810122106 * 29349566754?
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀 Sì, ha funzionato in ~ 0,5 secondi, non è stato correttamente programmato.
clismique,

È possibile passare "+" if "+" in s else "*"a "*+"["+"in s], quindi invece di assegnarlo a t, è sufficiente aggiungerlo in linea nella execchiamata.
Rame

3

R, 110 byte

Usando lo splitter di @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

Produzione

> 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

modifica: non posso contare.


R è fantastico perché ci consente di abbreviare la sua funzione, qualcosa di prezioso nel golf. (+1)
Anastasiya-Romanova 秀

3

Clojure 126 byte

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

La funzione si chiama così:

(f + 81 31)

Ecco il codice 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])

Ricorda che Clojure è ancora nuovo per me, quindi questa non è probabilmente la soluzione migliore. La sfida è stata comunque divertente. Inoltre, il codice veniva eseguito con numeri molto grandi senza alcuna difficoltà.


È molto tardi, ma puoi ridurre la maggior parte degli spazi.
clismique il

2

Perl 6 53 byte

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

Dal momento che ( 12, &[+], 123 )è accettabile per l'input, posso ottenerlo fino a 53 byte.
( &[+]è l'abbreviazione per la &infix:<+>quale è una "riverenza" per l'operatore di aggiunta numerica dell'infisso)

Se il secondo argomento dovesse essere una stringa (+)sarebbe 87 byte

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

Spiegazione:

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

Uso normale:

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

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)

Una funzione anonima che accetta input tramite argomento di un primo operando a, un operatore o( '+'o '*') e un secondo operando be restituisce un elenco del modulo [result, steps].

Come funziona

La funzione anonima crea una stringa concatenando gli operandi con l'operatore tra di loro e quindi la valuta; questo è il primo passo descritto nella domanda. Quindi, questo valore e l'operatore vengono passati alla funzione ricorsiva g. Qui, viene utilizzato un contatore i, che viene incrementato per ogni chiamata ricorsiva. Se l'ingresso è inferiore a 10, deve essere stata raggiunta una singola cifra, quindi questa e iviene restituita. In caso contrario, l'input viene convertito in una stringa e ogni carattere in questa stringa viene unito all'operatore, fornendo il calcolo desiderato, che viene quindi valutato e passato ricorsivamente alla funzione.

Provalo su Ideone


(+1) mentre aspetto la spiegazione :)
Anastasiya-Romanova 秀

2

Groovy, 102 byte

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

Spiegazione

Basato sull'eccellente soluzione di @Sean Bean per Java.

  • p: La chiusura (funzione, lambda, qualunque cosa) che implementa la soluzione
  • t: La profondità della chiamata corrente (numero di iterazioni) pdeve essere sempre invocata cont=1
  • m: L'operazione da eseguire, 0per "aggiungere", 1per "moltiplicare"
  • d: L'elenco di operandi, ogni operando è un oggetto String
  • e: Gli elementi di d, ciascuno convertito in un numero intero
  • r: La somma o il prodotto di e, a seconda dell'operazionem
  • dichiarazione dei risultati, a partire da r > 9:
    • Se a più cifre ( r > 9), reinvocare, aumentare la profondità te convertire rin un elenco di stringhe di cifre (e restituire il risultato).
    • Se a cifra singola, restituisce re tcome un elenco.

Programma di test

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

risultati

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

2

Haskell, 76 70 byte

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

Restituisce un elenco di due elementi con il risultato e il numero di passaggi. Funziona per numeri arbitrari di grandi dimensioni. Esempio di utilizzo: (351#14568)(+)-> [6,3].

Modifica: grazie a @BlackCap per 6 byte.


È possibile sostituire (-48+).fromEnumconread.pure
BlackCap

2

R, 91 byte

Usando il codice di @ Vlo, che utilizza lo splitter di @ plannapus, e alcune idee che ho generato giocando a golf la risposta di @ Frédéric, questa è la risposta R più breve di sempre. (Un numero insolitamente elevato di risposte R qui oggi ...)

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

Fondamentalmente, ciò richiede che l'input per l'operatore sia sumper (+) o prodper (*). Secondo le regole della sfida, questo sembra essere a posto.

Con rientro:

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

Le principali differenze rispetto alla risposta di @ Vlo sono:

  1. Invece di usare Reduce, facciamo affidamento sul fatto che l'argomento input sia una funzione e lo chiamiamo esplicitamente. (Sì, per funzioni che sono oggetti di prima classe!)
  2. Invece di inizializzare una nuova variabile come nostro contatore, abusiamo dei builtin e dell'uso di R T, che valuta TRUE(alias 1), ma poiché non è una variabile riservata, possiamo modificarla. Così T+Tè 2. Quindi lo usiamo come nostro contatore.
  3. Invece di catinserire l'output, lo restituiamo semplicemente come vettore con c. Oltre a salvare due byte, il fatto che l'output sia forzato in un vettore garantisce che Tsia di classe numeric. Se usiamo cate Tnon è stato incrementato, otteniamo un output errato come 1 TRUE.

si può ristrutturare il whileciclo come segue, cambiando Fdi essere qualcos'altro al nome evitano conflitti: 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)}}. È incredibile quanti trucchi per il golf R abbiamo inventato negli ultimi anni :)
Giuseppe

@Giuseppe Bella ristrutturazione! Non riesco a trovare il meta consenso al momento, ma sono ragionevolmente fiducioso che l'uso del trucco Te il Fcontro all'interno di una funzione non sia effettivamente valido, poiché significa che la funzione può essere chiamata solo una volta. Quindi questa risposta (e molti altri miei!) Non sono validi, a meno che non ci sia un esplicito rm(T)alla fine. Continuerò a cercare quel meta post in modo da essere sicuro di non averlo solo immaginato.
rturnbull,

Credo che il trucco Te Fsia perfettamente valido fintanto che non si modifica To Fnell'ambiente globale. per esempio, f=function(){T=T+1;T}ritorna costantemente 2. Penso che questo sia il meta post a cui ti riferisci.
Giuseppe,

@Giuseppe Ah sì, hai ragione su entrambi i fronti. Grazie!
rturnbull,

1

Rubino, 55 byte

Chiamata ricorsiva. Utilizzato per essere molto diverso dalla risposta JavaScript di @ edc65 ma quando l'ho ottimizzato alla fine è diventato una porta diretta sviluppata quasi indipendentemente dalla loro risposta, meno un'ottimizzazione finale che comporta la verifica del risultato valutato invece della lunghezza dell'elenco di operandi passati , che mi ha permesso di superare il numero di byte.

L'input è una stringa che rappresenta l'operatore e un array che contiene gli operandi.

Provalo online.

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

Il risultato è corretto, ma il numero di passaggi necessari per ottenere un valore a singola cifra non è corretto. Potresti correggere il tuo codice?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 ah, hai ragione. La mia vecchia logica richiedeva che iniziasse i=0e mi sono quasi dimenticato di refactoring.
Valore inchiostro

1

Perl, 38 byte

Include +2 per -ap

Esegui con l'input su STDIN e gli spazi attorno all'operatore:

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

L'output è composto da cifre e passi separati da +A

amath.pl:

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

Se l'output dei passaggi in unario va bene, questa versione da 35 byte funziona meglio:

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

1

Mathematica, 105 94 byte

Codice.

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

Uso.

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

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

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

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

Spiegazione.

Le due funzioni x(per (+)) e y(per (*)) vengono create contemporaneamente sostituendo i parametri fe oin

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

con i loro valori appropriati. Perché x, fdiventa #1 + #2e odiventa Plus; poiché y, rispettivamente diventano #1 #2e Times. Riscrivere la funzione xper l'ultima parte della spiegazione:

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 byte

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

Utilizza long(valore massimo di 2 63 -1). Se intinvece usasse (valore massimo di 2 31 -1) sarebbe solo 1 byte in meno ( 191 byte ):

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

Molto probabilmente può essere giocato a golf un po 'di più. Dover stampare i passaggi così come la risposta per entrambi gli operatori richiede alcuni byte.
Usa 0 (per (+)) e 1 (per (*)).

Codice non testato e test:

Provalo qui.

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

Produzione:

4,2
6,3
8,3
0,2
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.