Multiply numbers by their depth

Given a ragged list, we can define an element's depth as the number of arrays above it, or the amount that it is nested.

For example, with the list [[1, 2], [3, [4, 5]]] the depth of the 2 is 2, as it is nested within two lists: The base list, and the list [1, 2]. The depth of the 4 is 3 as it is nested within three lists.

Your challenge is to, given a ragged list of positive integers, multiply them by their depths.

For example, given the list [[1, 2], [3, [4, 5]], 6]:

• The depth of 1 is 2, so double it -> 2
• The depth of 2 is also 2, so double it -> 4
• The depth of 3 is 2, so double it -> 6
• The depth of 4 is 3, so triple it -> 12
• The depth of 5 is 3, so triple it -> 15
• The depth of 6 is 1, so leave it alone -> 6

So, the result is [[2, 4], [6, [12, 15]], 6].

Another way of viewing it:

[[1, 2], [3, [4, 5 ]], 6]  - Original list
[[2, 2], [2, [3, 3 ]], 1]  - Depth map
[[2, 4], [6, [12,15]], 6]  - Vectorising product


You can assume the list won't contain empty lists.

This is , shortest wins!

Testcases

[[1, 2], [3, [4, 5]], 6] => [[2, 4], [6, [12, 15]], 6]
[[3, [2, 4]]] => [[6, [6, 12]]]
[[9, [[39], [4, [59]]]], 20] => [[18, [[156], [16, [295]]]], 20]
[2, [29]] => [2, [58]]
[[[[[[[[9]]]]]]]] => [[[[[[[[72]]]]]]]]

• Brownie points for beating my 10 bytes in Vyxal Jul 24 at 0:03

Vyxal, 4 bytes

⁽L€*


Try it Online!

⁽L€*
⁽ €  # At each value in the input, all the way down, run the following on the multi-dimensional index of the current value:
L   # Length. This gets the current depth
* # Vectorizically (is that a word?) multiply by the input

• I believe the word is "Vectoriously" Jul 24 at 1:28
• You got brownie points! Jul 25 at 12:24

Wolfram Language (Mathematica), 12 bytes

#0/@#-#&@-#&


Try it online!

         -# negate
#0/@#  &@   at each level:
-#       subtract original value(s)
(atoms: #0/@#-# = #-# = 0)


Python, 514944 43 bytes

f=lambda l,d=0:l*d*-1or[f(s,d-1)for s in l]


Attempt This Online!

This is a really fun abuse of the overloading of the * operator:

• If l is a positive integer, then l*d*-1 equals l*-d, which is always truthy (because the integers are always positive, so non-zero), so it returns l*-d, where d is the negation of the depth.
• If l is an array, then l*d produces d copies of the list joined together, which is actually interpreted as 0 copies of the list joined together (because d is negative), i.e. []. So l*d*-1 equals equals []*-1 equals [], which is falsy, so the second part of the conditional is run.

-1 bytes from @loopywalt by flipping the sign of d.

• You can flip the sign of d to save 1. Jul 24 at 1:11
• f=lambda l,d=0:l*d*-1or[f(s,d-1)for s in l] Jul 24 at 1:13

Jelly, 5 bytes

ŒJẈṁ×


Try it online!

ŒJ       All multidimensional indices, in flat order.
Ẉ      Get the length of each index (= depth of value at index).
ṁ     Mold to the structure of the input,
×    and multiply corresponding elements.


K (ngn/k), 17 bytes

{$[x~*x;0;x+o'x]}  Try it online! JavaScript, 32 bytes (g=k=>a=>a.map?.(g(-~k))??a*k)()  f = (g=k=>a=>a.map?.(g(-~k))??a*k)() testcases =  [[1, 2], [3, [4, 5]], 6] => [[2, 4], [6, [12, 15]], 6] [[3, [2, 4]]] => [[6, [6, 12]]] [[9, [[39], [4, [59]]]], 20] => [[18, [[156], [16, [295]]]], 20] [2, [29]] => [2, [58]] [[[[[[[[9]]]]]]]] => [[[[[[[[72]]]]]]]] .trim().split('\n').map(l => l.split(' => ').map(t => JSON.parse(t))); testcases.forEach(([i, e]) => { console.log(JSON.stringify(f(i)) === JSON.stringify(e), JSON.stringify(f(i))); }); The submitted function is partial invoked currying function. Maybe the first time I try to use this pattern in a code-golf. However, the a.map?.(…)??… pattern is quite common for . • Further explanation: -~k is a 2's complement bithack to increment, and force it to be a 32-bit integer (because of doing bitwise not). But how does k get initialized to 1 for the first call? Does the caller have to provide that, or is it somehow implicit in the partial currying, or an uninitialized value being 0? (I'm not familiar with that JS syntax, unfortunately) Jul 27 at 0:24 • @PeterCordes The first call is done in the code by () at the end. Since no value passed here, k is undefined. And undefined is converted into 0 when toInt32 implicit applied before ~. – tsh Jul 27 at 2:23 BQN, 9 bytes {+⟜𝕊⍟=¨𝕩}  Try it here! -5 bytes thanks to @att! Explanation • {...¨𝕩} for each element n over input... • ...⍟= if rank of n > 0 (i.e. n is a list)... • +⟜𝕊 n + F(n) • you don't need the ( ) around +⟜𝕊 – att Jul 25 at 4:52 • = works instead of (×≡) – att Jul 25 at 4:59 • @att thanks, good catches! Jul 25 at 5:20 Retina 0.8.2, 51 bytes \d+$*
1(?=((\[)|(?<-2>])|(])|[^][])+)
$#3$*
1+
$.&  Try it online! Link includes test cases. Explanation: \d+$*


Convert to unary.

1(?=((\[)|(?<-2>])|(])|[^][])+)
$#3$*


Replace each 1 with the number of unmatched ]s in the input's suffix, which equals its depth, thereby multiplying each number by its depth.

1+
$.&  Convert to decimal. Just creating the depth map can be readily achieved with the following code: \d+(?=((\[)|(?<-2>])|(])|[^][])+)$#3


