¿Cómo funcionan las matemáticas en el mundo de Anastasiya?


44

Antecedentes:

Matemáticas de operación estándar como la suma y la multiplicación básicas en el mundo real funcionan así:

12 + 123 = 135

y

12 * 123 = 1476

¡Eso no es interesante y aburrido! Muchas escuelas ya están interpretando esto como práctica, práctica, práctica de algoritmos formales. Eso implica una dieta matemática bastante rígida y aburrida y no es lo que se pretende en este desafío. Prepárate para divertirte en nuestro querido sitio.

Considere el proceso de sumar dos números enteros positivos, luego agregue nuevamente todos los dígitos de su resultado. Repitiendo con la suma hasta que solo se obtenga un solo dígito. Por ejemplo:

  1. El resultado de 12 + 123es 135.
  2. Sumando todos los dígitos de 135 que obtenemos 1 + 3 + 5 = 9.

El número de pasos necesarios para obtener un valor de un solo dígito 9 en esta suma repetida es 2.

Al igual que con el proceso anterior de la suma, la multiplicación de dos números enteros positivos sigue el mismo proceso. Multiplique todos los dígitos de su resultado y luego repita este proceso hasta que solo quede un solo dígito. Tome el ejemplo anterior:

  1. El resultado de 12 * 123es 1476.
  2. Multiplica todos los dígitos de 1476 que obtenemos 1 * 4 * 7 * 6 = 168.
  3. Multiplica nuevamente todos los dígitos de 168 que obtenemos 1 * 6 * 8 = 48.
  4. Multiplica nuevamente todos los dígitos de 48 que obtenemos 4 * 8 = 32.
  5. Multiplica una vez más todos los dígitos de 32 que obtenemos 3 * 2 = 6.

El número de pasos necesarios para obtener un valor de un solo dígito 6 esta multiplicación repetida es 5.

Por el bien de este desafío y para evitar cualquier mal uso de las anotaciones matemáticas, presento estas dos anotaciones ficticias: (+)y (*), pero puede usar cualquier notación que desee , que funciona de la siguiente manera:

  1. La operación del proceso de suma repetida para obtener un valor único es 12 (+) 123 = 9.
  2. La operación del proceso de multiplicación repetida para obtener un solo valor es 12 (*) 123 = 6.

Desafío:

El desafío es escribir un programa o una función que pueda realizar ambas operaciones como se explica en la sección de antecedentes: (+)y (*).

Entrada:

Las entradas del programa o la función son dos enteros positivos y una operación, (+)y (*). El formato de la entrada es una elección arbitraria del programador . Puede dar formato a la entrada, por ejemplo, a (+) bo F(a, (+), b), o cualquier formato que desee.

Salida:

La salida del programa o la función debe contener el resultado de la operación y la cantidad de pasos necesarios con el formato de estilo libre que desee.

Casos de prueba (ignore el formato de entrada y salida):

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

Reglas generales:

  • Este es el , por lo que la respuesta más corta en bytes gana el desafío.
    No dejes que esolangs te desanime de publicar una respuesta con idiomas regulares. Disfrute de este desafío proporcionando una respuesta lo más breve posible con su lenguaje de programación. Si publica una respuesta inteligente y una explicación clara, su respuesta será apreciada (de ahí los votos positivos) independientemente del lenguaje de programación que utilice.
  • Se aplican reglas estándar para su respuesta, por lo que puede usar STDIN / STDOUT, funciones / método con los parámetros adecuados, programas completos, etc. La elección es suya.
  • Si es posible, su programa puede manejar adecuadamente grandes números. Si no, eso estará bien.

¡¡Que empiece el juego!!


La parte de adición repetida ( raíz digital ) es esencialmente un duplicado de codegolf.stackexchange.com/q/1128/194
Peter Taylor

44
Gran primera pregunta! Y reconozco el formato de las reglas generales y las oraciones de mis propias Preguntas. ;)
Kevin Cruijssen

44
@KevinCruijssen Sí. Eso es correcto. Como no tiene derechos de autor, lo duplico sin su permiso. Jejeje: D
Anastasiya-Romanova 秀

