30
\$\begingroup\$

The Challenge

Given a string, output the text in the shape of a square.

You can assume that the text will always fit in a square, and that it will never be an empty string.

You can also assume it will never have newlines.

Example

Input:
Hi, world
Output:
Hi,
 wo
rld

Test Cases

Input:
Hi, world! Hello
Output:
Hi, 
worl
d! H
ello
Input:
Lorem ipsum dolor sit amt
Output:
Lorem
 ipsu
m dol
or si
t amt
Input:
H
Output:
H

Rules

  • This is , so shortest answer in bytes wins! Tiebreaker is most upvoted answer.
  • Standard loopholes are forbidden.
asked Aug 5, 2016 at 22:20
\$\endgroup\$
7
  • \$\begingroup\$ Can we assume that the input will never have new lines? \$\endgroup\$ Commented Aug 6, 2016 at 2:13
  • \$\begingroup\$ @MayorMonty yep. \$\endgroup\$ Commented Aug 6, 2016 at 2:20
  • 2
    \$\begingroup\$ Can we output array of strings instead? \$\endgroup\$ Commented Aug 6, 2016 at 5:10
  • \$\begingroup\$ @LeakyNun no 15 chars \$\endgroup\$ Commented Aug 6, 2016 at 16:58
  • 2
    \$\begingroup\$ May we print with a trailing newline? \$\endgroup\$ Commented Oct 4, 2017 at 15:53

72 Answers 72

1
2 3
22
\$\begingroup\$

Vim, (削除) 59, 57 (削除ここまで), 48 bytes/keystrokes

$:let @q=float2nr(sqrt(col('.')))."|li<C-v><cr><C-v><esc>@q"<cr>@q

Since V is backwards compatible, you can Try it online!

I randomly received an upvote on this answer, so I looked over it again. My vim-golfing skills have greatly increased over the last 7 months, so I saw that this answer was very poorly golfed. This one is much better.

answered Aug 5, 2016 at 23:46
\$\endgroup\$
15
\$\begingroup\$

Brainfuck, (削除) 116 (削除ここまで) 112 bytes

>>>>,[[<]<<+>>>[>],]<[<]<+<[>>+<[-<-<+>>]<<++[->>+<<]>]>[-]>>[<[->.[-]<[->+<]<+[->+<]>>]++++++++++.[-]<[->+<]>>]

Try it online!

Safe in flavours of BF that does not mask the cells with 256, does not support null bytes.

Remove the initial right arrows if the flavour supports negative memory for 4 bytes saved.

Explanation

The program is divided into 3 stages:

Stage 1: >>>>,[[<]<<+>>>[>],]<[<]
Stage 2: <+<[>>+<[-<-<+>>]<<++[->>+<<]>]>[-]>>
Stage 3: [<[->.[-]<[->+<]<+[->+<]>>]++++++++++.[-]<[->+<]>>]

Stage 1

In this stage, we put all the characters onto the tape, while keeping count of the number of characters.

This is the tape for the input abcdefghi after this tape:

000 009 000 000 095 096 097 098 099 100 101 102 103
 ^

The 009 is the count.

For each character, we move the the first zero on the left [<] and then add one to the count <<+>>>, and then move to the rightmost zero [>] to get ready for the next character.

Stage 2

This stage does the square root of the length stored in the second cell.

It keeps subtracting by 1, 3, 5, 7, ... until the number reaches zero, while keeping check of the number of iterations.

It works because square numbers can be expressed as 1 + 3 + 5 + ....

Stage 3

Denote the square root of the length found above as n.

This stage outputs n characters at a time, and then output a newline, until the tape is cleared.

answered Aug 6, 2016 at 7:05
\$\endgroup\$
0
11
\$\begingroup\$

Python 2, 55 bytes

s=input()
n=int(len(s)**.5)
while s:print s[:n];s=s[n:]
answered Aug 5, 2016 at 22:35
\$\endgroup\$
1
  • \$\begingroup\$ Interesting is a=lambda s,a=0:s[a:(int(c:=a+len(s)**0.5))]+"\n"+(a(s[c:],c)if s else"") implementating as a recursive function but unfortunately it errors and is also longer. \$\endgroup\$ Commented Jan 14, 2024 at 23:27
