Contexte
Les atomes arithmétiques de Jelly se vectorisent automatiquement. En fait, x + y est bien défini chaque fois que x et y sont des nombres ou des tableaux irréguliers de nombres. Le code source de Jelly implémente ce comportement à l'aide d'un vectoriseur générique, mais pour ce défi, nous ne considérerons que l'ajout d'entiers et de tableaux d'entiers imbriqués.
Définitions
Définissez la profondeur de x comme 0 si x est un entier, comme 1 s'il s'agit d'un tableau plat (éventuellement vide) d'entiers, et comme n + 1 s'il contient au moins un élément de profondeur n et aucun élément de profondeur k> n .
De cette façon, 1 a la profondeur 0 , [] et [1] et [1, 1] ont la profondeur 1 , [[], []] et [[1], [1]] et [[1]] et [1 , []] a la profondeur 2 , [1, [1, [1]]] a la profondeur 3 , etc.
L'opération x + y est définie comme suit.
Si x et y ont une profondeur de 0 , renvoyez leur somme.
Si x et y ont des profondeurs égales mais positives, appliquer récursivement + à tous les éléments de x et aux éléments correspondants de y .
Si x et y ont des longueurs différentes, ajoutez la queue du tableau le plus long au tableau des sommes.
Renvoie le résultat.
Si la profondeur de x est strictement inférieure à la profondeur de y , appliquez récursivement + à x et à tous les éléments de y , et retournez le résultat.
Faire le contraire si y « s profondeur est strictement inférieure à x » s.
Par exemple, considérons l'opération [1, [2, 3], [4]] + [[[10, 20], [30], 40, 50], 60] .
La profondeur de l'argument de gauche est 2 , tandis que la profondeur de l'argument de droite est 3 , donc nous calculons [1, [2, 3], [4]] + [[10, 20], [30], 40, 50 ] et [1, [2, 3], [4]] + 60 .
[1, [2, 3], [4]] et [[10, 20], [30], 40, 50] ont tous deux la profondeur 2 , nous calculons donc 1 + [10, 20] , [2, 3] + [30] et [4] + 40 .
1 + [10, 20] = [1 + 10, 1 + 20] = [11, 21]
[2, 3] + [30] = [2 + 30, 3] = [32, 3]
Notez que 3 reste intact, car il n'a pas d'élément correspondant.
[4] + 40 = [4 + 40] = [44]
50 n'a pas un élément d'adaptation, de sorte que le résultat est [[[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]] , ce qui donne [61, [62, 63], [64]] .
Le résultat final est [[[11, 21], [32, 3], [44], 50], [61, [62, 63], [64]]] .
Tâche
Écrivez un programme ou une fonction qui prend en entrée deux entiers, deux tableaux imbriqués d'entiers ou une combinaison de ceux-ci et renvoie leur somme, comme défini ci-dessus.
Si votre langue a plusieurs types de tableaux (listes, tuples, vecteurs, etc.), vous pouvez choisir l'un d'eux pour votre réponse. Le type de retour doit correspondre au type d'argument.
Pour éviter des solutions ennuyeuses et imbattables, si une langue a cette opération exacte en tant que intégré, vous ne pouvez pas utiliser cette langue.
Toutes les intégrations de toutes les autres langues sont autorisées. Si la langue de votre choix le permet, vous pouvez surcharger et / ou redéfinir l'ajout intégré.
Il s'agit de code-golf , donc le code le plus court en octets l'emporte.
Cas de test
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]]]]
Pour générer plus de cas de test, vous pouvez utiliser ce programme Jelly .
Réponses:
Pyth, 42 octets
Suite de tests
Les 4 derniers octets exécutent simplement la fonction sur l'entrée.
la source
APL, 44 octets
APL
+
distribue également sur des tableaux, mais d'une manière suffisamment différente pour que cela ne puisse pas vraiment être utilisé. Cependant, il existe une fonction de profondeur intégrée (≡
).Explication:
1=≡⍺⍵:⍺+⍵
: si les profondeurs de⍺
⍵
sont toutes deux nulles (et donc la profondeur de⍺ ⍵
est 1), ajoutez-les.∆←|≡¨⍺⍵
: Prendre l'absolu de la profondeur à la fois⍺
et⍵
et les stocker dans∆
. (≡
donne une valeur négative si tous les éléments n'ont pas la même profondeur.)=/∆
: s'ils ont la même profondeur:↓↑⍺⍵
: remplir le tableau le plus court avec des zéros pour correspondre au tableau le plus long⊃∇¨/
: distribuer la fonction sur les deux tableaux</∆
: si la profondeur de⍺
est inférieure à celle de⍵
:⍺∘∇¨⍵
: lier⍺
puis cartographier⍵
⍵∇⍺
: si rien d'autre (donc⍵
c'est plus profond que⍺
), échangez les arguments et réessayez.la source
Mathematica, 122 octets
Définit une fonction récursive
f
qui calcule la somme. Utilisant la correspondance de motifs de Mathematica, cette fonction se compose de quatre définitions distinctes:Si la profondeur de
x
est supérieure à celle dey
, permutez les arguments de sorte que nous n'ayons à gérer la distribution que dans une seule direction (ce que nous pouvons faire, car l'addition est commutative).Si la profondeur de
x
est inférieure à celle dey
, remplacez chaque valeur#
pary
parf[x,#]
, qui s'occupe de la distribution des arguments de profondeur inégale.Sinon, si un argument est une liste (ce qui implique que l'autre est également une liste, car nous savons qu'ils ont la même profondeur), nous mettons les deux arguments dans une liste, les
PadRight[..., Automatic]
remplissons à la même longueur avec (qui remplit simplement un tableau irrégulier avec des zéros pour le rendre rectangulaire), puis utilisezMapThread
pour appliquerf
aux paires correspondantes des deux listes.Et enfin, le cas de base:
Si aucun des autres modèles ne correspond, nous devons essayer d'ajouter deux nombres, alors nous le faisons simplement.
la source
Haskell, 150 octets
Explication
La première ligne définit un type de données algébrique
L
, qui est soit unS
calar (contenant unInt
) ou unV
ector (contenant une liste deL
s, accessible à l'aide d'un getter d'enregistrementv
, qui est une fonction partielleL → [L]
.)La deuxième ligne définit la fonction de profondeur : la profondeur d'un
V
ecteur est une plus sa profondeur maximale. Je fais précéderS 0
les valeurs du vecteur, de sorte quedepth [] == 1 + maximum [depth (S 0)] == 1
. La profondeur de «toute autre chose» (un scalaire) est0
.La troisième ligne définit le cas de base pour
!
(la fonction d'addition): la somme des scalaires est simplement un scalaire.La cinquième ligne définit une variante
zipWith (!)
qui sélectionne simplement les éléments de la liste la plus longue lorsque l'un d'eux est vide.La quatrième ligne est divisée en trois cas:
Si la profondeur de
x
est strictement inférieure à la profondeur dey
, cartographiez(x!)
les éléments dey
. (L'utilisation dev
est garantie valide, asd(y) ≥ 1
.)Si la profondeur de
x
est strictement supérieure, retournez les arguments et redémarrez.Si leurs profondeurs sont égales, zippez les arguments avec
(!)
. (L'utilisation dev
est garantie, car le cas ad(x) = d(y) = 0
été traité comme un cas de base.)Cas de test
Alors
show (lArg ! rArg) == "[[11,[21]],[[12,[22]],[13,[24]]]]"
.la source
import
parce que Ideone a un vieux compilateur Haskell. Les versions modernes de GHC mis<$>
enPrelude
, afin que vous n'avez pas besoin d'importerControl.Applicative
de l' utiliser ces jours -ci .Java,
802794754746 octetsJ'ai décidé de relever @ Dennis ♦ pour le défi d'opérer sur les cordes "en dernier recours" car c'était probablement "trop compliqué". Aussi, dans la pire langue pour jouer au golf.
Les tableaux en entrée sont séparés par des virgules, entourés de crochets et sans espaces.
Programme complet avec des fonctions enveloppées dans une classe et avec des cas de test
Je pourrais porter cela en C ++ plus tard, car c'est l'autre langage que je connais qui ne prend pas en charge les tableaux irréguliers, car je suis
presque sûrque ce sera plus court que cette réponse. C'était surtout une preuve de concept mais tous les conseils de golf seraient toujours appréciés!-31 octets de @ user902383 suggérant d'utiliser un foreach sur un tableau de caractères converti, puis j'ai économisé un peu plus en réorganisant les blocs if dans la partie finale.
la source
Object[]
, qui contient soit imbriqué,Object[]
soitInteger
. Ou simplement une liste non générique.Python 2.7,
261209202198191 191185197181 octetsSolution triviale FGITW
EDIT: Bien sûr, @Dennis le bat
Merci à @LeakyNun pour avoir économisé 57 octets avec des conseils sur les expressions lambda et 2 octets à partir de crochets inutiles.
Merci à @Adnan pour 4 octets en raison de la suggestion d'utiliser
type
au lieu deisinstance
Merci à @Lynn pour 7 octets avec
-~
etmap
Merci à @FryAmTheEggman pour
z>=[]
au lieu detype
+12 octets pour convertir lambda en if else et corriger un bug majeur
-16 octets grâce à @Kevin Lau - pas Kenny
Essayez-le en ligne
la source
z==[]or`z`>']'and ...
max(d(a)+1for a in z)
par-~max(d(a)for a in z)
enregistre un octet (car vous pouvez supprimer l'espace avantmax
). Ce qui est alors juste-~max(map(d,z))
.[p(a,b)for a,b in zip(x,y)]
enmap(p,x,y)
. Vous pouvez toujours le faire en 3, mais vous devez ajouter un appel àlist
. Je pense que vous pourriez également améliorer la suggestion de Lynnz>=[]
. Indépendant, vous devriez également pouvoir échanger l'type
ordre de comparaison pour économiser de l'espace.or`z`>'['
, bien sûr, mais je ne peux plus changer mon commentaire. Mais en effet,z>[]
c'est encore plus court (l'==
affaire est déjà traitée)!Python 2,
145136 octetsTestez-le sur Ideone .
Comment ça fonctionne
En Python 2, tous les entiers sont inférieurs à tous les dictionnaires, mais toutes les listes sont supérieures. d calcule récursivement la profondeur de t en retournant 0 pour les entiers ou le maximum incrémenté des profondeurs de ses éléments et 0 .
t+[0]
évite de placer une casse spéciale dans la liste vide.s calcule récursivement la somme de Jelly de x et y .
Si y 'la profondeur dépasse x ' s, des
s(y,x)
appels s avec des arguments échangés, en vous assurant que d (x) ≤ d (y) .Si y a une profondeur positive,
map(s,(x,[x]*len(y))[d(x)<d(y)],y)
procédez comme suit.Si les profondeurs x et y correspondent, il s'exécute
map(s,x,y)
, mappant s sur tous les éléments de x et les éléments correspondants de y .Dans le cas de listes de longueurs différentes, map passera None comme argument gauche ou droit pour les éléments manquants dans la liste plus courte.
Si la profondeur de x est inférieure à celle de y , elle s'exécute
map(s,[x]*len(y),y)
, mappant s (x, ·) sur y .Si y (et, par conséquent, x ) a la profondeur 0 ,
(x or 0)+(y or 0)
remplace les arguments falsifiés ( Aucun ou 0 ) par des zéros et renvoie la somme des entiers résultants.la source
JavaScript (ES6), 152 octets
la source
Ruby 2.3,
143145148149 149 octetsRuby a toutes ces petites bizarreries dans la façon dont
zip
fonctionne avec des tableaux de différentes longueurs etmap
avec des fonctions multi-arguments, ce qui en fait assez amusant pour jouer au golf.la source
map
d'une fonction à deux arguments comme je l'ai configuré à la fin. Voici une version éditée pour 2.1 qui fonctionne qui ajuste l'map
appel à la fin pour fonctionner. ideone.com/q1jqTAJulia, 113 octets
Essayez-le en ligne!
Comment ça fonctionne
crée un alias de 1 octet pour endof , qui renvoie la longueur d'un tableau.
définit une fonction de profondeur. La profondeur de t est nulle si et seulement si 0t == 0 . Sinon, t est un tableau et sa profondeur est calculée comme le maximum incrémenté des profondeurs de ses éléments et 0 .
[t;0]
ajoute un 0 au tableau t , évitant ainsi la nécessité de mettre en cas particulier le tableau vide.La somme intégrée de Julia + se comporte déjà comme la somme de Jelly si l'un (ou les deux) de ses arguments est un entier. Cependant, la somme de deux tableaux ( + ) nécessite des tableaux de même forme, et même la somme vectorisée ( . + ) Nécessite des tableaux pouvant être diffusés vers une forme commune.
Nous redéfinissons + pour une paire de tableaux via
Cela n'affecte pas la définition de + pour les arguments entier / entier, tableau / entier ou entier / tableau.
(!x,~x)>(!y,~y)
compare lexicographiquement les paires de profondeurs et de longueurs de x et y . Si la profondeur de x dépasse y , ou si leur profondeur correspond et la longueur de x dépasse y ,y+x
appelle récursivement + avec des arguments échangés.Sinon,
!x<!y
teste si la profondeur de x est inférieure à celle de y . Si c'est,map(t->x+t,y)
mappe x + · sur y .Si les profondeurs correspondent,
~x<~y
teste si x est plus court que y . Si c'est le cas,[x;0]+y
appelle récursivement + après avoir ajouté un 0 à l'argument de gauche.Enfin, si les profondeurs et les longueurs sont identiques,
x.+y
mappe + sur tous les éléments de x et les éléments correspondants de y .la source