22
\$\begingroup\$

Challenge

Create a function or program that, when given an integer size, behaves the following way:

If size is equal to 1, output

┌┐
└┘

If size is greater than 1, apply the following substitutions :

Source Target
┌┐
└┌
┌┐
┐┘
┌└
└┘
┘┐
└┘

Note: this is basically a Unicode box-drawing version of the T-Square fractal.

If it makes things easier for you, you may make the base case correspond to 0, as long as you specify in your answer.

The program should output anything that is isomorphic to a grid, so a multiline string, an array of strings, an array of arrays of chars, whichever is more comfortable. You may use a different set of characters than ┌┐└┘ (such as 1234, ABCD, etc.) if you want.

Leading and trailing spaces are allowed if you choose to work with strings.

Please specify what output format your code is returning.

Test Cases

1

┌┐
└┘

2

┌┐┌┐
└┌┐┘
┌└┘┐
└┘└┘

3

┌┐┌┐┌┐┌┐
└┌┐┘└┌┐┘
┌└┌┐┌┐┘┐
└┘└┌┐┘└┘
┌┐┌└┘┐┌┐
└┌└┘└┘┐┘
┌└┘┐┌└┘┐
└┘└┘└┘└┘

This is , so the lowest byte count for each language wins!

\$\endgroup\$
2
  • \$\begingroup\$ Can we use integer arrays? \$\endgroup\$
    – Noodle9
    Feb 7 at 9:08
  • \$\begingroup\$ @Noodle9 yes, so long as you specify its format \$\endgroup\$
    – zdimension
    Feb 7 at 9:37
7
\$\begingroup\$

JavaScript (ES6), 108 bytes

Returns an array of strings, with 0123 instead of ┌┐└┘.

f=(n,a=[w="01","23"])=>n?f(n-1,[...a,...a].map((s,i)=>i<w|i/w/3?s+s:s.slice(0,w)+a[i-w]+s.slice(-w)),w*=2):a

Try it online!

How?

This is a rather straightforward recursive construction of the pattern and is probably not the shortest method.

Below is an example for the 2nd iteration, with w = 2.

   0123  0123 4567  0123 4567
0  ABCD  ABCD|ABCD  ABCD|ABCD  \__ i < w -> s + s
1  EFGH  EFGH|EFGH  EFGH|EFGH  /
2  IJKL  IJ..|..KL  IJAB|CDKL  \
3  MNOP  MN..|..OP  MNEF|GHOP   \
         ----+----  ----+----    }-- s.slice(0, w) + a[i - w] + s.slice(-w)
4        AB..|..CD  ABIJ|KLCD   /
5        EF..|..GH  EFMN|OPGH  /
6        IJKL|IJKL  IJKL|IJKL  \__ i ≥ 3w -> s + s
7        MNOP|MNOP  MNOP|MNOP  /

Commented

f = (                     // f is a recursive function taking:
  n,                      //   n = number of iterations
  a = [                   //   a[] = output array initialized to:
    w = "01",             //     the pattern "01" (we also initialize w to "01")
    "23"                  //     the pattern "23"
  ]                       //
) =>                      //
  n ?                     // if n is not equal to 0:
    f(                    //   do a recursive call:
      n - 1,              //     decrement n
      [...a, ...a]        //     repeat a[] twice
      .map((s, i) =>      //     for each string s at index i in this array:
        i < w |           //       if i is less than w
        i / w / 3 ?       //       or i is greater than or equal to w * 3:
          s + s           //         just double the previous row
        :                 //       else:
          s.slice(0, w) + //         take the first half of s
          a[i - w] +      //         append the row i - w of the previous pattern
          s.slice(-w)     //         append the 2nd half of s
      ),                  //     end of map()
      w *= 2              //     double w
    )                     //   end of recursive call
  :                       // else:
    a                     //   return a[]
\$\endgroup\$
6
\$\begingroup\$

Charcoal, 29 21 bytes

┌F÷X²…⁰N²«Cιι‖BO⌈⊗ι

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

Print a quarter of the initial box. This gets fixed up on the first loop iteration. Note that while this character is not in Charcoal's code page, Charcoal has an escape sequence that encodes this character using three bytes; this sequence is not shown although the deverbosifier does account for it correctly.

F÷X²…⁰N²«