10
\$\begingroup\$

05AB1E, 5 bytes

Dgtô«

Try it online!

D duplicate a (implicit input)
g length of a
t square root of a
ô push a split in pieces of b
« join by newlines (implicit output)
answered Aug 5, 2016 at 23:16
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Great answer. But how does it work? Could you please edit to add an explanation? \$\endgroup\$ Commented Aug 6, 2016 at 13:22
  • \$\begingroup\$ @grooveplex done. \$\endgroup\$ Commented Aug 6, 2016 at 15:51
  • \$\begingroup\$ Very impressive! \$\endgroup\$ Commented Jun 7, 2017 at 17:44
  • 3
    \$\begingroup\$ It's weird to see old 05AB1E answers where » is newlines now. \$\endgroup\$ Commented Jun 13, 2017 at 17:36
8
\$\begingroup\$

MATL, 6 bytes

tnX^e!

Try it online!

Explanation

t % Take input implicitly. Push another copy
n % Get number of elements of the copy
X^ % Take square root
e % Reshape the input into that number of rows, in column-major order
 % (which means: down, then across)
! % Transpose so that text reads horizontally. Implicitly display
answered Aug 5, 2016 at 22:44
\$\endgroup\$
3
  • 1
    \$\begingroup\$ square "toor"? :P \$\endgroup\$ Commented Aug 5, 2016 at 22:48
  • \$\begingroup\$ @daHugLenny :-D. Corrected \$\endgroup\$ Commented Aug 5, 2016 at 22:48
  • 4
    \$\begingroup\$ @daHugLenny That's the inverse of the square root. ;-) \$\endgroup\$ Commented Aug 6, 2016 at 5:46
7
\$\begingroup\$

Jelly, (削除) 8 (削除ここまで) 7 bytes

sLÆ1⁄2$j7

Saved a byte thanks to @Dennis.

Try it online.

Explanation

sLÆ1⁄2$j7 Input: string S
 $ Monadic chain
 L Get the length of S
 Æ1⁄2 Take the integer square root of it, call it n
s Split S into chunks of size n
 j7 Join using newline
answered Aug 5, 2016 at 22:29
\$\endgroup\$
4
  • 2
    \$\begingroup\$ œs and s do the same thing here. \$\endgroup\$ Commented Aug 5, 2016 at 22:48
  • \$\begingroup\$ Why does ½ not work instead of ƽ? \$\endgroup\$ Commented Aug 5, 2016 at 22:48
  • \$\begingroup\$ @LuisMendo Because it returns a float. I'll patch s and œs so they cast to int. \$\endgroup\$ Commented Aug 5, 2016 at 22:49
  • \$\begingroup\$ @Dennis long-awaited patch still waiting... \$\endgroup\$ Commented May 15, 2017 at 10:51
7
\$\begingroup\$

JavaScript (ES7), 49 bytes

s=>s.match(eval(`/.{${s.length**.5}}/g`)).join`
`

44 bytes in Firefox Nightly 43-46 only (** was introduced some time between Firefox Nightly 42 and 43 and g as a separate parameter was removed some time between Firefox Nightly 46 and 47):

s=>s.match(`.{${s.length**.5}}`,`g`).join`
`
answered Aug 6, 2016 at 0:09
\$\endgroup\$
10
  • \$\begingroup\$ In the first version why do you need the + in s.length*+.5 \$\endgroup\$ Commented Aug 6, 2016 at 1:54
  • \$\begingroup\$ I've never seen the *+ syntax before. Could someone please explain it? \$\endgroup\$ Commented Aug 6, 2016 at 2:25
  • \$\begingroup\$ He probably means **. \$\endgroup\$ Commented Aug 6, 2016 at 5:53
  • \$\begingroup\$ @MayorMonty Yeah it was a typo sorry. \$\endgroup\$ Commented Aug 6, 2016 at 9:37
  • \$\begingroup\$ @Downgoat It was a typo sorry. \$\endgroup\$ Commented Aug 6, 2016 at 9:38
7
\$\begingroup\$

J, 9 bytes

$~,~@%:@#

This is a monadic hook over the input string:

$~ ,~@%:@#

The right tine is a series of compositions:

,~ @ %: @ #

The left is a shaping verb, switched such that it works in the hook format.

Here are some intermediate results:

 # 'hiya'
4
 %:@# 'hiya'
2
 ,~@%:@# 'hiya'
2 2

In words:

 size =: #
 sqrt =: %:
 dup =: ,~
 on =: @
 shape =: $~
 block =: shape dup on sqrt on size
 block 'Hello, World! :)'
Hell
o, W
orld
! :)
answered Aug 6, 2016 at 5:51
\$\endgroup\$
5
  • 2
    \$\begingroup\$ I like the fact that $~,~@ resembles some sort of emoticon but @ seems weird for an ear but & fits better, or $~,~& \$\endgroup\$ Commented Aug 6, 2016 at 6:13
  • 1
    \$\begingroup\$ And I do suppose they are functionally equivalent. Well, mostly. One lets you hear better than the other ;) \$\endgroup\$ Commented Aug 6, 2016 at 6:14
  • 1
    \$\begingroup\$ +1 for having your score be n². Mine is too :) \$\endgroup\$ Commented Aug 6, 2016 at 22:49
  • \$\begingroup\$ @DigitalTrauma fun! +1 likewise! \$\endgroup\$ Commented Aug 6, 2016 at 22:51
  • 1
    \$\begingroup\$ $~2#%:@# is 8. The left part of a fork can be a constant. \$\endgroup\$ Commented Oct 5, 2017 at 11:22
5
\$\begingroup\$

C, 64 bytes

Call f() with the string to square.

m;f(char*s){for(m=sqrt(strlen(s));*s;s+=m)printf("%.*s\n",m,s);}

Try it on ideone.

answered Aug 6, 2016 at 2:30
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Can you make it work with implicit int argument instead of char*? \$\endgroup\$ Commented Aug 7, 2016 at 7:31
  • \$\begingroup\$ I don't think so. It needs to be dereferenced, so a numeric type won't work, and it can't be an int* since that would scale wrong when adding. \$\endgroup\$ Commented Aug 7, 2016 at 12:27
  • \$\begingroup\$ Suggest s+=write(puts(""),s,m)); instead of s+=m)printf("%.*s\n",m,s); \$\endgroup\$ Commented Oct 11, 2018 at 6:16
5
\$\begingroup\$

Perl, 23 + 4 (-pF flags) = 27 bytes

-2 bytes thanks to @DomHastings
-1 bytes thanks to @DomHastings

$==sqrt@F;s/.{$=}/$&
/g

Try it online!

Expanations : computes the square root (lets call it S for the explanation) of the size of the input (it will be always be an integer) (@F is used in scalar context, thus returning its size), then add a newline after each bloc of S characters.

answered Aug 5, 2016 at 22:30
\$\endgroup\$
6
  • \$\begingroup\$ Nice use of $@, ;) You can save a byte using y///c instead of length and I think you can use a literal new line as well. I was looking as trying to do something with setting ,ドル and matching, but I think this is much shorter! \$\endgroup\$ Commented Aug 5, 2016 at 22:52
  • 1
    \$\begingroup\$ @DomHastings Yea, I thought you'd like the $@! Thanks for the y///c, I tend to forget that it exists. \$\endgroup\$ Commented Aug 5, 2016 at 23:21
  • 1
    \$\begingroup\$ @DomHastings managed to save 1 byte by using $= instead of $@, which allows to not use -l flag. \$\endgroup\$ Commented Aug 7, 2016 at 12:26
  • \$\begingroup\$ Good going! Good to use the magic variables for genuine reasons too! \$\endgroup\$ Commented Aug 7, 2016 at 14:00
  • \$\begingroup\$ Hey, hope you're doing alright! This got bumped to homepage and I noticed another optimisation for -1: 23 bytes code + 4 for -pF \$\endgroup\$ Commented Oct 5, 2017 at 15:16
4
\$\begingroup\$

05AB1E, (削除) 8 (削除ここまで) 6 bytes

Thanks to @quartata for letting me know about the square-root function

Dgtô¶ý

Try it online!

Explanation

