Unfold in all directions
SOGL V0.12, 75 bytes
l√u²m√lH»{ā;l⁾:A∫Ba{bIwFIWhFbž;FIbI@ž}};}¹K⁴{ē2\⌡±e{@Κ};⁴┼┼};0E{ē2\⌡№:h++}╚
Try it Here!
This expects the input on the stack, so for ease-of-use I added ,
at the start. That can cause issues if the input contains only numbers so here
is a a test-suite for that.
70 bytes √lH»{ā;l⁾:A∫Ba{bIwFIWhFbž;FIbI@ž}};}¹K⁴{ē2\⌡±e{@Κ};⁴┼┼};0E{ē2\⌡№:h++}╚
works too, but as I only now implemented √
on strings and the documentation didn't mention that it would floor the length I won't count it.
Explanation:
creating a square from the input
l get the length of the input
√ get its square root
u floor that
² square it
m mold the input to that length
√ convert it to a square
creating the unfoldings of the square - the idea is to cut out the inner squares to a new array
lH»{ } (length-1)//2 times do
ā; push an empty array below ToS
l⁾ push ToS.length - 2 (ToS here is the square or the previous unfolding)
:A save a copy of that in the variable A
∫B } repeat that amount of times, saving iteration on B - cutting the inner square to the empty array
a{ } variable A times do
bIw get the b+1th row of the previous unfolding
FIW get the (current loops iteration + 1)th character of that
h swap the 2 items below ToS - so the stack now is [..., prevUnfolding, newArray, character]
Fbž at [current loops iteration; b] insert that character in the array
; swap the top 2 items - the stack now is [..., newArray, prevUnfolding]
FIbI@ž at [current loops iteration+1; b+1] insert a space
; get the now not empty array ontop of the stack
add the horizontal unfoldings
¹ wrap the stack in an array
K push the 1st item of that, which will function as the canvas
⁴{ } iterate over a copy of the remaining items
ē2\⌡ repeat (e++ divides by 2) times (default for the variable E is the input, which defaults to 0)
± reverse the array horizontally
e{ } repeat e times
@Κ add a space before ToS
;⁴┼┼ add that horizontally before and after the canvas
add the veertical unfoldings
; get the copy of the foldings above the canvas
0E reset the variable E to 0
{ } iterate the copy of the foldings
ē2\⌡ repeat (e++ divides by 2) times (default for the variable E is the input, which defaults to 0)
№ reverse the array vertically
:h++ add that vertically before and after the canvas
╚ center the canvas vertically
Charcoal, 120 109 bytes
AI§⪪IXLθ⁰·⁵.⁰ηFη⊞υ✂θ×ιηF⁴«AυεJ⁰¦⁰F÷⁺¹η²«F⁴«F⁻η⁺κꧧεκ⁺μκ↷A⮌EεEε§ξν嶻A⎇﹪ι²Eε⮌λ⮌εεA⎇‹ι²⁻⁺²⁺κκη⁻η⁺κκκ¿﹪ι²Mκ¹M¹κ
Try it online! Note that A
has since been changed to ≔
and the link reflects this. Explanation:
θ Input string
L Length
X ⁰·⁵ Raise to the power 0.5
I Cast to string
⪪ . Split on the decimal point
§ ⁰ Take the first element (integer part)
I Cast to integer
A η Assign to h
Calculates h = int(sqrt(len(q)))
. (Floor
was yet to be implemented...)
Fη⊞υ✂θ×ιη
Extracts the h
slices of length h
from the input. (Actually I don't bother truncating the slices to length h
.) I use a for
loop rather than a Map
because I need to Assign
the result of the Map
somewhere and this is nontrivial when dealing with a Slice
.
F⁴«
The unfolding happens 4 times, once for each direction (down, right, up, left as coded). The loop variable for this loop is i
.
Aυε
Take a copy of the sliced string.
J⁰¦⁰
Jump back to the origin of the canvas so that each unfold starts with the h
-by-h
square in the same place.
F÷⁺¹η²«
Repeat (h+1)/2
times; once for each unfold, plus once for the original square. The loop variable for this loop is k
.
F⁴«
Repeat 4 times, once for each side of the unfolded square. (I don't use the loop variable l
.)
F⁻η⁺κκ Loop h-2k times, loop variable `m`
§εκ Take the `k`th row
§ ⁺μκ Take the `k+m`th column
Implicitly print the character
Print one side of the unfolded square. Since this is the k
th unfold, the square's side is h-2k
, and takes characters k
away from the edge of the original square.
↷
Pivot ready to print the next side of the square.
Eε Map over the array (element `m`, index `n`)
Eε Map over the array (element `x`, index `p`)
§ξν Take the `n`th element of `x`
⮌ Reverse
A ε Replace the array with the result
Rotate the sliced string. (Yes, that's a ξ
. I don't get to use it often!) Eη
would also work for the outer Map
. The rotation also has the convenient side-effect of truncating the array's width to h
.
¶»
After printing the side, the cursor moves off the edge of the square. Printing one character fewer fails for squares of side 1 and is less golfy anyway. Having previously pivoted, printing a newline conveniently moves the cursor back to the corner.
﹪ι² Take `i` modulo 2
⎇ Choose either
⮌ε Reverse the array
Eε Map over the array (element `l`, index `m`)
⮌λ Reverse each element
A ε Replace the array with the result
Flip the square vertically or horizontally as appropriate.
⎇‹ι² If `i` < 2
⁺κκ Double `k`
⁺² Add 2
⁻ η Subtract `h`
⁺κκ Else double `k`
⁻η Subtract from `h`
≔ κ Assign back to `k`.
Calculate the displacement to the next unfold.
﹪ι² Take `i` modulo 2
¿ If not zero
Mκ¹ `k` across and 1 down
M¹κ Else 1 across and `k` down
Move horizontally or vertically to the next unfold as appropriate.
Here's a link to the 97-byte version obtained by making use of all the latest Charcoal features including Floor
: Try it online! Link is to verbose version of code.