Take the powers of two from 1 up to (but not including) 2ⁿ, but then integer divide them by 2.

Cιι

Make a copy of the current figure, overwriting the bottom right quarter of the figure. (Except that i is zero on the first loop, so nothing happens.)

‖BO⌈⊗ι

Reflect the (original three quarters of) the figure to complete the new iteration.

\$\endgroup\$
6
\$\begingroup\$

Ruby, 103 101 bytes (UTF 8) or 95 93 bytes (ASCII)

->n{n<1?%w{┌┐ └┘}:(q=f[n-1];(-k=1<<n)...k).map{|i|s=q[i]*2;(t=i+j=k/2)/2%k<j&&s[j,k]=q[t];s}}

A function which returns an array of strings.

For n=0 the output is as follows:

UTF 8 ┌┐      Or   ASCII (my preferred   pq
      └┘            character choice)    bd

For higher values of n the function is called recursively to build up a square of double the proportions of the previous iteration (total 4 copies) line by line. For the middle rows, the lines are modified as necessary to overwrite a fifth copy of the previous iteration onto the centre of the pattern.

Try it online!

TIO link shows the UTF 8 version for easy verification. substituting the box characters with pq bd (or other ASCII characters) reduces the code to 93 bytes.

\$\endgroup\$
1
  • \$\begingroup\$ An alternative verification method is to take my Charcoal answer and make it print a p, after which Charcoal will automatically reflect it to q, b and d as necessary, thus duplicating this answer's output. \$\endgroup\$
    – Neil
    Feb 6 at 17:11
3
\$\begingroup\$

J, 46 42 bytes