44
@ Anastasiya-Romanova 秀 "sin derechos de autor"? En el siglo XXI? No; todo aquí es CC-BY-SA 3.0. El permiso se otorga cuando se envía el contenido. Verifique el pie de página del sitio.
Mindwin

1
@ BradGilbertb2gills Sí, por supuesto. Por cierto, se afirma en la publicación. Cita: "El formato de la entrada es una elección arbitraria del programador".
Anastasiya-Romanova 秀

Respuestas:


11

Dyalog APL , 33 32 30 29 bytes

Esto extiende APL para incluir la notación de prefijo +/A n₁ n₂y ×/A n₁ n₂. (De hecho, puede usar cualquier operación a la izquierda de la /A.) Devuelve una lista de {resultado, recuento de repetición}.

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

A←{definir una función de orden superior en términos de función de la izquierda ⍺⍺y argumento de la derecha

(⊃,≢) el primer elemento de, seguido por el recuento de

⍺⍺{la función suministrada ( +/por suma o ×/por producto) alimentada a la función de orden superior

los elementos únicos de

⍵,⍨ el argumento anexado a

⍺⍺ la función alimentada aplicada a

⍎¨ la evaluación de cada personaje de

la representación del personaje de

⊃⍵ el primer elemento del argumento

}⍣≡ aplicado repetidamente hasta que el resultado sea idéntico al argumento, comenzando con

⍺⍺⍵la función alimentada originalmente ( +/o ×/) aplicada al argumento original

} [fin de la definición de función de orden superior]

TryAPL en línea! ( ha sido emulado epor razones de seguridad).

Gracias a @ngn por guardar un byte.


0 bytes (en broma)

Dyalog APL ya tiene soporte completo para las matemáticas de Anastasiyan; en lugar de (+)y (×), usa +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}y ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}.

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


Gracias por la respuesta, (+1). ¿Puede manejar entradas de gran número?
Anastasiya-Romanova 秀

1
Si establece ⎕FR←1287(es decir, usa IEEE 754-2008 de 128 bits decimal F representación de punto de referencia R ) y ⎕PP←34(es decir, usa la resolución P rint P de 34 caracteres ), puede usar enteros por debajo de 10³⁴.
Adám

Hmm, a pesar de que tiene soporte completo, ¿no son +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}y ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}siguen siendo bastantes bytes? Estoy confundido acerca de cómo esto es 0 bytes ..: S
Kevin Cruijssen

3
@KevinCruijssen El OP permite cualquier notación de entrada. Entonces, si un idioma es compatible con la anotación matemática Anastasiyan predeterminada, el glifo multi-char (+)sería el Anastasiyan +. Dyalog APL es compatible con las matemáticas de Anastasiyan, pero utiliza un glifo multi-char diferente, así como *significa potencia y necesitas ×multiplicación, mientras que /significa replicación y necesitas ÷división.
Adám

1
@ Adám Ah ok, eso tiene sentido. Es un poco doblegar las reglas de OP, pero no romperlas. Todavía es bastante extraño que en lugar de (+)tener +{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}como entrada, pero dado que OP de hecho declaró que cualquier formato de entrada funcionará, puede usar la función como parámetro. Hmm, me pregunto si esto también es posible en otros lenguajes de programación que admiten funciones como entrada.
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

Define la función #que primero toma ay by entonces el operador o. Dato curioso: ¡esto funciona con cualquier operador (en realidad, cualquier función) que desee!


Gracias por la respuesta, (+1). ¿Puede manejar entradas de gran número?
Anastasiya-Romanova 秀

44
@ Anastasiya-Romanova 秀 Sí, puede manejar números tan grandes como su RAM ya que el Integertipo de Haskell no tiene límites.
ThreeFx

8

Pyke, 16 bytes