D Implicit input. Duplicate
g Number of elements
t Square root
ô Split into chunks of that length
¶ Push newline character
ý Join list by newlines. Implicit display
answered Aug 5, 2016 at 23:11
\$\endgroup\$
6
  • \$\begingroup\$ Very nice! Also, « is short for joining on newlines :). \$\endgroup\$ Commented Aug 5, 2016 at 23:13
  • 1
    \$\begingroup\$ @Adnan Thanks! Now I have outgolfed myself :-D \$\endgroup\$ Commented Aug 5, 2016 at 23:21
  • \$\begingroup\$ I have rolled back to my 6-byte version because there was a previous answer with « \$\endgroup\$ Commented Aug 5, 2016 at 23:52
  • 1
    \$\begingroup\$ Oh, that's too bad :( \$\endgroup\$ Commented Aug 5, 2016 at 23:56
  • \$\begingroup\$ Does anyone else feel like those languages specifically created for code golf are kinda ruining the appeal of this whole thing? \$\endgroup\$ Commented Aug 7, 2016 at 16:15
4
\$\begingroup\$

Dyalog APL, 10 bytes

⊢⍴⍨2⍴.5*⍨≢

Explanation:

 ≢ length of the argument 
 .5*⍨ square root 
 2⍴ reshape that to a length-2 vector
⊢⍴⍨ reshape the input by that vector

Tests:

 (⊢⍴⍨2⍴.5*⍨≢)'Hi, world'
Hi,
 wo
rld
 (⊢⍴⍨2⍴.5*⍨≢)'Hi, world! Hello'
Hi, 
worl
d! H
ello
 (⊢⍴⍨2⍴.5*⍨≢)'Lorem ipsum dolor sit amt'
Lorem
 ipsu
m dol
or si
t amt
 (⊢⍴⍨2⍴.5*⍨≢) 'H'
H
answered Aug 6, 2016 at 14:21
\$\endgroup\$
4
\$\begingroup\$

Python, (削除) 94 (削除ここまで) (削除) 75 (削除ここまで) (削除) 71 (削除ここまで) (削除) 65 (削除ここまで) 63 bytes

import re;lambda r:"\n".join(re.findall("."*int(len(r)**.5),r))

Old version:

lambda r:"\n".join(map("".join,zip(*[iter(r)]*int(len(r)**.5))))
answered Aug 5, 2016 at 22:25
\$\endgroup\$
4
  • \$\begingroup\$ Note that you can use input() by default to receive input in quotes, unless you want to specifically remove that option. \$\endgroup\$ Commented Aug 5, 2016 at 22:34
  • \$\begingroup\$ @xnor Oh wow, a few days ago I was wondering if I could use quotes on input... \$\endgroup\$ Commented Aug 5, 2016 at 22:42
  • \$\begingroup\$ Wouldn't it be shorter to use a lambda? \$\endgroup\$ Commented Aug 6, 2016 at 4:58
  • \$\begingroup\$ @LeakyNun true... \$\endgroup\$ Commented Aug 6, 2016 at 15:54
4
\$\begingroup\$

zsh, (削除) 36 (削除ここまで) 33 bytes

fold -`tr -d .<<<$[$#1**.5]`<<<1ドル

Try it online!

Takes input as a command line argument, outputs to STDOUT.

 $#1 # get the length of the input string
 $[ **.5] # take it to the .5 power (sqrt)
 <<< # and pass the result to
 tr -d . # tr, to delete the trailing decimal point
 # (sqrt(9) is 3. instead of 3)
 -` ` # give the result as a command line flag to
fold # the fold util, which wraps at nth column
 <<<1ドル # pass the input as input to fold
answered Aug 6, 2016 at 5:31
\$\endgroup\$
2
  • \$\begingroup\$ +1 for having your score be n². Mine is too :) \$\endgroup\$ Commented Aug 6, 2016 at 22:49
  • \$\begingroup\$ @DigitalTrauma Should you retract your upvote now? \$\endgroup\$ Commented Dec 26, 2019 at 16:50
4
\$\begingroup\$

Cheddar, 27 bytes

s->s.chunk(s.len**.5).vfuse

