15
\$\begingroup\$

Task

  • Take input string separated by space.
  • Sort the words alphabetically.
  • Print them out vertically in 3 columns separated by space(s).

Challenge

  • All three column's heights should be as evenly weighted as possible.
  • All three column's should be left aligned.

This is , so shortest code wins!

Example

If the input is:

"cat caterpillar pie frog elephant pizza", 

The output should be:

cat         elephant pie
caterpillar frog     pizza

Please beware of cases, if input is:

"a b c d e f g" 

Should be printed as:

a c e
b d f
    g

# or

a d f
b e g
c

# and not

a d g
b e
c f
\$\endgroup\$
10
  • 2
    \$\begingroup\$ Also, I would recommend you remove the strict I/O requirement; that is, take input as a list of strings in any form (as answerer wants) and as a program or a function taking the list. \$\endgroup\$ – hyper-neutrino Nov 16 '17 at 15:20
  • \$\begingroup\$ Is it acceptable to output this for the first example? \$\endgroup\$ – caird coinheringaahing Nov 16 '17 at 15:27
  • 4
    \$\begingroup\$ @Satendra Don't worry about the "put on hold as off-topic...", when/if the question is sufficiently good it will be reopened. | You can consider using the sandbox. \$\endgroup\$ – user202729 Nov 16 '17 at 15:32
  • 3
    \$\begingroup\$ Please consider using the Sandbox in the future to get feedback on your challenges before posting them to the main site. \$\endgroup\$ – user45941 Nov 16 '17 at 15:32
  • 1
    \$\begingroup\$ @Satendra Nice first challenge. If the columns must be separated by a single space at the narrowest gap, you should state so. \$\endgroup\$ – Adám Nov 16 '17 at 15:36

12 Answers 12

4
\$\begingroup\$

Husk, 24 17 bytes

TmoTT' §CȯmLTC3Ow

Try it online!

Explanation

This was a surprisingly tricky challenge, as Husk currently lacks a builtin for breaking a list into a given number of parts.

TmoTT' §CȯmLTC3Ow  Implicit input, say s="bbb a cc ddd e"
                w  Split at spaces: x=["bbb","a","cc","ddd","e"]
             C3    Cut into slices of length 3: [["bbb","a","cc"],["ddd","e"]]
            T      Transpose: [["bbb","ddd"],["a","e"],["cc"]]
         ȯmL       Map length: [2,2,1]
                   These are the correct lengths of the columns.
       §C      O   Sort x and split into these lengths: [["a","bbb"],["cc","ddd"],["e"]]
                   These are the columns of the correct output, without padding.
 mo                For each column,
    T'             transpose and pad with spaces: [["ab"," b"," b"],["cd","cd"," d"],["e"]]
   T               then transpose back: [["a  ","bbb"],["cc ","ddd"],["e"]]
T                  Transpose the whole list: [["a  ","cc ","e"],["bbb","ddd"]]
                   Implicitly join each row by spaces,
                   join the resulting strings by newlines and print.
\$\endgroup\$
2
\$\begingroup\$

Jelly, 6 bytes

Ṣœs3ZG

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ @DLosc It's actually been tested with the a b c d e f g case too, and I did other extensive tests because I had that feeling first too. Oh, and its shortness comes from the G (Format as Grid.) builtin. \$\endgroup\$ – Erik the Outgolfer Nov 17 '17 at 7:11
  • \$\begingroup\$ Ah, there's a builtin. (Why am I surprised?) That explains a lot. \$\endgroup\$ – DLosc Nov 17 '17 at 7:51
2
\$\begingroup\$

Python 3, 148 bytes

-6 bytes thanks to ovs.

l=sorted(input().split())
n=-~len(l)//3
f=lambda l:[i.ljust(max(map(len,l)))for i in l+['']]
for i in zip(f(l[:n]),f(l[n:n*2]),f(l[n*2:])):print(*i)

Try it online!

