Antecedentes
Los átomos aritméticos de Jelly se vectorizan automáticamente. De hecho, x + y está bien definido cuando x e y son números o matrices desiguales de números. El código fuente de Jelly implementa este comportamiento usando un vectorizador genérico, pero para este desafío, solo consideraremos la adición de enteros y matrices de enteros anidados.
Definiciones
Defina la profundidad de x como 0 si x es un número entero, como 1 si es un conjunto plano (posiblemente vacío) de enteros, y como n + 1 si contiene al menos un elemento de profundidad n y ningún elemento de profundidad k> n .
De esta manera, 1 tiene profundidad 0 , [] y [1] y [1, 1] tienen profundidad 1 , [[], []] y [[1], [1]] y [[1]] y [1 , []] tiene profundidad 2 , [1, [1, [1]]] tiene profundidad 3 , etc.
La operación x + y se define de la siguiente manera.
Si x e y tienen profundidad 0 , devuelve su suma.
Si X y Y tienen profundidades iguales pero positivos, aplicar de forma recursiva + a todos los artículos de x y los artículos correspondientes de y .
Si x y y tienen diferentes longitudes, añadir la cola de la matriz más tiempo para la matriz de sumas.
Devuelve el resultado.
Si la profundidad de x es estrictamente menor que la profundidad de y , aplique recursivamente + a x y todos los elementos de y , y devuelva el resultado.
Hacer lo contrario, si Y 's profundidad es estrictamente menor que x ' s.
Por ejemplo, considere la operación [1, [2, 3], [4]] + [[[10, 20], [30], 40, 50], 60] .
La profundidad del argumento izquierdo es 2 , mientras que la profundidad del argumento derecho es 3 , entonces calculamos [1, [2, 3], [4]] + [[10, 20], [30], 40, 50 ] y [1, [2, 3], [4]] + 60 .
[1, [2, 3], [4]] y [[10, 20], [30], 40, 50] tienen profundidad 2 , por lo que calculamos 1 + [10, 20] , [2, 3] + [30] y [4] + 40 .
1 + [10, 20] = [1 + 10, 1 + 20] = [11, 21]
[2, 3] + [30] = [2 + 30, 3] = [32, 3]
Tenga en cuenta que 3 permanece intacto, ya que no tiene un elemento coincidente.
[4] + 40 = [4 + 40] = [44]
50 no tiene un elemento de adaptación, por lo que el resultado es [[[11, 21], [32, 3], [44], 50]] .[1, [2, 3], [4]] + 60 = [1 + 60, [2, 3] + 60, [4] + 60] = [61, [2 + 60, 3 + 60], [ 4 + 60]] , lo que resulta en [61, [62, 63], [64]] .
El resultado final es [[[11, 21], [32, 3], [44], 50], [61, [62, 63], [64]]] .
Tarea
Escriba un programa o una función que tome dos enteros, dos matrices anidadas de enteros o una combinación de los mismos como entrada y devuelva su suma, como se definió anteriormente.
Si su idioma tiene múltiples tipos de matriz (listas, tuplas, vectores, etc.), puede elegir cualquiera de ellos para su respuesta. El tipo de retorno debe coincidir con el tipo de argumento.
Para evitar soluciones aburridas e inmejorables, si un idioma tiene esta operación exacta como una función incorporada, no puede usar ese idioma.
Todos los elementos integrados de todos los demás idiomas están permitidos. Si su idioma de elección lo permite, puede sobrecargar y / o redefinir la adición incorporada.
Este es el código de golf , por lo que gana el código más corto en bytes.
Casos de prueba
0 + 0 = 0
[-1, 0, -1] + [1] = [0, 0, -1]
[] + [0] = [0]
[] + 0 = []
[] + [] = []
[[], 0] + [] = [[], []]
[1, 2, 3] + 10 = [11, 12, 13]
[1, 2, 3] + [10] = [11, 2, 3]
[1, 2, 3] + [10, [20]] = [[11, 12, 13], [21, 2, 3]]
[1, 2, 3, []] + [10, [20]] = [11, [22], 3, []]
[1, [2, [3, [4]]]] + [10, [20]] = [[11, [21]], [[12, [22]], [13, [24]]]]
Para generar más casos de prueba, puede usar este programa Jelly .
Respuestas:
Pyth, 42 bytes
Banco de pruebas
Los últimos 4 bytes simplemente ejecutan la función en la entrada.
fuente
APL, 44 bytes
APL también se
+
distribuye en matrices, pero de una manera lo suficientemente diferente como para que esto realmente no se pueda usar. Sin embargo, hay una función de profundidad incorporada (≡
).Explicación:
1=≡⍺⍵:⍺+⍵
: si las profundidades de⍺
⍵
son ambas cero (y por lo tanto la profundidad de⍺ ⍵
es 1), agréguelas∆←|≡¨⍺⍵
: Tomar el absoluto de la profundidad de ambos⍺
y⍵
y almacenarlos en∆
. (≡
da un valor negativo si no todos los elementos tienen la misma profundidad).=/∆
: si tienen la misma profundidad:↓↑⍺⍵
: rellena la matriz más corta con ceros para que coincida con la matriz más larga⊃∇¨/
: distribuye la función en ambas matrices</∆
: si la profundidad de⍺
es menor que la de⍵
:⍺∘∇¨⍵
: enlazar⍺
y luego mapear⍵
⍵∇⍺
: si nada más (⍵
es más profundo que⍺
), intercambie los argumentos e intente nuevamente.fuente
Mathematica, 122 bytes
Define una función recursiva
f
que calcula la suma. Haciendo uso de la coincidencia de patrones de Mathematica, esta función se compone de cuatro definiciones separadas:Si la profundidad de
x
es mayor que la dey
, intercambie los argumentos para que solo tengamos que manejar la distribución en una dirección (lo que podemos hacer, ya que la suma es conmutativa).Si la profundidad de
x
es menos thann la dey
, reemplazar cada valor#
eny
conf[x,#]
, que se encarga de la distribución para los argumentos de profundidad desigual.De lo contrario, si un argumento es una lista (lo que implica que el otro también es una lista, ya que sabemos que tienen la misma profundidad), colocamos ambos argumentos en una lista, los rellenamos con la misma longitud
PadRight[..., Automatic]
(que simplemente llena un matriz irregular con ceros para hacerlo rectangular), y luego usarMapThread
para aplicarf
a los pares correspondientes de las dos listas.Y finalmente, el caso base:
Si ninguno de los otros patrones coincide, debemos tratar de sumar dos números, así que solo hacemos eso.
fuente
Haskell, 150 bytes
Explicación
La primera línea define un tipo de datos algebraicos
L
, que es unS
calar (que contiene unInt
) o unV
ector (que contiene una lista deL
s, al que se accede mediante un captador de registrosv
, que es una función parcialL → [L]
).La segunda línea define la función de profundidad : la profundidad de un
V
ector es uno más su profundidad máxima. AntepongoS 0
los valores en el vector, de modo quedepth [] == 1 + maximum [depth (S 0)] == 1
. La profundidad de "cualquier otra cosa" (un escalar) es0
.La tercera línea define el caso base para
!
(la función de suma): la suma de escalares es simplemente un escalar.La quinta línea define una variante de
zipWith (!)
que solo selecciona elementos de la lista más larga cuando uno de ellos está vacío.La cuarta línea se divide en tres casos:
Si la profundidad de
x
es estrictamente menor que la profundidad dey
, mapee(x!)
sobre los elementos dey
. (El uso dev
está garantizado como válido, comod(y) ≥ 1
.)Si la profundidad de
x
es estrictamente mayor, voltee los argumentos y reinicie.Si sus profundidades son iguales, junta los argumentos con
(!)
. (Sev
garantiza que el uso de es válido, ya que el casod(x) = d(y) = 0
se trató como un caso base).Casos de prueba
Entonces
show (lArg ! rArg) == "[[11,[21]],[[12,[22]],[13,[24]]]]"
.fuente
import
se debe a que Ideone tiene un viejo compilador Haskell. Las versiones modernas de GHC ponen<$>
enPrelude
, por lo que no es necesario importarControl.Applicative
para usarlo en estos días.Java,
802794754746 bytesDecidí aceptar a @ Dennis ♦ para el desafío de operar con cuerdas "como último recurso" porque probablemente era "demasiado complicado". Además, en el peor idioma para jugar al golf.
Las matrices en la entrada están separadas por comas, rodeadas con corchetes y sin espacios en blanco.
Programa completo con funciones incluidas en una clase y con casos de prueba.
Yo podría puerto esta a C ++ más adelante ya que es el otro idioma Sé que no es compatible con matrices irregulares, ya que estoy
bastante seguro de quecasi seguro que va a ser más corta que esta respuesta. Esto fue principalmente una prueba de concepto, ¡pero cualquier consejo de golf aún sería apreciado!-31 bytes de @ user902383 sugiriendo usar un foreach sobre una matriz de caracteres convertida, y luego ahorré un poco más de reorganizar los bloques if en la parte final.
fuente
Object[]
, que contiene anidadosObject[]
oInteger
. O simplemente Lista no genérica.Python 2.7,
261209202198191185197181 bytesSolución trivial FGITW
EDITAR: Por supuesto, @Dennis lo supera
Gracias a @LeakyNun por guardar 57 bytes con consejos sobre expresiones lambda y 2 bytes de paréntesis innecesarios.
Gracias a @Adnan por 4 bytes debido a la sugerencia de usar en
type
lugar deisinstance
Gracias a @Lynn por 7 bytes con
-~
ymap
Gracias a @FryAmTheEggman por en
z>=[]
lugar detype
+12 bytes para convertir lambda a if else y corregir un error mayor
-16 bytes gracias a @Kevin Lau - no Kenny
Pruébalo en línea
fuente
z==[]or`z`>']'and ...
max(d(a)+1for a in z)
con-~max(d(a)for a in z)
guardar un byte (porque puede eliminar el espacio antesmax
). Que es entonces justo-~max(map(d,z))
.[p(a,b)for a,b in zip(x,y)]
enmap(p,x,y)
. Todavía puede hacer esto en 3 pero necesita agregar una llamadalist
. Creo que también podrías mejorar la sugerencia de Lynn de serz>=[]
. Sin relación, también debería poder intercambiar eltype
orden de comparación para ahorrar un espacio.or`z`>'['
, por supuesto, pero ya no puedo cambiar mi comentario. Pero, de hecho, ¡z>[]
es aún más corto (el==
caso ya está manejado)!Python 2,
145136 bytesPruébalo en Ideone .
Cómo funciona
En Python 2, todos los enteros son menores que todos los diccionarios, pero todas las listas son mayores. d calcula recursivamente la profundidad de t devolviendo 0 para enteros o el máximo incrementado de las profundidades de sus elementos y 0 .
t+[0]
evita el uso de mayúsculas especiales en la lista vacía.s calcula recursivamente la suma Jelly de x e y .
Si Y 'profundidad s excede x ' s,
s(y,x)
llamadas s con argumentos intercambiados, asegurándose de que d (x) ≤ d (y) .Si y tiene profundidad positiva,
map(s,(x,[x]*len(y))[d(x)<d(y)],y)
hace lo siguiente.Si las profundidades de x e y coinciden, se ejecuta
map(s,x,y)
, asignando s sobre todos los elementos de x y los elementos correspondientes de y .En el caso de listas de diferentes longitudes, el mapa pasará Ninguno como argumento izquierdo o derecho para los elementos que faltan en la lista más corta.
Si la profundidad de x es menor que la de y , se ejecuta
map(s,[x]*len(y),y)
, asignando s (x, ·) sobre y .Si y (y, por lo tanto, x ) tiene profundidad 0 ,
(x or 0)+(y or 0)
reemplaza los argumentos falsos ( Ninguno o 0 ) con ceros y devuelve la suma de los enteros resultantes.fuente
JavaScript (ES6), 152 bytes
fuente
Rubí 2,3,
143145148149 bytesRuby tiene todas estas pequeñas peculiaridades sobre cómo
zip
funciona con matrices de diferentes longitudes ymap
con funciones de múltiples argumentos, lo que hace que sea bastante divertido jugar golf.fuente
map
en una función de dos argumentos de la forma en que la configuré al final. Aquí hay una versión editada para 2.1 que funciona que ajusta lamap
llamada al final para que funcione. ideone.com/q1jqTAJulia, 113 bytes
Pruébalo en línea!
Cómo funciona
crea un alias de 1 byte para endof , que devuelve la longitud de una matriz.
define una función de profundidad. La profundidad de t es cero si y solo si 0t == 0 . Si no, t es una matriz, y su profundidad se calcula como el máximo incrementado de las profundidades de sus elementos y 0 .
[t;0]
agrega un 0 a la matriz t , evitando así la necesidad de poner en especial la matriz vacía.La suma incorporada de Julia + ya se comporta como la suma de Jelly si cualquiera (o ambos) de sus argumentos es un número entero. Sin embargo, la suma de dos matrices ( + ) requiere matrices de la misma forma, e incluso la suma vectorizada ( . + ) Requiere matrices que pueden transmitirse a una forma común.
Redefinimos + para un par de matrices a través de
Esto no afecta la definición de + para los argumentos de entero / entero, matriz / entero o entero / matriz.
(!x,~x)>(!y,~y)
compara lexicográficamente los pares de profundidades y longitudes de x e y . Si la profundidad de x excede la de y , o si su profundidad coincide y la longitud de x excede y ' s,y+x
llama recursivamente + con argumentos intercambiados.De lo contrario,
!x<!y
comprueba si la profundidad de x es menor que la de y . Si esto es,map(t->x+t,y)
asigna x + · sobre y .Si las profundidades coinciden,
~x<~y
comprueba si x es más corto que y . Si esto es,[x;0]+y
recursivamente llama a + después de agregar un 0 al argumento izquierdo.Finalmente, si ambas profundidades y longitudes son idénticas,
x.+y
asigna + sobre todos los elementos de x y los elementos correspondientes de y .fuente