RE`DltImbRoKr)oh

Pruébalo aquí!

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

Toma multiplicar como By agregar como s. Las dos entradas numéricas están separadas por comas.


1
¡Agradable! ¿Podemos obtener una explicación?
Emigna

Gracias por la respuesta, (+1). ¿Puede manejar entradas de gran número?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀debería poder manejar números arbitrarios
Azul

No puedo probar su código porque la web está bloqueada porque viola la política de uso de Internet de mis padres. T_T
Anastasiya-Romanova 秀

Algo como esto: ¡Página web bloqueada! Intentó acceder a una página web que infringe su política de uso de Internet. URL: pyke.catbus.co.uk/?code=RE%60DltImbRoKr%29oh&input=B%0A21%2C+111&warnings=0 Categoría: Sin clasificar
Anastasiya-Romanova 秀

8

JavaScript (ES6), 59

Función recursiva, el formato de entrada está diseñado para simplificar la llamada recursiva:

  • operador: '+' o '*'
  • operandos: conjunto de dos valores
f=(o,v,s=1,t=eval(v.join(o)))=>t>9?f(o,[...t+''],s+1):[t,s]

Prueba

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


Gracias por la respuesta, (+1). ¿Puede manejar entradas de gran número?
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀 hasta el límite del formato numérico javascript, 53 bits de precisión (17 dígitos decimales)
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)

De entrada es una cadena como 81+31, la salida es una tupla de una cadena singleton y un contador (por ejemplo, ('4', 2).

Pruébalo en Ideone .


Si se permite la entrada como una matriz de cadenas y se permite una sola cadena, por ejemplo, f(['81', '31'],'+')se puede guardar un byte adicional, pero eso se siente como estirar demasiado las reglas ...
Dennis


... en cuyo caso incluso iría tan lejos y consideraría pasar operator.addo operator.mulrespectivamente;)
Tobias Kienzler

7

Pyth, 16

eJ.uvjhQ`N.vQ)lJ

Toma datos como "+ 123 12"para sumar y "* 123 12"multiplicar. Salidas como result<linefeed>steps.

Pruébelo aquí o ejecute un Test Suite , pero tenga en cuenta que esto depende de eval, por lo que solo la variante de adición funcionará en el intérprete en línea. La multiplicación funciona correctamente con el intérprete fuera de línea.

Esto usa la función de reducción acumulativa para crear una lista de resultados intermedios, así que para "+ 351 14568"obtener [14919, 24, 6]. Esto funciona porque los números de un solo dígito son un punto fijo de la suma y multiplicación de Anastasiya. Luego solo obtenemos el último elemento de la matriz, así como la longitud de la matriz.

Esto funcionará para números arbitrariamente grandes, al menos hasta que se quede sin memoria.


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

Sin golf:

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

ifelseestá de vuelta ! Si!
Nop

Uso:

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

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

¡Muchas gracias a @plannapus por jugar 24 bytes!
-7 bytes gracias a una buena idea de @Vlo !


Sí, por favor agregue explicaciones ya que amo a R! Este es mi segundo idioma después de VBA. (+1)
Anastasiya-Romanova 秀

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

@plannapus: ¡Muy bien! Muchas gracias !
Frédéric

1
@ Frédéric buen uso de strtoi! 4 bytes más me has derrotado.
plannapus

1
Parece que puede jugar golf más lejos de un byte al incluir la definición de O dentro de la asignación de x en la primera operación: x = (O = interruptor (S, suma, `*`)) (G, D) ;.
rturnbull

6

05AB1E , 20 15 bytes

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

Explicación

[       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

El operador es 1 para la suma, 0 para la multiplicación.

Pruébalo en línea


Gracias por la respuesta, (+1). ¿Puede manejar entradas de gran número?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 No veo una razón por la que no. ¿Tienes un ejemplo?
Emigna

Su programa ha sido probado para ese tipo de entradas, por lo que es perfecto :)
Anastasiya-Romanova 秀

6

Jalea , 11 10 bytes

Dj⁹VµÐĿḊĖṪ

La entrada es un par de números y o +o ×.

Pruébalo en línea! o verificar todos los casos de prueba .

Cómo funciona

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

Código de máquina ARM, 48 bytes

