14
\$\begingroup\$

Input:

A string

Output:

1) First we take remove character at the end of the input-string until we are left with a length that is a square (i.e. 1, 4, 9, 16, 25, 36, etc.)
So abcdefghijklmnopqrstuvwxyz (length 26) becomes abcdefghijklmnopqrstuvwxy (length 25).

2) Then we put this in a square, one line at a time, left to right:

abcde
fghij
klmno
pqrst
uvwxy

3) We fold it in all four directions, like this (we keep unfolding until the outer folded 'block' has no inner characters to unfold anymore):

      m
     qrs
     l n
     ghi
    abcde
 ihgf   jihg
mn lk   on lm
 srqp   tsrq
    uvwxy
     qrs
     l n
     ghi
      m

Some things to note, when we fold outward, we basically mirror like this (numbers added as clarification, which represents the 'indexes' in these examples):

When we fold out the left side:

 123    to:   321 123
fghij         ihgf   j

When we fold the right side:

 123    to:    123 321
fghij         f   jihg

When we fold upwards:

            3q
            2l
            1g
  b   to:    b
 1g         1
 2l         2
 3q         3
  v          v

When we fold downwards:

 b          b
1g         1
2l         2
3q         3
 v   to:    v
           3q
           2l
           1g

Challenge rules:

  • You can assume the input will always have at least 1 character (which will also be the output).
  • Output format is flexible, so you can print to STDOUT or STDERR; return as string-array/list or character 2D-array; single string with new-lines; etc.
  • The input will only contain alphanumeric characters (a-zA-Z0-9)
  • You can also use a non-alphanumeric character to fill up the spaces in and/or around the ASCII-art output, like a dot ..
  • Trailing spaces and a single trailing new-line are optional.
  • We continue unfolding until the outer folded 'block' has no more centers to unfold.

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code.
  • Also, please add an explanation if necessary.

Test cases:

Input: abcdefghijklmnopqrstuvwxy
Output:
      m
     qrs
     l n
     ghi
    abcde
 ihgf   jihg
mn lk   on lm
 srqp   tsrq
    uvwxy
     qrs
     l n
     ghi
      m

Input: A
Ouput:
A

Input: ThisIsATest
Output:
  I
 Thi
Is sI
 ATe
  I

Input: HowAboutAVeryLongExampleWhichIsAlsoAnEvenSquareInsteadOfOddOneAndExceeds64Chars
Output:

               An
               ch
              xamp
              i  I
              o  E
              quar
             steadO
             S    e
             s    v
             h    s
             E    l
             VeryLo
            HowAbout
      oLyreVA      noLyreV
  xampl    Eg      el    Examp
hci  Is    hW      As    hi  Ihc
nAo  Ev    sl      ev    so  EnA
  quare    Sn      Ie    Squar
      Odaetsn      fOdaets
            OddOneAn
             steadO
             S    e
             s    v
             h    s
             E    l
             VeryLo
              xamp
              i  I
              o  E
              quar
               An
               ch

Input: Lenght7
Output:
Le
ng

Input: abc
Output:
a
\$\endgroup\$
  • \$\begingroup\$ there's a mistake in the test for "HowAboutAVeryLongExampleWhichIsAlsoAnEvenSquareInsteadOfOddOneAndExceeds64Chars": 'h'->'i' near the bottom of the output \$\endgroup\$ – ngn Nov 26 '17 at 2:06
5
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ Your 70 byte version is valid as non-competing isn't a thing anymore. \$\endgroup\$ – Shaggy Aug 29 '17 at 9:29
  • \$\begingroup\$ @Shaggy The 75 byte version is valid only because of that as before this challenge only worked on numbers. The reason why I'm not counting the 75 byte version is because I feel like it falls under the loophole of adding a built-in just for a challenge \$\endgroup\$ – dzaima Aug 29 '17 at 10:21
4
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ Are you sure this works? TIO just seems to raise an error. \$\endgroup\$ – LyricLy Aug 28 '17 at 23:23
  • \$\begingroup\$ @LyricLy Bah, I thought I was being clever, but failed to actually check that it worked. I'll revert the change. \$\endgroup\$ – Neil Aug 28 '17 at 23:46
  • 1
    \$\begingroup\$ Crap forgot to make floats work in slices oops \$\endgroup\$ – ASCII-only Aug 29 '17 at 0:25
  • \$\begingroup\$ @ASCII-only Doesn't help me, I need to truncate to integer before multiplying anyway. \$\endgroup\$ – Neil Aug 29 '17 at 8:03
  • \$\begingroup\$ Right. Well I'm adding floor soon so it won't be as much of a problem :P \$\endgroup\$ – ASCII-only Aug 29 '17 at 8:07

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.