I added the .chunk function a while ago but I removed it in the transition to the new stdlib format and forgot to re-add it. Cheddar has a dedicated sqrt operator but **.5 is shorter

Try it online!

Explanation

s -> // Function with argument s
 s.chunk( // Chunk it into pieces of size...
 s.len ** .5 // Square root of length.
 ).vfuse // Vertical-fuse. Join on newlines
emanresu A
46.2k5 gold badges111 silver badges257 bronze badges
answered Aug 6, 2016 at 2:20
\$\endgroup\$
0
3
\$\begingroup\$

CJam, 8 bytes

l_,mQ/N*

Try it online!

Explanation

l e# Read line from input
_, e# Duplicate. Get length 
mQ e# Integer square root
/ e# Split into pieces of that size
N* e# Join by newline. Implicitly display
answered Aug 5, 2016 at 22:54
\$\endgroup\$
3
\$\begingroup\$

Pyth, 8 bytes

jcs@lQ2Q

Try it online

How it works

 lQ length of input
 @ 2 square root
 s floor
 c Q chop input into that many equal pieces
j join on newline
answered Aug 5, 2016 at 23:51
\$\endgroup\$
3
\$\begingroup\$

Bash + GNU utilities, 25

fold -`dc -e${#1}vp`<<<1ドル

Not so different to @Doorknob's answer, but dc is a shorter way to get the square root.

answered Aug 6, 2016 at 22:47
\$\endgroup\$
3
\$\begingroup\$

ESMin, 11 chars / 14 bytes