([`(<@;~@(-:+i.)@#@[)`]},~@,.~)@[&0 i.@2 2

Try it online!

  • i.@2 2 returns:

     0 1
     2 3
    
  • (...)@[&0 Apply the verb (...) iteratively "input" number of times.

  • (<replace logic> ,~@,.~) - ,~@,.~ first zips the current input with itself ,.~, so with the starting input that becomes:

     0 1 0 1
     2 3 2 3
    

    and then appends that to itself ,~@:

     0 1 0 1
     2 3 2 3
     0 1 0 1
     2 3 2 3
    

    giving us the original input repeated 4 times in a square.

  • Next we replace the "center" with the original input. Imagine filling in a hole like so:

      0 1 0 1                0 1 0 1
      2     3   +  0 1  =    2 0 1 3
      0     1      2 3       0 2 3 1
      2 3 2 3                2 3 2 3
    
  • Here we're using the gerund form of Amend }, and all the rest is mechanics to specify which coordinates we replace:

  • (<@;~@(-:+i.)@#@[) That entire phrase, verbosely, converts (in our example) the 2x2 original input matrix into the J double boxed:

     ┌─────────┐
     │┌───┬───┐│
     ││1 2│1 2││
     │└───┴───┘│
     └─────────┘
    

    which is how we tell Amend: "Replace the intersection of rows 1 and 2, and columns 1 and 2 with..."

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

Wolfram Language (Mathematica), 60 55 bytes

Nest[Flatten[q/. 5-#->#&/@#&/@#,q]&,q={{1,3},{2,4}},#]&

Try it online!

Returns a matrix of integers - uses 1234 for ┌└┐┘.

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

Python 3, 217 \$\cdots\$ 119 102 bytes

Saved 9 a whopping 35 bytes thanks to Danis!!!
Saved 2 5 bytes thanks to att!!!

f=lambda n:n and[[(j,c)[j+c==3]for c in r for j in(i,i+1)]for r in f(n-1)for i in(0,2)]or[[0,1],[2,3]]

Try it online!

Uses integers \$0,1,2,3\$ instead of chars ,,,.
Inputs a zero-base integer \$n\$ and returns the \$2^{n+1}\times 2^{n+1}\$ T-Square fractal as a list of strings.

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

APL(Dyalog Unicode), 36 31 bytes SBCS

{⊃⍪/,/{⍵@(⌽⍵=⊖)x}¨⍵}⍣⎕⊢x←2 2⍴⍳4

Try it online!

A dfn submission which takes the number as left argument.

Uses ⎕IO←0 (0-indexing).

The box is represented as

01
23

which is then substituted exactly according to the question spec.

-5 bytes from Adám.

Explanation

{⊃⍪/,/{⍵@(⌽⍵=⊖)x}¨⍵}⍣⎕⊢x←2 2⍴⍳4
                       x←2 2⍴⍳4  store 0 1 in x
                                       2 3
                    ⍣⎕⊢          apply the following n times to the value of x:
{                ¨⍵}             substitute each number ⍵ with:
      {⍵@      x}                replace the following with ⍵ in the value of x:
         (⌽⍵=⊖)                  position of ⍵, flipped diagonally
  ⍪/,/                           join all the submatrices together
 ⊃                               and remove boxing.
\$\endgroup\$
1
  • \$\begingroup\$ -5: {⊃⍪/,/{⍵@(⌽⍵=⊖)x}¨⍵}⍣⎕⊢x←2 2⍴⍳4 \$\endgroup\$
    – Adám
    Feb 8 at 12:17
2
\$\begingroup\$

APL (Dyalog Classic), 42 bytes

{⍵≡0:2 2⍴⍳4⋄m⊣@((2*⍵-1)+⍳,⍨2*⍵)⍪⍨,⍨m←∇⍵-1}
{⍵≡0:2 2⍴⍳4⋄m⊣@((2*⍵-1)+⍳,⍨2*⍵)⍪⍨,⍨m←∇⍵-1}
 ⍵≡0:2 2⍴⍳4                                 ⍝ if ⍵ is 0 return the first result
           ⋄                                ⍝ otherwise
                                   m←∇⍵-1   ⍝ assign the last result to m
                               ⍪⍨,⍨         ⍝ duplicate in both directions
               ((2*⍵-1)+⍳,⍨2*⍵)             ⍝ indices corresponding to the middle section
            m⊣@                             ⍝ replace with m

Produces the fractal recursively using a pattern I spotted where you make 4 copies of the previous one and replace the middle. (I'm not sure if this works in general though, so if you have outputs for 4+ that would be great)

Try it online!

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

05AB1E, 30 bytes

3Ý2ô©IGNoTS-U2δиD«DÅsε®NèXǝ}Xǝ

Port of @Jonah's J answer, so make sure to upvote him as well!

Outputs as a matrix, with 0123 for ┌┐└┘ respectively.

Try it online or verify the first input amount of test cases (the footers transliterate it to the unicode boxes to pretty-print).

Explanation:

3Ý                # Push list [0,1,2,3]
  2ô              # Split it into parts of size 2: [[0,1],[2,3]]
    ©             # Store this 2x2 matrix in variable `®` (without popping)
     IG           # Loop `N` in the range [1,input):
       No         #  Push 2 to the power `N`
         TS-      #  Subtract [1,0] to create a pair: [2^N-1,2^N]
            U     #  Pop and store this pair in variable `X`
        δ         #  Map over each row of the matrix:
       2 и        #   And repeat it
                  #  (i.e. [[0,1],[2,3]] becomes [[0,1,0,1],[2,3,2,3]])
          D«      #  Merge a copy of itself:
                  #   [[0,1,0,1],[2,3,2,3],[0,1,0,1],[2,3,2,3]]
       D          #  Create a copy of the matrix
        Ås        #  Pop and push its middle two rows
          ε       #  Map over those two rows:
           ®      #   Push matrix [[0,1],[2,3]] from variable `®`
            Nè    #   Get the M'th row of this matrix based on the 0-based map-index `M`
              Xǝ  #   Insert those two values at indices `X` into the current row
          }Xǝ     #  After the map: insert the modified middle rows at indices `X` into
                  #  the matrix
                  # (after the loop, the resulting matrix is output implicitly)
\$\endgroup\$
3
  • 3
    \$\begingroup\$ +1 but i claim this answer as my intellectual property, as it contains ©NGN :D \$\endgroup\$
    – ngn
    Feb 9 at 13:43
  • 1
    \$\begingroup\$ btw, the code in the explanation and the tio link use ©IGN instead \$\endgroup\$
    – ngn
    Feb 9 at 14:12
  • 1
    \$\begingroup\$ @ngn Ah oops.. It was indeed supposed to be a I (for input). The N is used in the test suit link within the loop. Sorry, you can no longer claim intellectual property over it. ;p \$\endgroup\$ Feb 9 at 14:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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