Volcado hexadecimal:

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

Esta función no depende de ninguna llamada al sistema o funciones de la biblioteca. Este es el código Thumb-2, que es una codificación de instrucciones de longitud variable (2 o 4 bytes) para ARM de 32 bits. Por lo tanto, el valor máximo que puede procesar es 2 ^ 32-1. Se podrían descartar 2 bytes si no se ajustaba al AAPCS ( 46 bytes ), ya que no tendríamos que apilar registros al principio.

Ensamblaje no protegido (sintaxis 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

Prueba de script en 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 caracteres

Un enfoque algo diferente al de @ 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)}

Sangrado, con nuevas líneas:

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 línea 4 probablemente necesita más explicaciones:

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

Casos de prueba:

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

Muy desafortunado llegaste tarde con esta respuesta, pero tienes mi voto a favor. Gracias por crear esto en R.
Anastasiya-Romanova 秀

¿Por qué desafortunado?
plannapus

Porque si hubieras venido primero, entonces tendrías más votos a favor
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Muy bien :)
plannapus

Puntos de bonificación por haber fsido tanto el nombre de la función como uno de sus argumentos :)
JDL

4

Octava, 85 bytes MATLAB, 123, 114, 105, 94 bytes

Decidí traducir esto a Octace, para aprovechar la indexación directa y aumentar las capacidades. Toma la entrada en el formulario:, f(a,operator)where a = [number1, number2], y operator==1da el producto, y operator==2da la suma.

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

Explicaciones:

g={@prod,@sum}{o} : Elige la función, el producto o la suma apropiados y lo asigna a g

x=g(a) toma la suma o producto de las entradas

i=1; ... i++ : Incrementador para contar el número de pasos

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

Se eliminaron dos líneas nuevas, un espacio y se colocaron ambos números de entrada en un vector en lugar de argumentos separados. Esto ahorró 9 bytes, gracias a pajonk! Eliminado k=@(x)...para guardar otros 11 bytes gracias a beaker =) Finalmente, tradujo todo a Octave para guardar otros 9 bytes ...


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

El primer argumento es solo el contador, siempre 0

El segundo argumento es el método, 0 para ADD y 1 para MULTIPLY.

El tercer argumento es una matriz de cadenas, que contiene los valores para agregar / multiplicar.

Sin golf

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

Gracias a @Kevin Cruijssen por cortar algunos bytes.

gracias a @milk por afeitar 5 bytes.

Programa de prueba

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

Agradable, más corto que mi respuesta de Java . Sin embargo, también se supone que debe imprimir los pasos, así como la respuesta que falta actualmente en su respuesta ..
Kevin Cruijssen

@KevinCruijssen Ahh. Eso es aburrido. Intentaré arreglar eso ahora.
Shaun Wild

Por cierto, puedes jugar un poco a tu respuesta actual. m==0puede ser m<1y Integer.parseIntpuede ser Integer.decode.
Kevin Cruijssen

No uso mucho Java, pero ¿necesitas esa jvar al final? La alineación (r+"")dos veces parece que afeitaría unos pocos bytes.
leche

1
¿No podemos cambiar mis publicaciones en el futuro? Si desea sugerir una edición, hágalo en los comentarios.
Shaun Wild

3

Jalea , 17 bytes

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

Pruébalo en línea!

Dados argumentos como x y 1, esto calcula la suma de Anastasiya x (+) y.

Dados argumentos como x y 0, esto calcula el producto Anastasiya x (*) y.

La salida se da como [number of steps, result].


Gracias por la respuesta, pero la salida de su programa no contiene el número de pasos necesarios. ¿Me estoy perdiendo de algo?
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

Publicaremos una explicación pronto.

La entrada es en forma 12+12o 5*35(con signos normales +y *), y supone que esos son los únicos dos operadores.

Puede manejar entradas numéricas tan grandes como lo permita la memoria de su computadora.

Estoy casi seguro de que esto puede ser más.

EDITAR: 16 31 bytes guardados gracias a @Copper.