ѨĊ(ï,√ ïꝈ⸩Ė⬮

Try it here (ES6 browsers only).

Generated using this code (run in the interpreter's browser console):

c.value=`Ѩ${alias(_,'chunk')}(ï,√ ïꝈ⸩${alias(Array.prototype,'mjoin')}⬮`
answered Aug 22, 2016 at 1:11
\$\endgroup\$
3
\$\begingroup\$

Brainfuck, 83 bytes

,[>+[>+<-],]
>
[
 >>[<+<-->>-]
 +<[>+<-]
 <-
]
<<
[
 [<]
 >.,
 >[>]
 >>+>-[<]
 <[[>+<-]++++++++++.,<<]
 <
]

Try it online!

This uses the same idea as Leaky Nun's answer. He asked for help golfing it in chat, then suggested that I add this as a new answer. (Actually what I wrote in chat was an 84-byte solution very similar to this.)

For the sake of comparison, an extra > is needed at the beginning for brainfuck implementations that don't allow negative memory addresses.

As expected, this finds the length of the input, then takes the square root, then prints the lines accordingly. It takes advantage of perfect squares being partial sums of 1 + 3 + 5 ....

answered Aug 22, 2016 at 1:27
\$\endgroup\$
3
\$\begingroup\$

Brain-Flak, (削除) 110 (削除ここまで) 96 bytes

([]<>){({}{}(({}[()])))}{}{({}()<(({})<{({}()<<>({}<>)>)}{}((()()()()()){})>)>)}{}{}{({}<>)<>}<>

Try it online!

Second solution, 96 bytes

(([]<>)<{({}({})({}[()]))}{}>){({}(({})<{({}()<<>({}<>)>)}{}((()()()()()){})>))}{}{}{({}<>)<>}<>

Try it online!

Explanation

Here I explain the first solution, both are the same length but I like the first one because it is cooler and employs some nice tricks.

The most important part of the code is a modified square root function I wrote some time ago. The original version was

{({}[({})({}())])}{}

And this works, but we actually want two copies of the negative square root. Why? We need two copies because we are looping through the string at two levels, one to make the lines and one to count the number of lines. We want it to be negative because looping with negatives is cheaper.

To make this negative we move around the [...] so it looks like this

{({}({})({}[()]))}{}

To make two copies we change when pops occur

{({}{}(({}[()])))}{}

Now that we have that bit we can put it together with a stack height to get the first chunk of code we need.

([]<>){({}{}(({}[()])))}{}

We move to the offstack because our square root function needs two free zeros for computation, and because it makes stuff a little bit cheaper int he future in terms of stack switching.

Now we construct the main loop

{({}()<(({})<{({}()<<>({}<>)>)}{}((()()()()()){})>)>)}{}{}

This is pretty straight forward, we loop n times each time moving n items and capping it with a new line (ASCII 10).

Once the loop is done we need to reverse the order of our output so we just tack on a standard reverse construct.

{({}<>)<>}<>
answered Oct 4, 2017 at 16:55
\$\endgroup\$
1
  • \$\begingroup\$ Also 96 \$\endgroup\$ Commented Oct 4, 2017 at 17:23
2
\$\begingroup\$

PHP, 51 bytes

<?=join("
",str_split($x=$argv[1],strlen($x)**.5));
answered Aug 5, 2016 at 23:56
\$\endgroup\$
2
\$\begingroup\$

Perl 6, 38 bytes

$_=get;.put for .comb: .chars.sqrt.Int

Explanation:

$_ = get; # get a single line of input
$_.put # print with trailing newline
for # every one of the following:
$_.comb: # the input split into
$_.chars.sqrt.Int # chunks of the appropriate size
answered Aug 6, 2016 at 0:38
\$\endgroup\$
2
\$\begingroup\$

Cheddar, 57 bytes

n->(m->(|>m).map(i->n.slice(i*m,i*m+m)).vfuse)(n.len**.5)

Since variables are broken, I would have to pass in variables through lambda application.

Also, it turns out that even if variables worked, it would still be shorter to use lambda application.

Usage

cheddar> (n->(m->(|>m).map(i->n.slice(i*m,i*m+m)).vfuse)(n.len**.5))("abcd")
"ab
cd"
answered Aug 6, 2016 at 4:22
\$\endgroup\$
2
\$\begingroup\$

Pyke, 5 bytes

l,fnJ

Try it here!

answered Aug 6, 2016 at 7:15
\$\endgroup\$
2
\$\begingroup\$

Java 1.7, 110 bytes

void f(String s){for(int i=-1,k=(int)Math.sqrt(s.length());++i<k;)System.out.println(s.substring(i*k,i*k+k));}

Try it! (Ideone)

I tried another approach with a function returning the result as a string, but just having to declare the string and the return statement is already more expensive (byte-count-wise) than the print statement.

Gotta love Java's verbosity... :)

answered Aug 6, 2016 at 14:39
\$\endgroup\$
1
  • \$\begingroup\$ Nice answer +1. You can golf it by 1 byte by using i=0, i<k and s.substring(i*k,i++*k+k) instead of i=-1, ++i<k, s.substring(i*k,i*k+k). Also, usually we use just Java 7 instead of Java 1.7, but it's good that you've added it, a lot of people forget to do so. \$\endgroup\$ Commented Sep 7, 2016 at 8:58
2
\$\begingroup\$

R, (削除) 59 (削除ここまで) 54 bytes

function(s)write(el(strsplit(s,'')),1,nchar(s)^.5,,'')

Try it online!

Prints with a trailing newline. Surprisingly short, considering how badly R handles strings.

answered Oct 4, 2017 at 15:53
\$\endgroup\$
2
\$\begingroup\$

PowerShell, 56 (削除) 58 (削除ここまで) (削除) 61 (削除ここまで) bytes

param($i)$i-replace".{$([Math]::Sqrt($i.Length))}",'$&
'
answered Aug 6, 2016 at 11:11
\$\endgroup\$
1
2
\$\begingroup\$

Ruby -p, (削除) 40 (削除ここまで) (削除) 33 (削除ここまで) 30 bytes

-7 bytes from @Jordan.

gsub(/#{?.*~/$/**0.5}/){$&+$/}

Try it online!

answered Aug 6, 2016 at 1:48
\$\endgroup\$
0
2
\$\begingroup\$

K (ngn/k), 11 bytes

{(2#%#x)#x}

Try it online!


the bracketed expression returns list 5 5 for input "Lorem ipsum dolor sit amt". it reads "2 take sqrt count x", where x is the string argument. then (5 5)#x means "cut x into 5 lists each of length 5". with this we get:

 {(2#%#x)#x}"Lorem ipsum dolor sit amt"
("Lorem";" ipsu";"m dol";"or si";"t amt")
answered Aug 20, 2019 at 10:29
\$\endgroup\$
1
2 3

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.