# Generate recursive "arrays" up to a certain depth

Given a positive integer n.

Generate a JSON array (can be a string, or your language's built-in JSON representation as long as we can get valid JSON, (your code does not need to include outputting the string, you can just use the built-in JSON representation)) containing two empty JSON arrays, then, add a set of 2 empty JSON arrays to each existing set of 2 empty JSON arrays up to n deep. n can be 0 or 1 indexed.

# Rules

1. The shortest code wins the challenge (as this is code-golf).
2. All output JSON must be RFC8259 compliant.

# Examples

Input: 0
Output: [[], []]
Input: 1
Output: [[[], []], [[], []]]
Input: 2
Output: [[[[], []], [[], []]], [[[], []], [[], []]]]

• Welcome to Code Golf! I've added the code-golf and array tags. Dec 12, 2022 at 20:34
• -1 should give [] then, no?
Dec 12, 2022 at 21:03
• @Adám The integer must be positive, so the number -1 is out of the question. And no, you must start the index at 0. I will update the post to state that. Dec 12, 2022 at 21:15
• I wasn't saying that -1 should be a valid input, just that if we run the transformation rule in reverse from [[],[]] we get []. Also, this community enjoys having input rule lax, and it is common to allow both 0-indexing and 1-indexing.
Dec 12, 2022 at 21:37
• Oh. Sorry I'm new to the community, just learning the ropes here. Dec 12, 2022 at 23:53

# APL (Dyalog Extended), 12 6 bytes

−6 thanks to OP now allowing 1-indexing and results that can be converted to JSON, rather than the JSON itself.

Full program; prompts for 1-indexed n and prints APL nested array equivalent of the required JSON. Adding an print handler which just converts output to JSON shows the required result.

⍮⍨⍣⎕⊢⍬


Try it online!

⍬ empty list ([])

⍣⎕⊢ on that, apply the following function n (prompted-for) number of times:

⍮⍨ pair up with itself

The print handler:

Print←{} assign a function as follows:

⎕JSON⍺ convert output array to JSON

⎕← print that

Setting up the JSON printing callback on output:

⎕SE. for the current session:

onSessionPrint← set the event handler for printing to

Print call the above handler function

# GNU sed, 36 35 bytes

I believe numeric input is allowed to be in unary format for sed. For ex. 3 becomes @@@ and 0 becomes the empty string (no @s). The nameless label : is supported by older versions of sed.

s:$:@[]: : s:@:: s:\[]:[&, &]:g /@/b  Try it online with sed 4.2.2! In each loop iteration one character is removed from the unary number as one depth is introduced in the array. A small trick is used in the first line, where the initialization is only [] (shorter than [[], []]), like a "-1 based indexing". As such the input number is incremented by one with the extra @. This helps also with not checking up front for the empty string (input 0). EDIT: with 1-based indexing now allowed, the incrementing from first line isn't needed,thus saving one byte: s:$:[]: Thanks to Adám for the heads-up.

• I think you can skip the incrementing, as 1-based indexing is now OK.
Dec 13, 2022 at 14:27

# Vyxal, 4 bytes

›(W:


Try it online! One-indexed. Returns a nested list.

›    # increment
(   # repeat for n+1 times (n+1 is popped):
W  #   wrap stack into single list (initially [])
: #   duplicate
# implicit output


### VyxalW, 3 bytes

(W:


Try it online!

Here, it repeats n times, and before outputting implicitly, the W flag wraps the stack into a single list.

# sclin, 15 bytes

[]"dup ,";1+ *#


Try it here! I've been thinking about having code that took input from the next line rather than the previous. Surprisingly useful, gonna have to use it more often...

For testing purposes:

[]"dup ,";1+ *# f>o
2


## Explanation

Prettified code:

[] ( dup , ) ; 1+ *#

• [] empty list
• (...) ; 1+ *# execute (next line) + 1 times...
• dup , duplicate and pair into list

# JavaScript (Node.js), 2523 22 bytes

Saved 2 bytes thanks to Arnauld! Saved 1 byte by changing to 1-indexed.

f=n=>n--?[a=f(n),a]:[]


Try it online! Arnauld's observation of testing for 1-indexed as ~n-- saves 1 byte over n--+1.

Returns an array of arrays, which, when printed, will output JSON compliant arrays.

If a string output is mandatory, then we have, using the same method:

# JavaScript (Node.js), 343231 29 bytes

Saved 2 bytes thanks to Arnauld! Saved 2 bytes thanks to l4m2! Saved 1 byte by changing to 1-indexed.

f=n=>[${n--?[a=f(n),a]:[]}]  Try it online! • 29 string output – l4m2 Dec 13, 2022 at 5:42 • @l4m2 thanks!!! Dec 13, 2022 at 18:27 # TI-Basic, 32 bytes Prompt N "[] For(I,0,N "["+Ans+","+Ans+"] End Ans  • Can you not remove Prompt N and replace N with Ans? – Adám Dec 15, 2022 at 17:19 • no, since I use Ans for the string, and adding ->Str1 everywhere would be longer I think Dec 15, 2022 at 17:22 • But wouldn't For( read the value of Ans once and for all, before the string concatenation overwrites Ans? – Adám Dec 15, 2022 at 17:33 • yes but I need to initialize Ans to "[]" before the loop Dec 15, 2022 at 18:17 # ><>, 58 bytes e0i1+:?v"]["oo~. 3[r]40.\"["o:1-20 .","o:1-303[r]40 ."]"o~  Try it Offsetting the number by 1 would save 2 bytes, since I can skip the 1+. ## Explanation Top row: Main function. Check if the recursion level is 0, if so print [] and return, else go down. Second row: print [, then recurse. Third row: print , then recurse Print ] and return. • OP has updated the spec, and you can probably remove the 1+ now. – Adám Dec 13, 2022 at 14:28 # Retina, 22 bytes K[] "$+"+\[]
[[],[]]


Try it online! No test suite due to the way the program uses history. Explanation:

K[]


Replace the input with an empty array.

"$+"+  Repeat n times... \[] [[],[]]  ... replace each empty array with a pair of empty arrays. Previous 0-indexed version was 27 bytes: K[[],[]] "$+"+\[]
[[],[]]


Try it online! No test suite due to the way the program uses history. Explanation: Starts with the first pair of empty arrays thus reducing the number of iterations needed by 1.

• 1-indexing is now OK.
Dec 13, 2022 at 14:26

# FunStack alpha, 23 bytes

Pair self iterate "" At


You can try it at Replit. Takes the depth (1-indexed) as a command-line argument and the program on stdin.

### Explanation

At the core of this solution is the following infinite sequence:

[]
[[],[]]
[[[],[]],[[],[]]]
...


We start with the empty list, and each subsequent element is two copies of the previous element wrapped in a list. Pair self does exactly that, and we get the desired infinite list by iterateing that function starting from "" (empty string / empty list).

This creates a bare value at the left end of the program, so it is appended to the program's argument list. Then At takes the first argument as an index into the second argument and returns the corresponding element.

# Charcoal, 11 bytes

Ｆ⊕Ｎ≔Ｅ²υυ⭆¹υ


Ｆ⊕Ｎ


Loop n+1 times...

≔Ｅ²υυ


... replace the predefined empty list with a list of two copies of it.

⭆¹υ


Pretty-print the final list (needed because Charcoal doesn't normally output anything for empty lists).

• You can probably change to looping n times, now with OP's updated spec.
Dec 13, 2022 at 14:29
• @Adám Not worth my while editing my answer just for that one byte (⊕) saving though.
– Neil
Dec 13, 2022 at 17:54

# Python, 29 bytes

g=lambda n:n*[0]and[g(n-1)]*2


Attempt This Online!

1-indexed. Returns Python's native array representation.

# Python, 45 bytes

g=lambda n:n and f'[{g(n-1)},{g(n-1)}]'or'[]'


Attempt This Online!

Returns a string, also 1-indexed. I found three different 45-byte functions for this, so I chose the simplest.

Takes n as 1-indexed argument on TIO.

.+
[&,&]


Initial input:

[]


Try it online!

.+ match everything (any number of any characters)

[&,&] replace with open-bracket, match, comma, match, close-bracket

for($a=[],$b=[&$a,&$a];$argn--;)$a=[$a,$a];echo json_encode($b);  Try it online! I thought this solution by reference elegant enough to be posted, I wish we could use a reference to a variable while initializing it, but unfortunately it's not the case. Too bad for the output format, almost a third of the code is lost to formatting.. # 05AB1E, 5 bytes ¯IƒD‚  Explanation: ¯ # Push an empty list: [] Iƒ # Loop the input+1 amount of times: D # Duplicate the current list ‚ # Pair the two lists together # (after the loop, output the result implicitly)  • Do you really need I? – Adám Dec 14, 2022 at 23:37 • @Adám Well, I could use s as alternative. ;) But the input has to be the top of the stack in order to start the loop. Dec 15, 2022 at 13:15 # Julia 1.0, 21 bytes !x=1:2(x>0).|>_->!~-x  Try it online! returns a nested array Explanation • a .|> f applies f on each element of a • when x=0, 1:0 is (kinda) an empty list, so the result is an empty list • when x>0, 1:2 acts like a 2-element list, and each element of this list will be !(x-1) # R, 57 53 bytes Edit: saved 4 bytes by copying MarcMush's approach \(n){s="[]";for(i in 1:n)s=paste0("[",s,",",s,"]");s}  Returns JSON string. Attempt This Online! # R, 41 37 bytes f=\(n,s={})if(n,f(n-1,list(s,s)),s)  Attempt This Online! Returns R nested list, which can be converted into a json string. # Raku, 21 bytes {(@,{$_,$_}...*)[$_]}


Try it online!

# jq, 36 bytes

def n:try(.<0//(.-1|[n,n]))+[]//[];n


Try it online!

Thanks to ovs for the try(A//C)+[]//B hack!

Our recursive function has a base case of -1, which yields []. Otherwise, our input is decremented, and [n,n] recurses into the function twice.

# Thunno, $$\7\log_{256}(96)\approx\$$ 5.76 bytes

ls{KDZP


Attempt This Online!

Port of Kevin Cruijssen's 05AB1E answer.

#### Explanation

ls{KDZP  # Implicit input
ls       # Push an empty list and swap
{K     # Repeat (input) times:
DZP  #  Duplicate and pair
# Implicit output


## Batch, 76 bytes

@set s=[]
@for /l %%i in (0,1,%1)do @call set s=%%s:[]=[[],[]]%%
@echo %s%


Explanation: Port of the 1-indexed version of my Retina answer, but looping from 0 to n to convert back to 0-indexed. call set is needed because otherwise the variable gets expanded before the for loop executes.

• Sadly no savings to be made by switching to 1-indexing (change the 0 to a 1).
– Neil
Dec 13, 2022 at 17:55

# Jelly, 9 bytes

’ßWƊR‘?;


A recursive, monadic Link that accepts a non-negative integer (0-indexed) and yields the nested list. (Replace ‘ with ¹ to use 1-indexed input.)

Try it online!

### How?

’ßWƊR‘?; - Link: integer, n
?   - if...
‘    - ...condition: increment (i.e. n != -1?)
’         -    decrement (n) -> n-1
ß        -    call this Link with n-1
W       -    wrap that in a list
R     - ...else: range (n = -1) -> []
 - use as both arguments of:
;  -   concatenate


# Factor, 33 bytes

[ { } swap [ dup 2array ] times ]
`

Try it online!