Gracias por la respuesta, (+1). ¿Puede manejar entradas de gran número?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 Uhmmm ... estoy bastante seguro de que pueden. ¿Me puede dar ejemplos de entradas grandes? Trataré de calcular a partir de esos.
clismique

Tal vez: 3218753647208435810122106 * 29349566754?
Anastasiya-Romanova 秀

1
@ Anastasiya-Romanova 秀 Sí, funcionó en ~ 0.5 segundos, no lo cronometró correctamente.
clismique

Puede cambiar "+" if "+" in s else "*"a "*+"["+"in s], y luego, en lugar de asignarlo t, simplemente agréguelo en línea en la execllamada.
Cobre

3

R, 110 bytes

Usando el divisor de @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

Salida

> 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

editar: no puedo contar.


R es fantástico porque nos permite acortar su función, algo valioso en el golf. (+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)))))

La función se llama así:

(f + 81 31)

Aquí está el código sin golf:

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

Tenga en cuenta que Clojure todavía es nuevo para mí, por lo que probablemente esta no sea la mejor solución. El desafío fue divertido de todos modos. Además, el código se ejecutó con números muy grandes sin ninguna dificultad.


Esto es muy tarde, pero puede reducir la mayoría de los espacios allí.
clismique

2

Perl 6 53 bytes

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

Como ( 12, &[+], 123 )es aceptable para la entrada, puedo reducirlo a 53 bytes.
( &[+]es la abreviatura de lo &infix:<+>que es una "reverencia" al operador de adición de infijo numérico)

Si el segundo argumento tuviera que ser una cadena (+), sería 87 bytes

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

Explicación:

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

Prueba:

#! /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 normal

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

Una función anónima que toma entrada a través del argumento de un primer operando a, un operador o( '+'o '*') y un segundo operando b, y devuelve una lista del formulario [result, steps].

Cómo funciona

La función anónima crea una cadena concatenando los operandos con el operador entre ellos y luego la evalúa; Este es el primer paso descrito en la pregunta. Luego, este valor y el operador se pasan a la función recursiva g. Aquí, ise usa un contador , que se incrementa para cada llamada recursiva. Si la entrada es menor que 10, se debe haber alcanzado un solo dígito, por lo que ise devuelve. Si no, la entrada se convierte en una cadena y cada carácter en esta cadena se une con el operador, dando el cálculo deseado, que luego se evalúa y se pasa a la función de forma recursiva.

Pruébalo en Ideone


(+1) mientras espera la explicación :)
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]}

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

Explicación

Basado en la excelente solución de @Sean Bean para Java.

  • p: El cierre (función, lambda, lo que sea) que implementa la solución
  • t: La profundidad de la llamada actual (número de iteraciones) psiempre debe invocarse cont=1
  • m: La operación a realizar, 0para "agregar", 1para "multiplicar"
  • d: La lista de operandos, cada operando es un objeto String
  • e: Los elementos de d, cada uno convertido a un entero
  • r: La suma o producto de e, dependiendo de la operaciónm
  • declaración de resultado, comenzando con r > 9:
    • Si es de varios dígitos ( r > 9), vuelva a invocar, incrementando la profundidad ty convirtiéndola ren una lista de cadenas de dígitos (y devuelva el resultado).
    • Si es de un solo dígito, regrese ry tcomo una lista.

Programa de prueba

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

Resultados

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

