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:
- El resultado de
12 + 123
es 135. - 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:
- El resultado de
12 * 123
es 1476. - Multiplica todos los dígitos de 1476 que obtenemos
1 * 4 * 7 * 6 = 168
. - Multiplica nuevamente todos los dígitos de 168 que obtenemos
1 * 6 * 8 = 48
. - Multiplica nuevamente todos los dígitos de 48 que obtenemos
4 * 8 = 32
. - 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:
- La operación del proceso de suma repetida para obtener un valor único es
12 (+) 123 = 9
. - 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 (+) b
o 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 código de golf , 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.
fuente
Respuestas:
Dyalog APL ,
33323029 bytesEsto 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}.TryAPL en línea! (
⍎
ha sido emuladoe
por 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¨⍕⊃⍵}⍣≡⍺⍺/⍺⍵} 31
y21 ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/e¨⍕⍵}⍣=⍵⍺⍺⍨⍺} 111
.fuente
⎕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³⁴.+{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(+)
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.(+)
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.Haskell, 108 bytes
Define la función
#
que primero tomaa
yb
y entonces el operadoro
. Dato curioso: ¡esto funciona con cualquier operador (en realidad, cualquier función) que desee!fuente
Integer
tipo de Haskell no tiene límites.Pyke, 16 bytes
Pruébalo aquí!
Toma multiplicar como
B
y agregar comos
. Las dos entradas numéricas están separadas por comas.fuente
JavaScript (ES6), 59
Función recursiva, el formato de entrada está diseñado para simplificar la llamada recursiva:
Prueba
fuente
Python 2, 60 bytes
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 .
fuente
f(['81', '31'],'+')
se puede guardar un byte adicional, pero eso se siente como estirar demasiado las reglas ...operator.add
ooperator.mul
respectivamente;)Pyth, 16
Toma datos como
"+ 123 12"
para sumar y"* 123 12"
multiplicar. Salidas comoresult<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.
fuente
R,
175167164140134127126119 bytesSin golf:
ifelse
está de vuelta ! Si!Nop
Uso:
¡Muchas gracias a @plannapus por jugar 24 bytes!
-7 bytes gracias a una buena idea de @Vlo !
fuente
strtoi
! 4 bytes más me has derrotado.05AB1E ,
2015 bytesExplicación
El operador es 1 para la suma, 0 para la multiplicación.
Pruébalo en línea
fuente
Jalea ,
1110 bytesLa 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
fuente
Código de máquina ARM, 48 bytes
Volcado hexadecimal:
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):
Prueba de script en C:
fuente
R,
130124 caracteresUn enfoque algo diferente al de @ Frédéric :
Sangrado, con nuevas líneas:
La línea 4 probablemente necesita más explicaciones:
Casos de prueba:
fuente
f
sido tanto el nombre de la función como uno de sus argumentos :)Octava, 85 bytes
MATLAB, 123, 114, 105, 94 bytesDecidí traducir esto a Octace, para aprovechar la indexación directa y aumentar las capacidades. Toma la entrada en el formulario:,
f(a,operator)
wherea = [number1, number2]
, yoperator==1
da el producto, yoperator==2
da la suma.Explicaciones:
g={@prod,@sum}{o}
: Elige la función, el producto o la suma apropiados y lo asigna ag
x=g(a)
toma la suma o producto de las entradasi=1; ... i++
: Incrementador para contar el número de pasosSe 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 ...fuente
Java,
164159146 bytesEl 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
Gracias a @Kevin Cruijssen por cortar algunos bytes.
gracias a @milk por afeitar 5 bytes.
Programa de prueba
fuente
m==0
puede serm<1
yInteger.parseInt
puede serInteger.decode
.j
var al final? La alineación(r+"")
dos veces parece que afeitaría unos pocos bytes.Jalea , 17 bytes
Pruébalo en línea!
Dados argumentos como
x y 1
, esto calcula la suma de Anastasiyax (+) y
.Dados argumentos como
x y 0
, esto calcula el producto Anastasiyax (*) y
.La salida se da como
[number of steps, result]
.fuente
Python,
160146129 bytesPublicaremos una explicación pronto.
La entrada es en forma
12+12
o5*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:
1631 bytes guardados gracias a @Copper.fuente
"+" if "+" in s else "*"
a"*+"["+"in s]
, y luego, en lugar de asignarlot
, simplemente agréguelo en línea en laexec
llamada.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)}
Salida
editar: no puedo contar.
fuente
Clojure 126 bytes
La función se llama así:
Aquí está el código sin golf:
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.
fuente
Perl 6 53 bytes
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 bytesExplicación:
Prueba:
Uso normal
fuente
Python 2,
10797 bytesUna función anónima que toma entrada a través del argumento de un primer operando
a
, un operadoro
('+'
o'*'
) y un segundo operandob
, 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í,i
se usa un contador , que se incrementa para cada llamada recursiva. Si la entrada es menor que10
, se debe haber alcanzado un solo dígito, por lo quei
se 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
fuente
Groovy, 102 bytes
Degolfed
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ónt
: La profundidad de la llamada actual (número de iteraciones)p
siempre debe invocarse cont=1
m
: La operación a realizar,0
para "agregar",1
para "multiplicar"d
: La lista de operandos, cada operando es un objeto Stringe
: Los elementos ded
, cada uno convertido a un enteror
: La suma o producto dee
, dependiendo de la operaciónm
r > 9
:r > 9
), vuelva a invocar, incrementando la profundidadt
y convirtiéndolar
en una lista de cadenas de dígitos (y devuelva el resultado).r
yt
como una lista.Programa de prueba
Resultados
fuente
Haskell,
7670 bytesDevuelve 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.
fuente
(-48+).fromEnum
conread.pure
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 ...)
De manera crucial, esto requiere que la entrada para el operador sea
sum
para (+) oprod
para (*). Según las reglas del desafío, esto parece estar bien.Con sangría:
Las principales diferencias con la respuesta de @ Vlo son:
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!)T
, que se evalúa comoTRUE
(aka1
), pero como no es una variable reservada, podemos modificarla. AsíT+T
es2
. Entonces usamos eso como nuestro contador.cat
la salida, simplemente la devolvemos como un vector conc
. Además de guardar dos bytes, el hecho de que la salida se fuerce a un vector garantiza queT
sea de clasenumeric
. Si usamoscat
, yT
no se ha incrementado, obtenemos resultados erróneos como1 TRUE
.fuente
while
bucle de la siguiente manera, el cambio deF
ser 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 :)T
y elF
contador 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ícitorm(T)
al final. Voy a seguir buscando esa meta publicación para estar seguro de que no solo la soñé.T
yF
es perfectamente válido siempre que no lo modifiqueT
oF
en el entorno global. por ejemplo,f=function(){T=T+1;T}
regresa constantemente2
. Creo que esta es la meta publicación a la que te refieres.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.
fuente
i=0
y me olvidé cuando refactorizaba.Perl, 38 bytes
Incluye +2 para
-ap
Ejecute con la entrada en STDIN y espacios alrededor del operador:
La salida es dígito y pasos separados por
+A
amath.pl
:Si la salida de los pasos en unary está bien, esta versión de 35 bytes funciona mejor:
fuente
Mathematica,
10594 bytesCódigo.
Uso.
Explicación.
Las dos funciones
x
(para (+)) yy
(para (*)) se crean al mismo tiempo reemplazando los parámetrosf
yo
encon sus valores apropiados Porque
x
, sef
vuelve#1 + #2
y seo
vuelvePlus
; paray
, respectivamente, se convierten en#1 #2
yTimes
. Reescribiendo la funciónx
para la última parte de la explicación:fuente
Java 7,
203195192 bytesUtiliza
long
(valor máximo de 2 63 -1). Si usaría en suint
lugar (valor máximo de 2 31 -1), solo sería 1 byte menos ( 191 bytes ):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í
Salida:
fuente