Retina 1 can perform multiplication as part of a substitution, solving the original problem as follows:

\d+(?=((\[)|(?<-2>])|(])|[^][])+)
$.($#3**


Try it online! Link includes test cases. Explanation: The ** causes the capture result (the depth) to be implicitly multiplied by the matched integer, converted to unary, and the $.( then converts back to decimal. PARI/GP, 25 bytes f(a)=if(#a',a+apply(f,a)) Attempt This Online! Racket, 88 63 bytes (define(m l[d 0])(if(list? l)(map(λ(n)(m n(+ 1 d)))l)(* l d)))  Try it online! -25 from removing whitespace, ty @emanresu A! • Welcome to Code Golf, and nice first answer! Be sure to check out our Tips for golfing in Raket page for ways you can golf your program. You can probably remove most of the whitespace. Jul 26 at 0:10 • Also, does Racket allow you to omit trailing parentheses? Jul 29 at 11:13 lin, 26 bytes "deps1> (.+ \@ ' + ) e&".'  Try it here! Uses stack as nested list. For testing purposes (use -i flag when running locally): [[1 2] [3 [4 5]] 6] \; ' "deps1> (.+ \@ ' + ) e&".'  Explanation Prettified: ( deps 1> (.+ \@ ' + ) e& ).'  • (...).' map... • deps 1> (...) e& if depth > 1 (i.e. is list)... • .+ \@ ' + recurse and vector-add to current element 05AB1E, 16 bytes _"Ddië®δ.V>"©.V*  Explanation: First step of this 05AB1E answer of mine. _ # Transform each integer in the (implicit) input to 0 "..." # Push the recursive string explained below © # Store it in variable ® (without popping) .V # Evaluate and execute it as 05AB1E code # (we now have the depth of each item in the ragged input-list) * # Multiply each by the value in the (implicit) input-list at the same # positions # (after which the result is output implicitly) D # Duplicate the current list dië # If it's not an integer (so it's a list): δ # Map over each item: ® .V # Do a recursive call > # Then increase each integer in this list by 1  05AB1E, 2316 15 bytes .γd}DžuSδ¢ÆηO*J  Try it online! -2 thanks to @Kevin Cruijssen Takes the input list as a string, using ( and ). If a and b are valid list boundaries, then it's -1 for replacing žu with A. Try it online! • Since you take the input as string, you can take the input with () instead of [] brackets, and then golf the „[] to žu for -1: try it online. Jul 25 at 7:34 • εžuS¢Æ} can be žuSδ¢Æ for another -1: try it online. Looks like using strings is shorter than lists after all, since my answer is 16 bytes rn. ;) Jul 25 at 8:27 Perl 5-p, 33 bytes s/\d+/$&*($=~y|[||-$=~y|]||)/ge


Try it online!

For each number, depth is determined by counting the number of [ and subtracting the number of ] that come before it in the string.

Ruby, 38 bytes

f=->a,d=0{a*0==0?a*d:a.map{f[_1,d+1]}}

Attempt This Online!

• Just asking, are you still active?
– null
Aug 10 at 14:02
• not very active, but i still do hang around this site. Aug 10 at 14:19
• Ah, good to know. Many people are no longer active these days.
– null
Aug 11 at 11:41

Ruby, 38 bytes

f=->a,i=1{a.map{f[_1,i+1]rescue _1*i}}

Attempt This Online!

An alternative to Razetime's answer for the same byte count.

Knight, 124 118 bytes

;=p++=o""=i=d 0P;W<=i+1iLp;=n=cGp i 1I>c"9";=d-d-1*2<c"]"=o+o cI<"/"c;W&<=tGp+1i 1"["<"/"t;=i+1i=n+n t=o+o*d n=o+o cOo


Try it online!

Nice, big ole fat Knight program. Parses it as a string lol

Ungolfed and commented:

; = p + + = o "" = i = d 0 PROMPT                # p = (o = "") + (i = d = 0) + input()
; W < = i + 1 i LENGTH p                         # while (i = i + 1) < len(p):
; = n = c GET p i 1                            #   n = c = p[i]
: IF > c "9"                                   #   if c > "9":
; = d - d - 1 * 2 < c "]"                    #     d = d - (1 - 2 * (c < "["))
: = o + o c                                  #     o = o + c
# ELSE                                         #   else:
: IF < "/" c                                 #     if "/" < c:
; WHILE & < = t GET p + 1 i 1 "[" < "/" t  #       while ((t = p[i + 1]) < "[") and ("/" < t):
; = i + 1 i                              #         i = i + 1
: = n + n t                              #         n = n + t
: = o + o * d n                            #       o = o + d * n
# ELSE                                       #     else:
: = o + o c                                #       o = o + c
: OUTPUT o                                       # print(o)


• 121 bytes: ;=o"";=pP;=d 0;=i~1;W<=i+1iLp;=n=cGp i 1I>c"9";=d-d-1*2<c"]"=o+o cI<"/"c;W&<=tGp+1i 1"["<"/"t;=i+1i=n+n t=o+o*d n=o+o cOo
Aug 2 at 23:18
• 118 bytes: ;=p++=o""=i=d 0P;W<=i+1iLp;=n=cGp i 1I>c"9";=d-d-1*2<c"]"=o+o cI<"/"c;W&<=tGp+1i 1"["<"/"t;=i+1i=n+n t=o+o*d n=o+o cOo
Aug 2 at 23:38

Charcoal, 35 bytes

⊞υ⟦¹θ⟧ＦυＵＭ⊟ι⎇⁺⟦⟧κ∧⊞Ｏυ⟦⊕Σικ⟧κ×Σικ⭆¹θ


Try it online! Link is to verbose version of code. Explanation:

⊞υ⟦¹θ⟧


Start by considering the input list at depth 1.

Ｆυ


Loop through the list and its sublists.

ＵＭ⊟ι


Loop through the elements of the current list.

⎇⁺⟦⟧κ


If this is a sublist, then...

∧⊞Ｏυ⟦⊕Σικ⟧κ


... push it with the incremented depth to the list of sublists, but don't actually change the list itself yet, otherwise...

×Σικ


... multiply the element by the current depth.

⭆¹θ


Pretty-print the result, since Charcoal's default formatting is not designed for ragged lists.

J, 12 bytes

Takes input as a boxed array.

*L:0#L:1@{::

Attempt This Online!

{:: Map; replaces each leaf by its multidimensional index.
#L:1 At level 1 (for each index vector), take the length.
*L:0 multiply with input at level 0 (leafs).