| Bytes | Lang | Time | Link |
|---|---|---|---|
| 005 | Japt | 170608T095634Z | Shaggy |
| 055 | Zsh +coreutils | 240702T124858Z | roblogic |
| 033 | K ngn/k | 240824T170545Z | coltim |
| 190 | Setanta | 240725T205957Z | bb94 |
| 106 | R | 240701T094454Z | int 21h |
| 022 | Perl 5 + plF M5.10.0 | 180806T120712Z | Dom Hast |
| 031 | Uiua | 240705T125210Z | Joao-3 |
| 088 | Ruby | 140106T134244Z | manatwor |
| 005 | MATL | 180731T131723Z | Sundar R |
| 043 | K oK | 190615T210338Z | mkst |
| 228 | C MinGW | 171203T154212Z | gastropn |
| 100 | JavaScript | 180731T163952Z | MattH |
| 029 | MATLAB | 180730T085625Z | Jacob Wa |
| 029 | Octave | 180731T150529Z | Sundar R |
| 006 | 05AB1E | 180730T091655Z | Kevin Cr |
| 101 | Python 2 | 180725T081807Z | Chas Bro |
| nan | Lua | 180725T061742Z | Visckmar |
| 154 | Excel VBA | 180725T105851Z | Taylor R |
| 002 | Pyth | 180406T163233Z | hakr14 |
| 040 | Retina | 180406T040812Z | mbomb007 |
| 103 | Javascript | 180406T085229Z | edc65 |
| 205 | Lua | 180406T082935Z | dragonit |
| 026 | J | 171206T035137Z | Bolce Bu |
| 081 | Perl 5 | 171204T202304Z | Xcali |
| 011 | Pyth | 171204T181847Z | KSmarts |
| 110 | PHP | 171202T084454Z | Titus |
| 124 | Bash | 140104T124502Z | memnon |
| 173 | JavaScript | 160505T164022Z | ericw314 |
| 098 | Groovy | 160504T120323Z | Krzyszto |
| 025 | CJam | 150421T232746Z | Martin E |
| 056 | K | 140106T140355Z | tmartin |
| nan | 140320T091126Z | chinese | |
| 083 | Bash+coreutils+sed | 140319T043859Z | Digital |
| 191 | Haskell | 140106T143712Z | Impredic |
| 095 | Mathematica | 140106T102932Z | alephalp |
| 090 | Python 2.7 | 140103T175421Z | Joachim |
| 217 | PHP | 140103T144223Z | Tim Segu |
| 103 | Python | 140103T215655Z | TrevorM |
| 171 | R | 140104T141207Z | Sven Hoh |
| 117 | MATHEMATICA | 140104T020120Z | Murta |
| 210 | AutoHotkey | 140104T091019Z | Avi |
| nan | 140104T082717Z | randomus | |
| nan | 140104T021604Z | tasegula | |
| 111 | Ruby | 140103T194549Z | Wayne Co |
| 194 | PHP | 140103T214547Z | elixenid |
| 144 | Ruby β | 140103T173551Z | O-I |
| 051 | GolfScript | 140103T192320Z | Ilmari K |
| 115 | Python 2.7 | 140103T183222Z | 0x90 |
| 243 | C++ | 140103T174845Z | David |
| 278 | C | 140103T154137Z | wjl |
| nan | 140103T134038Z | marinus |
Zsh +coreutils, 139 110 109 105 95 55 bytes
for i ({1..`wc -L<a`})cut -c$i a|rs -eg0|sed 's/ *$//'
Assumes input file a has lines of varying length. Pads the lines with spaces Slices, reshapes, and trims trailing spaces.
`wc -L<a` # get the longest line of πΜ²
for i ()cut -c$i a # take vertical slices of πΜ² at each $i
|rs -eg0|sed 's/ *$//' # reshape and remove trailing spaces
NaΓ―ve solution (TIO): for i ({1..`wc -L<a`})cut -c $i a|tr -d \\n&&echo
95b
105b
109b
110b
139b
K (ngn/k), 33 bytes
{"\n"/(|&\|^:)_'+(|/#'x)$x}@"\n"\
{...}@"\n"\split (implicit) input on newlines, passing into lambda+(|/#'x)$xright-pad each string to maximum length with spaces, then transpose(|&\|^:)_'drop trailing spaces from each line"\n"/join with newlines and (implicitly) return
Setanta, 191 190 bytes
gniomh(s){s=roinn@s("
")t:=0u:=""le i idir(0,fad@s)t=uas(t,fad(s[i]))le i idir(0,t){le j idir(0,fad@s)u+=(i<fad(s[j])&s[j][i])|" "nuair-a u!=""&u[-1]==" " u=cuid@u(0,fad@u-1)u+="
"}toradh u}
R, 106 bytes
for(j in Map(substr,list(s<-scan(,"",sep="\n")),n<-1:max(nchar(s)),n))cat(ifelse(j==""," ",j),"\n",sep="")
I have chosen to write the complete program: it grabs the manual input and prints the result out.
The text is transformed to a list of characters vectors (puts together all the 1st letters, the 2nd etc.). This is done by mapping the substr function, and the list size corresponds to the longest textline. When there is not enough characters an empty character is produced (this is why I prefer to use substr instead of strsplit: there'll be no vector recycling!).
The program then iterates through this list and conditionally outputs the characters: instead of the empty one there will be a space, or the character itself otherwise; the newlines are added at the end of each vector.
Perl 5 + -plF -M5.10.0, 22 bytes
Utilises ANSI escape sequences and unprintables.
$"="..";$_=".[1;$.H@F"
Explanation
This code first changes the list separator ($") value to be a form-feed and a backspace, then we set the implicitly printed variable $_ to be a string that starts with the ANSI escape sequence for 'start printing at line 1 column $. (where $. is the current line of text: \x1b1;$.H) and interpolates the list @F (which is a list of all the characters on that line, populated by autosplit (-a, implied by -F) with an empty split pattern (-F)) which places the contents of $" in between each item, moving the cursor vertically down instead of continuing output after the previous character.
Ruby: 88 characters
(Posted because it's shorter then the other Ruby solutions. Not checked whether my code introduces anything new compared to those. If you already posted a Ruby solution and you feel this is mostly a copy of yours, please comment and I will retire my answer.)
f=->t{l=t.split$/;r=[""]*m=l.map(&:size).max;l.map{|l|m.times{|i|r[i]+=l[i]||" "}};r*$/}
Sample run:
irb(main):001:0> f=->t{l=t.split$/;r=[""]*m=l.map(&:size).max;l.map{|l|m.times{|i|r[i]+=l[i]||" "}};r*$/}
=> #<Proc:0x99a9e68@(irb):1 (lambda)>
irb(main):002:0> sample='I am a text.
irb(main):003:0' Transpose me.
irb(main):004:0' Can you do it?'
=> "I am a text.\nTranspose me.\nCan you do it?"
irb(main):005:0> puts f[sample]
ITC
ra
aan
mn
sy
apo
ou
ts
eed
x o
tm
.ei
.t
?
=> nil
irb(main):006:0> puts f[f[sample]]
I am a text.
Transpose me.
Can you do it?
=> nil
MATL, 5 bytes
!Z{Zv
Input is taken implicitly, and conveniently, the shorter lines get spaces added to them by the environment to make them all equal in length.
! - transpose
Z{ - Convert to cell array (since we'll need to hold arrays of different lengths after the next step)
Zv - deblank i.e. remove the trailing spaces
K (oK), 43 bytes
Solution:
{"\n"/{(-+/&\32=|x)_x}@'+(|/#:'x)$x:"\n"\x}
Explanation:
Break on newlines, pad lines to same lengths, transpose, trim trailing whitespace and join on newlines. Feels like there has to be an easier way...
{"\n"/{(-+/&\32=|x)_x}@'+(|/#:'x)$x:"\n"\x} / the solution
{ } / lambda
x / input x
"\n"\ / split (\) on "\n"
x: / save as x
$ / pad right with left
( ) / do this together
#:'x / count (#:) each (') x
|/ / max
+ / transpose
{ }@' / apply (@) lambda to each (')
x / input x
_ / drop
( ) / do this together
|x / reverse (|) x
32= / equal to ASCII 32 aka " "
&\ / min
+/ / sum
- / negate
"\n"/ / join (/) on "\n"
C (MinGW), 272 262 259 254 234 229 228 bytes
-15 bytes thanks to ceilingcat
The TiO link requires the string.h include, but MinGW does not.
n,a,i,j;*f(int*s){char*p,**L=a=n=i=0,*r;for(;p=strtok(L?0:s,"\n");j>a?a=j:0)j=strlen((L=realloc(L,++n*8))[n-1]=p);for(p=r=calloc(n+1,a+1);i<a;i++,*p++=10){for(j=0;j<n;j++)*p++=i<strlen(L[j])?L[j][i]:32;while(p[-1]==32)p--;}s=r;}
JavaScript, 102 100 bytes
q=>[...q].reduce((r,e,j)=>(y=w.map((e,i)=>w[i][j]||" ").join``.trimEnd())?r+y+`
`:r,"",w=q.split`
`)
Run it here:
f = q=>[...q].reduce((r,e,j)=>(y=w.map((e,i)=>w[i][j]||" ").join``.trimEnd())?r+y+`
`:r,"",w=q.split`
`);
console.log(f(`I am a text.
Transpose me.
Can you do it?`));
MATLAB: 24 42 29 bytes
@(s)deblank(string(char(s)'))
Usage
s=["I am a text.";"Transpose me";"Can you do it?"];
@(s)deblank(string(char(s)'))
ans(s)
Output
ans =
14Γ3 char array
'ITC'
' ra'
'aan'
'mn'
' sy'
'apo'
' ou'
'ts'
'eed'
'x o'
'tm'
'.ei'
' t'
' ?'
Might be cheating here, as it's hard (as far as I can see) to get a string with newlines into MATLAB without using an array, so I went ahead and used an array for the input. Other than that, it does what it says on the tin - turns the string into a matrix of chars, transposes it and trims the whitespace.
Edit: Changed (and lengthened) the program as I didn't see the requirement for whitespace to be trimmed.
Edit: -13 bytes thanks to sundar.
Octave, 35 29 bytes
@(s)strjoin(cellstr(s'),'\n')
(-1 byte thanks to Luis Mendo, -5 bytes thanks to strjoin from this SO answer)
05AB1E, 6 bytes
΢ΡðΓ}Β»
Try it online.
Try it when taking the output as input-list again.
Explanation:
ΞΆ # Zip the input-list, swapping rows and columns
Ξ΅ } # For-each:
ðà # Remove trailing spaces
Β» # Join the resulting list by new-lines (and output implicitly)
Python 2, 87 101 bytes
lambda s:T('\n'.join(map(T,map(''.join,zip(*[t.ljust(len(s))for t in s.split('\n')])))))
T=str.rstrip
Lua, 203 189 bytes
t={{}}i=1m=0(...):gsub(".",function(c)n=#t[i]if c=="\n"then i=i+1t[i]={}else t[i][n+1]=c end m=m<=n and n+1or m end)
for x=1,m do for p=1,i do io.write(t[p][x]or" ")end _=m<=x or print()end
I saw another Lua solution here, but I don't think there's a problem with posting 2 solutions on the same language. If there is, tell me :)
Excel VBA, 154 bytes
Takes input from [A1] and outputs to the console.
x=Split([A1],vbLf):u=UBound(x):For i=0To u:l=Len(x(u)):m=IIf(m>l,m,l):Next:For i=1To m:For j=0To u:s=s+Mid(x(j)&String(m,32),i,1):Next:?RTrim(s):s="":Next
Ungolfed
x=Split([A1],vbLf) '' Split input by lines
u=UBound(x) '' Get number of lines
For i=0To u '' Iterate over lines
l=Len(x(u)) '' Get length of line `i`
m=IIf(m>l,m,l) '' Compare to max length; Store Max
Next '' Loop
For i=1To m '' Iterate over chars in line
For j=0To u '' Iterate over lines
s=s+Mid(x(j)&String(m,32),i,1) '' Append `i`th char of `j`th line to `s`
Next '' Loop
?RTrim(s) '' Remove right whitespace, print
s="" '' Reset `s`
Next '' Loop
Pyth, 2 bytes
.t
Performs the built in transpose function on an input list, outputting a list of lines.
Pyth, 7 bytes
V.t.zdN
The above program, modified to use the input and output format specified in the challenge.
Retina, 40 bytes
P`.+
~L0$`.
L,$.%'vs,$.(x$%=),`.+
m` *$
Based on this program that I created to transpose any size of rectangle, which uses Leo's suggestion for transposing a rectangle of a known size.
Edit: Golfed more and no longer has trailing spaces on lines.
Javascript, 103
s=>[...s].map((_,i)=>s.split`
`.map(b=>r+=b[q=b[i]||q,i]||' ',r=q='')&&r.replace(/ *$/,q?`
`:q)).join``
Less golfed
s=>[...s].map(
// we need 'i' ranging from 0 to the length of the longest input line
// so we scan all the input string, that is surely longer
// but we need to check that after some point the output must be empty
(_, i) => (
r = '', // the current output row, starts empty
q = '', // flag to check if we are beyond the longest line
s.split('\n') // split in rows
.map(
b => ( // for each input row in b
q = b[i] || q, // if there is a char at position i in b, i goes to q
r += b[i] || ' ' // add to output the char at position i or a fill space
)
),
q // if q is still '', we are beyond the longest input line
? r.replace(/ *$/,`\n`) // trim leading space and add newline
: '' // no output
)
).join('')
Test
F=
s=>[...s].map((_,i)=>s.split`
`.map(b=>r+=b[q=b[i]||q,i]||' ',r=q='')&&r.replace(/ *$/,q?`
`:q)).join``
function go() {
var text=I.value
var output = F(text)
O.textContent = output
}
go()
#I { width:50%; height:5em }
<textarea id=I>I am a text.
Transpose me.
Can you do it?</textarea><br>
<button onclick='go()'>Transpose</button>
<pre id=O></pre>
Lua, 205 bytes
L={}C=0 R=io.read I=R()while I~=""do L[C]=I C=C+1 I=R()end M=0 for i=0,C-1,1 do if#L[i]>M then M=#L[i]end end for i=1,M,1 do for j=0,C-1,1 do io.write(L[j]:sub(i,i)==""and" "or L[j]:sub(i,i))end print()end
Ungolfed
lines={}
count=0
R=io.read
input=R()
-- reads input in until an empty line is found
-- lines are added to the lines table
while input~="" do
lines[count]=input
count=count+1;
input=R()
end
-- find the length of the longest string
max_len=0
for i=0,count-1,1 do
if #lines[i]>max_len then
max_len=#lines[i]
end
end
-- loop through each character of each string
for i=1,max_len,1 do
for j=0,count-1,1 do
-- print the string's next character
-- or a space if there is not another character
if lines[j]:sub(i,i)=="" then--this if statement is golfed into a
io.write(" ") --pseudo-ternary statement in the golfed version
else
io.write(lines[j]:sub(i,i))
end
end
print()
end
J, 28 26 Bytes
Saved 2 bytes thanks to frownyfrog
t=.,@:(,&LF"1)@|:@:>@cutLF
Takes a string, returns a string. I'm not sure if there's a shorter version of the 'cutopen' function verb that I could use.
There's also the shorter
t=.|:@:>@cutLF
But I'm not sure it falls within the OP's guidelines, as it returns an array of characters.
How it works:
cutLF | Splits the input on new lines and boxes them
@ | Composes verbs (as does @:, but they're not equal)
> | Unboxes this, forming an array of the lines
@: |
|: | Transposes the array
( )@ |
,&LF | Appends a new line...
"1 | To each row of the array
@: |
, | Flatten the result
t=. | Assign this verb to t
The other version works the same, but doesn't convert the transposed array to a properly formatted string.
Examples:
NB. Define a multi-line string
text =: 0 : 0
I am a text.
Transpose me.
Can you do it?
)
t text
ITC
ra
aan
mn NB. There's whitespace after the 'n' here, but I assume it doesn't count as trailing since it's part of the original string
sy
apo
ou
ts
eed
x o
tm
.ei
.t
?
t t text
I am a text. NB. Again, whitespace here, but it's part of the argument of the second 't' (added by the first 't' to keep columns straight)
Transpose me.
Can you do it?
Perl 5, 81 bytes
chomp(@a=<>);say((join"",map{(substr$_,0,1,"")||$"}@a)=~s/\s+$//r)while"@a"=~/\S/
Pyth, 11 bytes
# aYcw1;.tY
Takes input as a string, outputs a list of lists
Pyth, 25 bytes
# aYcw1=+Z1;jbcj"".n.tY)Z
Takes input as a string, outputs a string.
PHP, 95+0 108+1 110 bytes
foreach($input as $s)for($y=0;~$c=$s[$y];)$r[$y++].=$c>"
"?$c:" ";echo rtrim(join("
",array_map(rtrim,$r)));
takes input from STDIN; breaks at the first empty line. Run with -nr or try it online.
Still trying to find something shorter than the additional rtrim to get rid of the second newline.
Bash, 124 bytes
D=`mktemp -d`;split -l1 - $D/;for F in $D/*;do grep -o . $F>$F+
done;paste $D/*+|sed -e's/\([^\t]\)\t/\1/g;s/\t/ /g;s/ *$//'
It reads standard input and writes standard output. Try it:
echo $'I am a text.\nTranspose me.\nCan you do it?' | script.sh
How it works:
splitinput into single lines (files in temporary directory$D)- split lines into single characters using
grep(files *+) - layout characters side-by-side using
paste(TAB-separated columns) - remove alignment TABs, replace filler TABs with BLANKs, trim using
sed
Edit:
- -9: Removed tidy-up code
;rm -r $D(thanks Tim) - -2: use
+instead of_as suffix and shorten${F}_to$F+ - -3: remove prefix
Lfrom split result files
JavaScript, 177 173 bytes
s=>{l=s.split`
`.sort((a,b)=>b.length-a.length)[0];for(i=0,t=[];i<l.length;i++){t[i]=s.split`
`.map(i=>i+" ".repeat(l.length-i.length)).map(j=>j[i]).join``}return t.join`
`}
s=>{l=s.split`\n`.sort((a,b)=>b.length-a.length)[0];for(i=0,t=[];i<l.length;i++){t[i]=s.split`\n`.map(i=>i+" ".repeat(l.length-i.length)).map(j=>j[i]).join``;}return t.join`\n`}
If you can help me shorten this up, please do so.
Groovy, 98 chars
{i->o=[].withDefault{''};i.readLines().each{it.toList().eachWithIndex{c,d->o[d]+=c}};o.join('\n')}
ungolfed:
{i->
o=[].withDefault{''};//create list with empty string as default value
i.readLines()
.each{
it.toList() //split every line to characters
.eachWithIndex{
c,d->o[d]+=c //append to string from list with right index
}
};
o.join('\n')}//join list with newlines
}
CJam, 32 25 bytes
CJam is newer than this challenge, so this answer is not eligible for being accepted.
Considerably shortened by user23013.
qN/_z,f{Se]}z{S+e`);e~N}%
qN/ "Read input, split into lines.";
_z, "Transpose, get length (find maximum line length).";
f{Se]} "Pad each line to that length with spaces.";
z "Transpose.";
{ }% "Map this block onto each line in the result.";
S+ "Add a space to ensure there's at least one.";
e` "Run-length encode.";
); "Discard the trailing run of spaces.";
e~ "Run-length decode";
N "Push a newline.";
K, 56
This should meet the spec now.
Accepts a string, returns a string.
{`/:{$[" "=*|x;|(+/&\" "=|x)_|x;x]}'x@'/:!max@#:'x:`\:x}
.
k)f:{`/:{$[" "=*|x;|(+/&\" "=|x)_|x;x]}'x@'/:!max@#:'x:`\:x}
k)f"I am a text.\nTranspose me.\nCan you do it?"
"ITC\n ra\naan\nmn\n sy\napo\n ou\nts\need\nx o\ntm\n.ei\n .t\n ?\n"
k)f f"I am a text.\nTranspose me.\nCan you do it?"
"I am a text.\nTranspose me.\nCan you do it?\n"
Perl (92+1)
reads stdin and writes to stdout. adding 1 to the score for say
@L=map[grep!/\n/,split//],<>;do{$_=join'',map shift@$_||$",@L;s/ +$//;say}while grep@$_>0,@L
Bash+coreutils+sed, 83
eval paste `sed 's/.*/<(fold -w1<<<"&")/'`|expand -t2|sed 's/\(.\) /\1/g;s/ \+$//'
fold and paste do the important work. The rest is just formatting.
Accepts input from stdin and outputs to stdout:
$ < tr.txt ./transposefile.sh
ITC
ra
aan
mn
sy
apo
ou
ts
eed
x o
tm
.ei
.t
?
$ < tr.txt ./transposefile.sh | ./transposefile.sh
I am a text.
Transpose me.?
Can you do it
$
Haskell: 191 chars
import Data.List
h [] = ' '
h (x:_) = x
t [] = []
t ([]:x) = t (" ":x)
t ((x:y):z) = takeWhile (any (/= ' ')).map (dropWhileEnd (== ' '))$(x:map h z):t (y:[s |(_:s)<-z])
m = (unlines.t.lines)
Mathematica, 95 chars
f=""<>Riffle[Thread@PadRight@Characters@StringSplit[#,"\n"]//.{0->" ",{x___," "..}:>{x}},"\n"]&
Python 2.7 (97 79 94 90)
EDIT: Missed the function requirement;
I'm fairly sure this will be improved on since I'm sort of a beginner here, but to start with;
c=lambda a:'\n'.join(''.join(y or' 'for y in x).rstrip()for x in map(None,*a.split('\n')))
The code uses a simple split to split the string into a vector of rows. It then uses map with a function value as None (the unity function) and the splat operator to transpose and pad the vector (similar functionality to zip_longest in Python3)
The rest of the code just maps None to space, trims and reassembles the matrix to a single string again.
>>> a = 'I am a text.\nTranspose me.\nCan you do it?'
>>> c(a)
'ITC\n ra\naan\nmn\n sy\napo\n ou\nts\need\nx o\ntm\n.ei\n .t\n ?'
>>> len("""c=lambda a:'\n'.join(''.join(y or' 'for y in x).rstrip()for x in map(None,*a.split('\n')))""")
88
# (+2 since `\n` is considered by `len` to be a single char)
PHP 227 217
Here's my attempt:
function f($s){$p=array_map;$s=$p(str_split,explode("
",$s));foreach($s as&$l)$l=array_pad($l,max($p(count,$s)),' ');array_unshift($s,null);foreach(call_user_func_array($p,$s)as$l)$r.=rtrim(implode($l))."
";return$r;}
Ungolfed:
<?php
function f($s) {
$s=array_map(str_split, explode("\n",$s));
foreach($s as &$l)
$l=array_pad($l, max(array_map(count, $s)),' ');
array_unshift($s, null);
foreach(call_user_func_array(array_map, $s)as$l)
$r.=rtrim(implode($l))."\n";
return $r;
}
$s="I am a text.
Transpose me.
Can you do it?";
echo f($s);
echo strlen(f($s));
Python 89 103 chars
def f(a):return'\n'.join([''.join(i).rstrip()for i in zip(*[j+' '*99 for j in a.split('\n')])]).rstrip()
I feel dirty. 90 104 chars for industrial strength version. :^)
R, 171
function(e){p=strsplit
x=t(plyr::rbind.fill.matrix(lapply(p(p(e,"\n")[[1]],""),t)))
x[is.na(x)]=" "
cat(apply(x,1,function(y)sub(" *$","",paste(y,collapse=""))),sep="\n")}
Usage example:
text <- "I am a text.
Transpose me.
Can you do it?"
(function(e){p=strsplit
x=t(plyr::rbind.fill.matrix(lapply(p(p(e,"\n")[[1]],""),t)))
x[is.na(x)]=" "
cat(apply(x,1,function(y)sub(" *$","",paste(y,collapse=""))),sep="\n")})(text)
ITC
ra
aan
mn
sy
apo
ou
ts
eed
x o
tm
.ei
.t
?
Trailing whitespace is removed.
MATHEMATICA 117 chars
t = "I am a text.\nTranspose me.\nCan you do it?";
f=(m=Length/@(f=Flatten[Characters/@StringSplit[#,"\n"],{{2},{1}}])//Max;
StringJoin@@@(PadLeft[#,m," "]&/@f)//Column)&
AutoHotkey 210
f(i){
StringSplit,o,i,`n
m:=0
loop % o0 {
a:=A_index
if (t:=Strlen(p:=o%a%))>m
m:=t
StringSplit,l%a%,o%a%
}
loop % m {
a:=A_index,n:=""
loop % o0
n.=(j:=l%A_index%%a%)=""?" ":j
s.=Rtrim(n," ") "`n"
}
return s
}
Test
text=
(
I am a text.
Transpose me.
Can you do it?
)
msgbox % f(text)
Haskell
import Data.List
main = interact (unlines . transpose . lines)
It was so short, I needed to add in white space...
Scheme/Racket 113
The text:
(define t (list
(string->list "I am a text.")
(string->list "Transpose me.")
(string->list "Can you do it?")
))
Without new lines and extra white spaces:
(define s(Ξ»(v x)(if(= x 0)'()(cons(list->string(car v))(s(cdr v)(- x 1))))))(s(apply map list t)(length(car t)))
The user-friendly version
(define text (list
(string->list "I am a text.")
(string->list "Transpose me.")
(string->list "Can you do it?")
))
(define transpose
(Ξ»(text length)
(if (= length 0)
'()
(cons (list->string (car text)) (transpose (cdr text) (- length 1)))
)))
(transpose (apply map list text) (length (car text)))
Ruby 111
Golfed:
def f t;s=t.lines;s.map{|l|l.chomp.ljust(s.map(&:size).max).chars}.transpose.map{|l|l.join.rstrip+?\n}.join;end
Ungolfed:
def transpose_text(text)
max_length = text.lines.map(&:size).max
text.lines.map do |line|
line.chomp.ljust(max_length).chars
end.transpose.map do |chars|
chars.join.rstrip + "\n"
end.join
end
Ruby has an array transpose function, so this simply pads the lines out, turns them into an array of characters, uses Ruby's Array#transpose function, then turns the array of characters back into lines.
Golfing it was simply using single-character identifiers, removing spaces, using a temporary for text.lines, and putting the calculation for max_length inline (there are no points for efficiency).
PHP 194
function x($a){$a.="\n";$s=strlen($a);$i=0;while($c<$s)if($a{$c}!="\n")$b[$i++].=$a{$c++};else{$c++;for(;$i<$s;$i++)$b[$i].=" ";$i=0;}ksort($b);return rtrim(implode("\n",array_map("trim",$b)));}
Non-golfed:
function x($a) {
$a.="\n";
$s=strlen($a);
$i=0;
while($c<$s)
if($a{$c}!="\n")
$b[$i++].=$a{$c++};
else{
$c++;
for(;$i<$s;$i++)
$b[$i].=" ";$i=0;
}
ksort($b);
return rtrim(implode("\n",array_map("trim",$b)));
}
This is my first golfing attempt, so please be kind! Also, tips/suggestions would be greatly appreciated!
Ruby β 144 characters
Here's my first attempt, golfed:
def f t
t.split(?\n).each{|l|l<<' 'until l.size==t.split(?\n).map(&:size).max}.map{|x|x.split('')}.transpose.map{|l|l.join.rstrip}.join(?/n)
end
For output, run puts f text where text is any multi-line string adhering to the rules above. The ungolfed version is below:
def text_transpose(text)
lines = text.split(?\n)
maxlen = lines.map(&:size).max
lines.each { |line| line << ' ' until line.size == maxlen }
.map { |line| line.split('') }.transpose
.map { |char| char.join.rstrip }.join(?\n)
end
For a similar, but ultimately better solution in Ruby, check out Wayne Conrad's code above.
GolfScript, 51 chars
n%.{,}%$-1=" "*:y;{y+y,<}%zip{n\+0{;).32=}do}%((;\+
This is a first attempt; I suspect it can be improved. Most of the code is to comply with the padding and trailing space removal requirements — without them, just n%zip n* would suffice.
Ps. The following 46-character version will do the job for the given sample input, but will crash if any input column consists entirely of spaces:
n%.{,}%$-1=" "*:y;{y+y,<}%zip{0{;).32=}do]}%n*
I assume that's enough to disqualify it, even if the challenge doesn't explicitly say so.
Python 2.7 - 115 chars:
oneliner:
>>> a
'I am a text.\nTranspose me.\nCan you do it?'
>>> "".join(["".join(i)+'\n' for i in zip(*[x+" "*(len(max(a.splitlines(), key=len))-len(x)) for x in a.splitlines()])])
'ITC\n ra\naan\nmn \n sy\napo\n ou\nts \need\nx o\ntm \n.ei\n .t\n ?\n'
and in a cleaner printing:
>>> print "".join(["".join(i)+'\n' for i in zip(*[x+" "*(len(max(a.splitlines(), key=len))-len(x)) for x in a.splitlines()])])
ITC
ra
aan
mn
sy
apo
ou
ts
eed
x o
tm
.ei
.t
?
in 115 chars:
>>> len(""""".join(["".join(i)+'\n' for i in zip(*[x+" "*(len(max(a.splitlines(), key=len))-len(x)) for x in a.splitlines()])])""")
115
C++ (243 characters)
Here's a function that takes and returns a string.
I could've shaved a couple dozen chars, but decided to keep it as not-stupid code (runs fast, reads okay). Maybe I only decided to do that because this is my first code golf... I'm not hardcore enough yet :)
string f(string s){stringstream ss(s);vector<string> v;for(size_t i=0;getline(ss,s);++i){if(v.size() < s.size())v.resize(s.size());for(size_t j=0;j<s.size();++j){v[j].resize(i,' ');v[j].push_back(s[j]);}}s="";for(auto& i:v)s+=i+'\n';return s;}
With formatting:
string f(string s)
{
stringstream ss(s);
vector<string> v;
for(size_t i = 0; getline(ss, s); ++i)
{
if(v.size() < s.size())
v.resize(s.size());
for(size_t j = 0; j < s.size(); ++j)
{
v[j].resize(i, ' ');
v[j].push_back(s[j]);
}
}
s = "";
for(auto& i : v)
s += i + '\n';
return s;
}
C (278 bytes)
Edit: This actually breaks the rules, since it takes a filename in as an argument but writes to stdout. I'll edit it later to write to a file and then print the filename to stdout.
This is my first code golf ever, so have mercy. Some plain old C. Place the input in test.txt and let it run!
clang transpose.c -o transpose && ./transpose test.txt
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#define BUFFER_SIZE 1024
#define MAX(A,B) ((A)>(B)?(A):(B))
int main(int argc, char **argv) {
char line[BUFFER_SIZE];
FILE *f; int nLines, maxLen;
f = fopen(argv[1], "r");
while(!feof(f) && fgets(line, BUFFER_SIZE, f)) {
nLines++;
maxLen = MAX(maxLen, strlen(line));
}
fclose(f);
for (int charPos = 0; charPos < maxLen; charPos++) {
f = fopen(argv[1], "r");
for (int linePos = 0; linePos < nLines; linePos++) {
fgets(line, BUFFER_SIZE, f);
printf("%c", charPos < strlen(line) && line[charPos] != '\xA' ? line[charPos] : ' ');
}
printf("\n");
fclose(f);
}
return 0;
}
By using short variable names, removing gratuitous formatting, and allowing file handles to leak, and disabling all warnings this is reduced to 278 bytes. (Since this uses implicit imports, it may not link properly on all systems. Works on my machine!)
#import <stdio.h>
int main(int C,char**V){char L[1024];int A,B,D,I,J,*F=fopen(V[1],"r");while(!feof(F)&&fgets(L,1024,F)){A++;D=strlen(L);B=B>D?B:D;}for(I=0;I<B;I++){F=fopen(V[1],"r");for(J=0;J<A;J++)fgets(L,1024,F)&&printf("%c",I<strlen(L)&&L[I]!='\n'?L[I]:' ');printf("\n");}}
J (31 40)
f=:3 :';(,&LF@dlb&.|.)&.><"1|:>LF cut y'
This is a function that takes a string, and returns a string (i.e. a character vector with linefeeds inserted in the right places, and not a matrix.)
Edit: no trailing whitespace on any line.
Test:
f=:3 :';(,&LF@dlb&.|.)&.><"1|:>LF cut y'
string=:stdin''
I am a text.
Transpose me.
Can you do it?
^D
$string
42
$f string
53
f string
ITC
ra
aan
mn
sy
apo
ou
ts
eed
x o
tm
.ei
.t
?