Workin' on it. Everything I've tried makes the output lopsided...

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 148 bytes using python 3. \$\endgroup\$ – ovs Nov 17 '17 at 15:56
1
\$\begingroup\$

Mathematica, 115 bytes

Grid[Transpose@PadRight@TakeList[#,Last@IntegerPartitions[Tr[1^#],3]]&@Sort@StringSplit@#/. 0->"",Alignment->Left]&

try it on wolfram sandbox

paste the following code and press shift+enter

Grid[Transpose@PadRight@TakeList[#,Last@IntegerPartitions[Tr[1^#],3]]&@Sort@StringSplit@#/. 0->"",Alignment->Left]&["cat caterpillar pie frog elephant pizza"]
\$\endgroup\$
1
  • 1
    \$\begingroup\$ @HalvardHummel fixed \$\endgroup\$ – ZaMoC Nov 16 '17 at 19:30
1
\$\begingroup\$

Perl 5, 134 + 1 (-a) = 135 bytes

$.=(sort{$b=~y///c-length$a}(@F=sort@F))[0]=~y///c;@a=splice@F,0,@F/3;@b=splice@F,0,@F/2;printf"%-$.s "x3 .$/,shift@a,shift@b,$_ for@F

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ What does it mean? \$\endgroup\$ – xyz123 Nov 25 '17 at 20:10
1
\$\begingroup\$

05AB1E, 8 bytes

#{.B3äζ»

Try it online!


#        | Split on spaces.
 {       | Sort aphabetically.
  .B     | Pad to max string length.
    3ä   | Split into columns.
      ζ  | Transpose.
       » | Print with newlines.
\$\endgroup\$
1
\$\begingroup\$

Javascript 181 175 bytes

f=a=>(a=a.split` `).sort().map(c=>(t[y]=[...t[y]||[],c],M[x]>(l=c.length)?0:M[x]=l,a[++y*3+x]?y:y=x++*0),M=[t=[x=y=0]])&&t.map(x=>x.map((c,y)=>c.padEnd(M[y])).join` `).join`
`

console.log(f("cat caterpillar pie frog elephant pizza"))
console.log("-------------------")
console.log(f("cat caterpillar pie frog frog123123 pizza"))
console.log("-------------------")
console.log(f("a b c d e f g"))
console.log("-------------------")
console.log(f("a b c d e f"))
console.log("-------------------")
console.log(f("a b c d e"))
console.log("-------------------")
console.log(f("a b c d"))

/*
f=a=>(a=a.split` `).sort().map(c=>((t[y] =t[y]||[])[x]=c,M[x]>(l=c.length)?0:M[x]=l,++y*3+x<a.length?0:y=x++*0),M=[t=[x=y=0]])&&t.map(x=>x.map((c,y)=>c.padEnd(M[y])).join` `).join`\n`

f=a=>(a=a.split` `).sort().map(c=>(t[y]=[...t[y]||[],c],M[x]>(l=c.length)?0:M[x]=l,++y*3+x<a.length?0:y=x++*0),M=[t=[x=y=0]])&&t.map(x=>x.map((c,y)=>c.padEnd(M[y])).join` `).join`\n`

*/

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

J, 73 bytes

,.@(' ',"1[:>|:)@((](s,(s=.]{.1:),(1:{.~[-2*]))([:<.0.5+%&3))@#];.1])@/:~

I can explain this mess later if someone is interested.

Try it online!

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

Charcoal, 65 64 bytes

≔⪪θ ηFη«⊞υ⌊η≔⟦⟧ηF⪪θ ¿¬№υκ⊞ηκ»FE³✂υ÷×ιLυ³÷×⊕ιLυ³I1«P⪫ι¶¿ιM⊕⌈EιLκ→

Try it online! Link is to verbose version of code. Save 2 bytes if I don't have to handle the case of fewer than 3 words. There's probably a sorting "eval" I should be using... Explanation:

≔⪪θ η

Split the input on spaces.

Fη«⊞υ⌊η≔⟦⟧ηF⪪θ ¿¬№υκ⊞ηκ»

Sort the array.

FE³✂υ÷×ιLυ³÷×⊕ιLυ³I1«

Loop over three approximately equal slices of the array. (I1 should really be ¦¹.)

P⪫ι¶

Join the slice with newlines and print it without moving the cursor.

¿ιM⊕⌈EιLκ→

If the slice is not empty then move right by one more than the length of the longest word in the slice.

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

358 bytes of minified JS:

function f(b){let d=[,,,],e=b.split(" ").sort(),g=[],h=[];for(var j in e){var k=Math.min(2,Math.floor(j/Math.floor(e.length/3)));d[k]||(d[k]=[],g[k]=e[j].length),d[k].push(e[j]),2==k&&h.push(""),g[k]=Math.max(e[j].length,g[k])}for(var o in g)for(var p=0;p<g[o]+1;p++)for(var q in h)h[q]+=q>=d[o].length||p>=d[o][q].length?" ":d[o][q][p];return h.join("\n")}

function f(b){let d=[,,,],e=b.split(" ").sort(),g=[],h=[];for(var j in e){var k=Math.min(2,Math.floor(j/Math.floor(e.length/3)));d[k]||(d[k]=[],g[k]=e[j].length),d[k].push(e[j]),2==k&&h.push(""),g[k]=Math.max(e[j].length,g[k])}for(var o in g)for(var p=0;p<g[o]+1;p++)for(var q in h)h[q]+=q>=d[o].length||p>=d[o][q].length?" ":d[o][q][p];return h.join("\n")}

console.log(f("cat caterpillar pie frog elephant pizza"));
console.log(f("a b c d e f g"));

\$\endgroup\$
1
  • \$\begingroup\$ @StephenLeppik np \$\endgroup\$ – jamespgilbert Nov 18 '17 at 3:20
0
\$\begingroup\$

GNU sed, 92 + 1 = 93 bytes

+1 bytes for -r flag.

I haven’t golfed this at all, but it turned out to be a lot simpler than I expected.

s/$/ /
s/(\S+ ){1,3}/:&\n/g
:
s/:(\S)/\1:/g
/:\S/!bZ
s/: / &/g
t
:Z
s/: / :/g
t
s/ *:.*$//gm

Try it online!

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

Bourne shell, 172 bytes

F=/tmp/t
<$1 tr \  \\n|sort>$F
N=$(wc -w $F|awk '{print $1/3}')
for i in 0 1 2
do
awk 'NR%N==C {print}' N=$N C=$i $F 
done|awk '{printf "%s%s",$1,NR%3?" ":"\n"}'|column -t

It's more readable if formatted conventionally:

#! /bin/sh
F=/tmp/t
<$1 tr \  \\n | sort > $F
N=$(wc -w $F | awk '{print $1/3}')

for i in 0 1 2
do    
    awk -v N=$N -v C=$i 'NR % N == C {print}' $F 
done |
    awk '{printf "%s%s", $1, NR % 3 == 0? "\n" : " " }' | column -t

At the price of scanning the input once per column, it uses no arrays. A more complex awk program could open 3 files (one for every Nth word), processing the input in one pass. Then they could be concatenated and printed using the same last line.

The variable N isn't strictly needed, either; for the price of 4 bytes, we save scanning the input 3 more times.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Welcome to PPCG! Since this is a code golf challenge, we require all answers to make an effort to minimize the bytecount. You can do that in exactly the ways you've mentioned--removing whitespace, shortening invocations, etc. Once you've done that, add a header to your answer giving the language used and the number of bytes. And feel free to keep your current version underneath as an "ungolfed" solution. \$\endgroup\$ – DLosc Nov 17 '17 at 6:50
  • \$\begingroup\$ Why aren't you making a scene about the 358 byte program, as well? \$\endgroup\$ – xyz123 Nov 25 '17 at 20:13

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.