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 code-golf, so shortest answer in bytes wins! Tiebreaker is most upvoted answer.
- Standard loopholes are forbidden.
-
\$\begingroup\$ Can we assume that the input will never have new lines? \$\endgroup\$bren– bren2016年08月06日 02:13:47 +00:00Commented Aug 6, 2016 at 2:13
-
\$\begingroup\$ @MayorMonty yep. \$\endgroup\$acrolith– acrolith2016年08月06日 02:20:21 +00:00Commented Aug 6, 2016 at 2:20
-
2\$\begingroup\$ Can we output array of strings instead? \$\endgroup\$Leaky Nun– Leaky Nun2016年08月06日 05:10:09 +00:00Commented Aug 6, 2016 at 5:10
-
\$\begingroup\$ @LeakyNun no 15 chars \$\endgroup\$acrolith– acrolith2016年08月06日 16:58:13 +00:00Commented Aug 6, 2016 at 16:58
-
2\$\begingroup\$ May we print with a trailing newline? \$\endgroup\$Giuseppe– Giuseppe2017年10月04日 15:53:54 +00:00Commented Oct 4, 2017 at 15:53
72 Answers 72
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.
Brainfuck, (削除) 116 (削除ここまで) 112 bytes
>>>>,[[<]<<+>>>[>],]<[<]<+<[>>+<[-<-<+>>]<<++[->>+<<]>]>[-]>>[<[->.[-]<[->+<]<+[->+<]>>]++++++++++.[-]<[->+<]>>]
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.
Python 2, 55 bytes
s=input()
n=int(len(s)**.5)
while s:print s[:n];s=s[n:]
-
\$\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\$Alan Bagel– Alan Bagel2024年01月14日 23:27:01 +00:00Commented Jan 14, 2024 at 23:27
05AB1E, 5 bytes
Dgtô«
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)
-
1\$\begingroup\$ Great answer. But how does it work? Could you please edit to add an explanation? \$\endgroup\$grooveplex– grooveplex2016年08月06日 13:22:57 +00:00Commented Aug 6, 2016 at 13:22
-
\$\begingroup\$ @grooveplex done. \$\endgroup\$acrolith– acrolith2016年08月06日 15:51:21 +00:00Commented Aug 6, 2016 at 15:51
-
\$\begingroup\$ Very impressive! \$\endgroup\$Gryphon– Gryphon2017年06月07日 17:44:22 +00:00Commented Jun 7, 2017 at 17:44
-
3\$\begingroup\$ It's weird to see old 05AB1E answers where
»is newlines now. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2017年06月13日 17:36:36 +00:00Commented Jun 13, 2017 at 17:36
MATL, 6 bytes
tnX^e!
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
-
1\$\begingroup\$ square "toor"? :P \$\endgroup\$acrolith– acrolith2016年08月05日 22:48:15 +00:00Commented Aug 5, 2016 at 22:48
-
\$\begingroup\$ @daHugLenny :-D. Corrected \$\endgroup\$Luis Mendo– Luis Mendo2016年08月05日 22:48:53 +00:00Commented Aug 5, 2016 at 22:48
-
4\$\begingroup\$ @daHugLenny That's the inverse of the square root. ;-) \$\endgroup\$WBT– WBT2016年08月06日 05:46:05 +00:00Commented Aug 6, 2016 at 5:46
Jelly, (削除) 8 (削除ここまで) 7 bytes
sLÆ1⁄2$j7
Saved a byte thanks to @Dennis.
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
-
2\$\begingroup\$
œsandsdo the same thing here. \$\endgroup\$Dennis– Dennis2016年08月05日 22:48:11 +00:00Commented Aug 5, 2016 at 22:48 -
\$\begingroup\$ Why does
½not work instead ofƽ? \$\endgroup\$Luis Mendo– Luis Mendo2016年08月05日 22:48:16 +00:00Commented Aug 5, 2016 at 22:48 -
\$\begingroup\$ @LuisMendo Because it returns a float. I'll patch
sandœsso they cast to int. \$\endgroup\$Dennis– Dennis2016年08月05日 22:49:08 +00:00Commented Aug 5, 2016 at 22:49 -
\$\begingroup\$ @Dennis long-awaited patch still waiting... \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年05月15日 10:51:26 +00:00Commented May 15, 2017 at 10:51
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`
`
-
\$\begingroup\$ In the first version why do you need the
+ins.length*+.5\$\endgroup\$Downgoat– Downgoat2016年08月06日 01:54:25 +00:00Commented Aug 6, 2016 at 1:54 -
\$\begingroup\$ I've never seen the
*+syntax before. Could someone please explain it? \$\endgroup\$bren– bren2016年08月06日 02:25:05 +00:00Commented Aug 6, 2016 at 2:25 -
\$\begingroup\$ He probably means
**. \$\endgroup\$Conor O'Brien– Conor O'Brien2016年08月06日 05:53:57 +00:00Commented Aug 6, 2016 at 5:53 -
\$\begingroup\$ @MayorMonty Yeah it was a typo sorry. \$\endgroup\$Neil– Neil2016年08月06日 09:37:17 +00:00Commented Aug 6, 2016 at 9:37
-
\$\begingroup\$ @Downgoat It was a typo sorry. \$\endgroup\$Neil– Neil2016年08月06日 09:38:29 +00:00Commented Aug 6, 2016 at 9:38
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
! :)
-
2\$\begingroup\$ I like the fact that
$~,~@resembles some sort of emoticon but@seems weird for an ear but&fits better, or$~,~&\$\endgroup\$miles– miles2016年08月06日 06:13:18 +00:00Commented 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\$Conor O'Brien– Conor O'Brien2016年08月06日 06:14:32 +00:00Commented Aug 6, 2016 at 6:14
-
1\$\begingroup\$ +1 for having your score be n². Mine is too :) \$\endgroup\$Digital Trauma– Digital Trauma2016年08月06日 22:49:42 +00:00Commented Aug 6, 2016 at 22:49
-
\$\begingroup\$ @DigitalTrauma fun! +1 likewise! \$\endgroup\$Conor O'Brien– Conor O'Brien2016年08月06日 22:51:06 +00:00Commented Aug 6, 2016 at 22:51
-
1\$\begingroup\$
$~2#%:@#is 8. The left part of a fork can be a constant. \$\endgroup\$FrownyFrog– FrownyFrog2017年10月05日 11:22:03 +00:00Commented Oct 5, 2017 at 11:22
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);}
-
1\$\begingroup\$ Can you make it work with implicit
intargument instead ofchar*? \$\endgroup\$anatolyg– anatolyg2016年08月07日 07:31:58 +00:00Commented 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\$owacoder– owacoder2016年08月07日 12:27:06 +00:00Commented Aug 7, 2016 at 12:27 -
\$\begingroup\$ Suggest
s+=write(puts(""),s,m));instead ofs+=m)printf("%.*s\n",m,s);\$\endgroup\$ceilingcat– ceilingcat2018年10月11日 06:16:33 +00:00Commented Oct 11, 2018 at 6:16
Perl, 23 + 4 (-pF flags) = 27 bytes
-2 bytes thanks to @DomHastings
-1 bytes thanks to @DomHastings
$==sqrt@F;s/.{$=}/$&
/g
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.
-
\$\begingroup\$ Nice use of
$@, ;) You can save a byte usingy///cinstead 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\$Dom Hastings– Dom Hastings2016年08月05日 22:52:04 +00:00Commented Aug 5, 2016 at 22:52 -
1\$\begingroup\$ @DomHastings Yea, I thought you'd like the
$@! Thanks for they///c, I tend to forget that it exists. \$\endgroup\$Dada– Dada2016年08月05日 23:21:58 +00:00Commented Aug 5, 2016 at 23:21 -
1\$\begingroup\$ @DomHastings managed to save 1 byte by using
$=instead of$@, which allows to not use-lflag. \$\endgroup\$Dada– Dada2016年08月07日 12:26:15 +00:00Commented Aug 7, 2016 at 12:26 -
\$\begingroup\$ Good going! Good to use the magic variables for genuine reasons too! \$\endgroup\$Dom Hastings– Dom Hastings2016年08月07日 14:00:00 +00:00Commented 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\$Dom Hastings– Dom Hastings2017年10月05日 15:16:47 +00:00Commented Oct 5, 2017 at 15:16
05AB1E, (削除) 8 (削除ここまで) 6 bytes
Thanks to @quartata for letting me know about the square-root function
Dgtô¶ý
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
-
\$\begingroup\$ Very nice! Also,
«is short for joining on newlines :). \$\endgroup\$Adnan– Adnan2016年08月05日 23:13:53 +00:00Commented Aug 5, 2016 at 23:13 -
1\$\begingroup\$ @Adnan Thanks! Now I have outgolfed myself :-D \$\endgroup\$Luis Mendo– Luis Mendo2016年08月05日 23:21:33 +00:00Commented Aug 5, 2016 at 23:21
-
\$\begingroup\$ I have rolled back to my 6-byte version because there was a previous answer with
«\$\endgroup\$Luis Mendo– Luis Mendo2016年08月05日 23:52:57 +00:00Commented Aug 5, 2016 at 23:52 -
1\$\begingroup\$ Oh, that's too bad :( \$\endgroup\$Adnan– Adnan2016年08月05日 23:56:06 +00:00Commented 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\$René Roth– René Roth2016年08月07日 16:15:28 +00:00Commented Aug 7, 2016 at 16:15
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
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))))
-
\$\begingroup\$ Note that you can use
input()by default to receive input in quotes, unless you want to specifically remove that option. \$\endgroup\$xnor– xnor2016年08月05日 22:34:44 +00:00Commented 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\$acrolith– acrolith2016年08月05日 22:42:18 +00:00Commented Aug 5, 2016 at 22:42
-
\$\begingroup\$ Wouldn't it be shorter to use a lambda? \$\endgroup\$Leaky Nun– Leaky Nun2016年08月06日 04:58:13 +00:00Commented Aug 6, 2016 at 4:58
-
\$\begingroup\$ @LeakyNun true... \$\endgroup\$acrolith– acrolith2016年08月06日 15:54:18 +00:00Commented Aug 6, 2016 at 15:54
zsh, (削除) 36 (削除ここまで) 33 bytes
fold -`tr -d .<<<$[$#1**.5]`<<<1ドル
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
-
\$\begingroup\$ +1 for having your score be n². Mine is too :) \$\endgroup\$Digital Trauma– Digital Trauma2016年08月06日 22:49:00 +00:00Commented Aug 6, 2016 at 22:49
-
\$\begingroup\$ @DigitalTrauma Should you retract your upvote now? \$\endgroup\$The Fifth Marshal– The Fifth Marshal2019年12月26日 16:50:09 +00:00Commented Dec 26, 2019 at 16:50
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
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
CJam, 8 bytes
l_,mQ/N*
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
Pyth, 8 bytes
jcs@lQ2Q
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
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.
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')}⬮`
Brainfuck, 83 bytes
,[>+[>+<-],]
>
[
>>[<+<-->>-]
+<[>+<-]
<-
]
<<
[
[<]
>.,
>[>]
>>+>-[<]
<[[>+<-]++++++++++.,<<]
<
]
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 ....
Brain-Flak, (削除) 110 (削除ここまで) 96 bytes
([]<>){({}{}(({}[()])))}{}{({}()<(({})<{({}()<<>({}<>)>)}{}((()()()()()){})>)>)}{}{}{({}<>)<>}<>
Second solution, 96 bytes
(([]<>)<{({}({})({}[()]))}{}>){({}(({})<{({}()<<>({}<>)>)}{}((()()()()()){})>))}{}{}{({}<>)<>}<>
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.
{({}<>)<>}<>
PHP, 51 bytes
<?=join("
",str_split($x=$argv[1],strlen($x)**.5));
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
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"
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... :)
-
\$\begingroup\$ Nice answer +1. You can golf it by 1 byte by using
i=0,i<kands.substring(i*k,i++*k+k)instead ofi=-1,++i<k,s.substring(i*k,i*k+k). Also, usually we use justJava 7instead ofJava 1.7, but it's good that you've added it, a lot of people forget to do so. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2016年09月07日 08:58:05 +00:00Commented Sep 7, 2016 at 8:58
PowerShell, 56 (削除) 58 (削除ここまで) (削除) 61 (削除ここまで) bytes
param($i)$i-replace".{$([Math]::Sqrt($i.Length))}",'$&
'
-
\$\begingroup\$ Taking it as a param saves two bytes \$\endgroup\$Veskah– Veskah2019年07月08日 15:36:11 +00:00Commented Jul 8, 2019 at 15:36
K (ngn/k), 11 bytes
{(2#%#x)#x}
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")