19
\$\begingroup\$

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]]]]]]]]
\$\endgroup\$
1
  • \$\begingroup\$ Brownie points for beating my 10 bytes in Vyxal \$\endgroup\$
    – emanresu A
    Commented Jul 24, 2022 at 0:03

21 Answers 21

17
\$\begingroup\$

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
\$\endgroup\$
2
  • 14
    \$\begingroup\$ I believe the word is "Vectoriously" \$\endgroup\$ Commented Jul 24, 2022 at 1:28
  • \$\begingroup\$ You got brownie points! \$\endgroup\$ Commented Jul 25, 2022 at 12:24
10
\$\begingroup\$

Wolfram Language (Mathematica), 12 bytes

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

Try it online!

         -# negate
#0/@#  &@   at each level:
     -#       subtract original value(s)
            (atoms: #0/@#-# = #-# = 0)
\$\endgroup\$
6
\$\begingroup\$

Python, 51 49 44 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.

\$\endgroup\$
2
  • \$\begingroup\$ You can flip the sign of d to save 1. \$\endgroup\$
    – loopy walt
    Commented Jul 24, 2022 at 1:11
  • 1
    \$\begingroup\$ f=lambda l,d=0:l*d*-1or[f(s,d-1)for s in l] \$\endgroup\$
    – loopy walt
    Commented Jul 24, 2022 at 1:13
6
\$\begingroup\$

K (ngn/k), 17 bytes

{$[x~*x;0;x+o'x]}

Try it online!

\$\endgroup\$
5
\$\begingroup\$

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.
\$\endgroup\$
5
\$\begingroup\$

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)
\$\endgroup\$
3
  • 1
    \$\begingroup\$ you don't need the ( ) around +⟜𝕊 \$\endgroup\$
    – att
    Commented Jul 25, 2022 at 4:52
  • 1
    \$\begingroup\$ = works instead of (×≡) \$\endgroup\$
    – att
    Commented Jul 25, 2022 at 4:59
  • \$\begingroup\$ @att thanks, good catches! \$\endgroup\$ Commented Jul 25, 2022 at 5:20
4
\$\begingroup\$

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 .

\$\endgroup\$
2
  • \$\begingroup\$ 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) \$\endgroup\$ Commented Jul 27, 2022 at 0:24
  • 1
    \$\begingroup\$ @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 ~. \$\endgroup\$
    – tsh
    Commented Jul 27, 2022 at 2:23
3
\$\begingroup\$

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.

\$\endgroup\$
3
\$\begingroup\$

PARI/GP, 25 bytes

f(a)=if(#a',a+apply(f,a))

Attempt This Online!

\$\endgroup\$
3
\$\begingroup\$

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!

\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$
    – emanresu A
    Commented Jul 26, 2022 at 0:10
  • \$\begingroup\$ Also, does Racket allow you to omit trailing parentheses? \$\endgroup\$
    – emanresu A
    Commented Jul 29, 2022 at 11:13
2
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 16 bytes

_"Ddië®δ.V>"©.V*

Try it online or verify all test cases.

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
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 23 16 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!

\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Jul 25, 2022 at 7:34
  • \$\begingroup\$ εž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. ;) \$\endgroup\$ Commented Jul 25, 2022 at 8:27
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

Ruby, 38 bytes

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

Attempt This Online!

\$\endgroup\$
3
  • \$\begingroup\$ Just asking, are you still active? \$\endgroup\$ Commented Aug 10, 2022 at 14:02
  • 1
    \$\begingroup\$ not very active, but i still do hang around this site. \$\endgroup\$
    – Razetime
    Commented Aug 10, 2022 at 14:19
  • \$\begingroup\$ Ah, good to know. Many people are no longer active these days. \$\endgroup\$ Commented Aug 11, 2022 at 11:41
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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)

-6 bytes thanks to Adam.

\$\endgroup\$
2
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Aug 2, 2022 at 23:18
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Aug 2, 2022 at 23:38
1
\$\begingroup\$

Charcoal, 35 bytes

⊞υ⟦¹θ⟧FυUM⊟ι⎇⁺⟦⟧κ∧⊞Oυ⟦⊕Σικ⟧κ×Σικ⭆¹θ

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

⊞υ⟦¹θ⟧

Start by considering the input list at depth 1.

Fυ

Loop through the list and its sublists.

UM⊟ι

Loop through the elements of the current list.

⎇⁺⟦⟧κ

If this is a sublist, then...

∧⊞Oυ⟦⊕Σικ⟧κ

... 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.

\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

jq, 31 bytes

def f(n):map(f(n+1))?//.*n;f(0)

Try it online!

The key to the base case: If map() fails (since we try to map over a number instead of an array), ? suppresses the error, // substitutes the alternate value of .*n

\$\endgroup\$
1
\$\begingroup\$

brev, 46 bytes

(c(fn(if(list? y)(map(c f(+ x 1))y)(* y x)))0)

Classic lispy depth first tree walking: map if not atom

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.