Devuelve una lista de dos elementos con el resultado y el número de pasos. Funciona para grandes números arbitrarios. Ejemplo de uso: (351#14568)(+)-> [6,3].

Editar: Gracias a @BlackCap por 6 bytes.


Puede reemplazar (-48+).fromEnumconread.pure
BlackCap

2

R, 91 bytes

Usando el código de @ Vlo, que hace uso del divisor de @ plannapus, y algunas ideas que generé mientras jugaba la respuesta de @ Frédéric, esta es la respuesta R más corta hasta ahora. (Un número inusualmente grande de respuestas R aquí hoy ...)

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

De manera crucial, esto requiere que la entrada para el operador sea sumpara (+) o prodpara (*). Según las reglas del desafío, esto parece estar bien.

Con sangría:

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

Las principales diferencias con la respuesta de @ Vlo son:

  1. En lugar de usar Reduce, confiamos en que el argumento de entrada es una función, y simplemente lo llamamos explícitamente. (¡Sí, las funciones son objetos de primera clase!)
  2. En lugar de inicializar una nueva variable como nuestro contador, abusamos del uso y uso de R T, que se evalúa como TRUE(aka 1), pero como no es una variable reservada, podemos modificarla. Así T+Tes 2. Entonces usamos eso como nuestro contador.
  3. En lugar de obtener catla salida, simplemente la devolvemos como un vector con c. Además de guardar dos bytes, el hecho de que la salida se fuerce a un vector garantiza que Tsea ​​de clase numeric. Si usamos cat, y Tno se ha incrementado, obtenemos resultados erróneos como 1 TRUE.

se puede reestructurar el whilebucle de la siguiente manera, el cambio de Fser algo más para evitar conflictos de nombres: 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 increíble cuántos trucos de golf R hemos inventado en los últimos años :)
Giuseppe

@Giuseppe ¡Buena reestructuración! No puedo encontrar el meta consenso en este momento, pero estoy bastante seguro de que usar el truco Ty el Fcontador dentro de una función no es válido, ya que significa que la función solo se puede llamar una vez. Entonces esta respuesta (¡y varias de mis otras!) No son válidas, a menos que haya un explícito rm(T)al final. Voy a seguir buscando esa meta publicación para estar seguro de que no solo la soñé.
rturnbull

Creo que el truco Ty Fes perfectamente válido siempre que no lo modifique To Fen el entorno global. por ejemplo, f=function(){T=T+1;T}regresa constantemente 2. Creo que esta es la meta publicación a la que te refieres.
Giuseppe

@Giuseppe Ah, sí, tienes razón en ambos aspectos. ¡Gracias!
rturnbull

1

Ruby, 55 bytes

Llamada recursiva Solía ​​ser muy diferente de la respuesta de JavaScript de @ edc65, pero a medida que optimicé, eventualmente se convirtió en un puerto directo desarrollado casi independientemente de su respuesta, menos una optimización final que implica verificar el resultado evaluado en lugar de la longitud de la lista de operandos que se pasa , lo que me permitió superar su recuento de bytes.

La entrada es una cadena que representa al operador y una matriz que contiene los operandos.

Pruébalo en línea.

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

El resultado es correcto, pero el número de pasos necesarios para obtener un valor de un solo dígito es incorrecto. ¿Podrías rectificar tu código?
Anastasiya-Romanova 秀

@ Anastasiya-Romanova 秀 ah, tienes razón. Mi vieja lógica requería que comenzara i=0y me olvidé cuando refactorizaba.
Value Ink el

1

Perl, 38 bytes

Incluye +2 para -ap

Ejecute con la entrada en STDIN y espacios alrededor del operador:

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

La salida es dígito y pasos separados por +A

amath.pl:

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

Si la salida de los pasos en unary está bien, esta versión de 35 bytes funciona mejor:

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

1

Mathematica, 105 94 bytes

Código.

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

Explicación.

Las dos funciones x(para (+)) y y(para (*)) se crean al mismo tiempo reemplazando los parámetros fy oen

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

con sus valores apropiados Porque x, se fvuelve #1 + #2y se ovuelve Plus; para y, respectivamente, se convierten en #1 #2y Times. Reescribiendo la función xpara la última parte de la explicación:

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

Utiliza long(valor máximo de 2 63 -1). Si usaría en su intlugar (valor máximo de 2 31 -1), solo sería 1 byte menos ( 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);}

Lo más probable es que se pueda jugar un poco más. Sin embargo, tener que imprimir los pasos y la respuesta para ambos operadores requiere algunos bytes.
Utiliza 0 (para (+)) y 1 (para (*)).

Ungolfed y código de prueba:

Pruébalo aquí

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

Salida:

4,2
6,3
8,3
0,2
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.