Transpose a page of text

28

3

EDIT I modified the wording of the rules to make some things which were implicit more explicit. I also added some emphasis to clear up some points of apparent confusion, and explicitly defined the option of making a standalone program instead of a function.

The goal here is to make a function that takes a text file (or string) and transposes it so that lines become columns and vice versa.

Example:

I am a text.
Transpose me.
Can you do it?

Results in:

ITC
 ra
aan
mn
 sy
apo
 ou
ts
eed
x o
tm
.ei
 .t
  ?

The rules:

  • You are allowed to assume that the only whitespace characters used are " " and "\n" and that there is no trailing whitespace on any line.
  • You may assume that the file is ASCII. Which endline marker you want to use is up to you.(CRLF or LF). It must work correctly on the example, but it should also work on any input that satisfies the above assumptions.
  • You might have to insert spaces (as in the example) where there were none in order to keep the columns in line.
  • Your result must not have trailing whitespace on any line.
  • The final newline character(for the last line) is optional.
  • It should be either a function or a complete program. If your function accepts a string, then it should return the results as a string. If it accepts a filename, then you return the name of the file where you saved the result. You are additionally allowed to write a complete program that accepts input from STDIN and outputs the correct result to STDOUT; if you do this, you must not output anything to STDERR.
  • Shortest procedure wins, but I will upvote any answer I like.

Based on the rules, the output on the example is either 53 or 52 bytes long (for LF newlines) depending on whether the final newline is included or not.

Note: It is not a specific requirement, but if your function, when run twice successively is not identical to the original(the final newline might be differ, and any empty lines at the end of the file will be deleted), then you are probably breaking one of the rules.

Tim Seguine

Posted 2014-01-03T13:19:33.003

Reputation: 824

Later duplicate: http://codegolf.stackexchange.com/q/85255

– msh210 – 2016-07-12T18:08:25.743

I decided to remove the prohibition on language built-ins. – Tim Seguine – 2014-01-03T13:27:09.373

I edited to clarify the trailing whitespace condition. – Tim Seguine – 2014-01-03T14:16:44.047

Are you asking for a function? Is it acceptable to accept a string from STDIN and print the correct output to STDOUT? – Justin – 2014-01-03T22:56:18.353

@Quincunx Yes, I am accepting that as a "function".I will alter the rules to be explicit on that point. – Tim Seguine – 2014-01-04T12:30:12.087

Are blank lines allowed in the input, eg "abc\n\ndef" ? – Lyndon White – 2018-07-25T10:53:12.570

@LyndonWhite I don't remember anymore what I originally intended, but reading what I wrote, I would say yes. – Tim Seguine – 2018-07-25T12:33:41.333

Are trailing new lines allowed? – Asone Tuhid – 2018-07-30T13:20:53.040

@AsoneTuhid I think at this point it is best to say, that is unspecified. If you are following the "no trailing whitespace" rule I don't think it should make a difference. But if it does, then choose whichever you prefer. – Tim Seguine – 2018-07-30T13:38:44.247

The text transpose function cannot be an involution unless you allow for trailing ws. Example: "ac\ndef\n" ->TT-> "a\ncd\nef\n" ~ "a\ncd\nef\n" ->TT-> "acd\nef\n", where *=ws – Emanuel Landeholm – 2014-03-19T05:28:20.960

@EmanuelLandeholm it wasn't intended to be perfect. It was intended to be an involution up to trailing whitespace. "You might have to insert spaces (as in the example) where there were none in order to keep the columns in line." This never requires a whitespace character to be inserted at the end of a line. The correct transformation for your example according to the rules is: "ac\ndef\n"->"ad\ne\ncf\n"->"a*c\ndef\n" Note there is no trailing whitespace at any step and on this input it is an involution. – Tim Seguine – 2014-03-19T09:49:23.653

Answers

2

Japt, 6 bytes

y mx1R

Try it
Run it twice - returns original string


Explanation

y

Transpose the input

m  R

Map over each line

x1

Trim right

Shaggy

Posted 2014-01-03T13:19:33.003

Reputation: 24 623

4

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
  ?

marinus

Posted 2014-01-03T13:19:33.003

Reputation: 30 224

I hope you noticed I removed the prohibition for built-ins. – Tim Seguine – 2014-01-03T13:43:37.963

@Tim: Yes, otherwise I wouldn't have posted this. – marinus – 2014-01-03T13:44:50.500

Is the trailing whitespace rule written unclearly? You seem to have more characters than I expected. – Tim Seguine – 2014-01-03T13:55:10.830

How many characters should I have? The last characters on the string are ?\n. – marinus – 2014-01-03T14:02:55.473

53 I think. I intended that the lines shouldn't have trailing whitespace. So apparently it is unclearly worded. Maybe also not a reasonable requirement, since there are spaces in that position in the input. – Tim Seguine – 2014-01-03T14:08:03.140

You've got trailing whitespace on the mn, ts and tm lines. – J B – 2014-01-03T14:10:26.123

I changed the wording now in the question. I can't/won't penalize you if you don't fix it though. – Tim Seguine – 2014-01-03T14:13:39.723

@Tim: it's fixed now. – marinus – 2014-01-03T14:40:46.537

I'm going to hold off a couple days before marking this as accepted in case someone post something surprising. But I think you got this one. Nothing shorter in APL? – Tim Seguine – 2014-01-04T22:06:55.093

1@Tim: I could only get it to 44 in APL. Main reason is that APL doesn't provide either cut or dlb by default and writing them myself takes a bunch of characters even in APL. – marinus – 2014-01-05T00:29:39.040

4

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)

Joachim Isaksson

Posted 2014-01-03T13:19:33.003

Reputation: 1 161

Not exactly compliant. It should be a function take takes a string and returns a string. – Tim Seguine – 2014-01-04T12:50:56.677

@Tim Yes, missed that. Fixed now, thanks. – Joachim Isaksson – 2014-01-04T13:16:09.377

+1 you appear to be the shortest compliant python entry at the moment. – Tim Seguine – 2014-01-04T13:23:37.337

Nice use of map. I keep looking for a place to use that... and you just beat me to it. ;) – boothby – 2014-01-04T19:26:34.917

4

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

Wayne Conrad

Posted 2014-01-03T13:19:33.003

Reputation: 163

Nice. You can strip out one more character by replacing "\n" with ?\n. – O-I – 2014-01-03T21:04:11.943

Also, the .to_a is superfluous. You can gain another 5 characters there. – O-I – 2014-01-03T21:43:10.263

@O-I Thanks, I owe you six characters. I dashed this off at work, which uses 1.9.3. The to_a is required in 1.9.3, but not in 2.0. – Wayne Conrad – 2014-01-03T22:29:22.323

I see. Good to know. Consider us even for showing me a few String methods in Ruby I should be using more often. Cheers! – O-I – 2014-01-04T00:19:06.090

2Some of the code golf challenges have renewed my interest in learning ruby. – Tim Seguine – 2014-01-04T13:29:12.603

4

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.

Sven Hohenstein

Posted 2014-01-03T13:19:33.003

Reputation: 2 464

4

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
$ 

Digital Trauma

Posted 2014-01-03T13:19:33.003

Reputation: 64 644

You appear to be breaking the rule "Your result must not have trailing whitespace on any line." – Tim Seguine – 2014-03-19T09:56:14.963

@TimSeguine Oops I missed that one. I just fixed it in the latest edit. – Digital Trauma – 2014-03-19T16:56:56.880

3

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");}}

wjl

Posted 2014-01-03T13:19:33.003

Reputation: 171

I think you can take advantage of implicit int to shorten some of your declarations, or is that illegal now? – Tim Seguine – 2014-01-03T15:51:18.903

Yeah, I'm using that in a later edit to not import stdlib.h or string.h. If I don't import stdio.h it segfaults on run. – wjl – 2014-01-03T15:59:25.677

To your edit comment on the rules: your other alternative is to accept input from stdin. I would consider that conforming as well. And also, I can't tell from a cursory glance: does it strip whitespace from the ends of lines in the transpose version? – Tim Seguine – 2014-01-03T16:09:00.920

Since I re-read the file multiple times to avoid storing in RAM, reading from stdio would probably be harder. :)

I'm not sure what whitespace should be stripped. Right now I don't think it does any stripping at all, unfortunately. I'll have to work on that too. – wjl – 2014-01-03T16:18:42.700

You can declare A,B,D,I,J,*F as global variables, in order to avoid int keyword. Similarly, you can remove int from main declaration, and C argument. In C, int is optional in many places. – Konrad Borowski – 2014-01-03T16:44:32.053

To answer which whitespace must be stripped. After transposition there is most likely going to be trailing " " characters on some lines. These should be deleted. – Tim Seguine – 2014-01-04T12:28:07.487

unlucky line break. The character in the quotation marks is a space. – Tim Seguine – 2014-01-04T13:06:14.290

3

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)

Avi

Posted 2014-01-03T13:19:33.003

Reputation: 261

I can't test this one, but it looks compliant – Tim Seguine – 2014-01-04T12:56:46.803

3

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:

  • split input 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 L from split result files

memnon

Posted 2014-01-03T13:19:33.003

Reputation: 161

For the purposes of code golf, you don't necessarily have to be nice and clean up after yourself. You can leave off the rm bit from your character count. – Tim Seguine – 2014-01-05T20:15:28.487

3

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

manatwork

Posted 2014-01-03T13:19:33.003

Reputation: 17 865

+1 You golfed it better in any case. – Tim Seguine – 2014-01-17T10:54:54.767

2

Retina, 40 bytes

P`.+
~L0$`.
L,$.%'vs,$.(x$%=),`.+
m` *$

Try it online!

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.

mbomb007

Posted 2014-01-03T13:19:33.003

Reputation: 21 944

2

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>

edc65

Posted 2014-01-03T13:19:33.003

Reputation: 31 086

2

Perl 5, 25 bytes

Note that this uses ANSI escape sequences and as such does not work on TIO, you can however see it in action here.

$"="[1D";$_="[1;$.H@F"

Explanation

This code first changes the list separator ($") value to be a vertical tab, followed by the ANSI escape sequence for 'go backwards 1 column' (\x1b[1D), 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) 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.

Try it online!

Dom Hastings

Posted 2014-01-03T13:19:33.003

Reputation: 16 415

1Oh my god, the sheer horror! I love it! – Tim Seguine – 2018-08-06T12:37:47.107

2

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.

O-I

Posted 2014-01-03T13:19:33.003

Reputation: 759

I didn't notice the transpose in your answer before I wrote mine. It doesn't seem quite kosher for me to have essentially rewritten your answer, only a little better. :( – Wayne Conrad – 2014-01-04T17:07:08.410

2I don't mind at all. You came up with your code independently and it's not a race. I definitely learned something from your solution. Had you held back because I used transpose, it's possible a better Ruby solution wouldn't have surfaced. One of things I love most about programming is the willingness to collaborate and cross-pollinate ideas. Till we meet again, kind sir. Cheers! – O-I – 2014-01-04T23:45:38.563

2

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!

elixenide

Posted 2014-01-03T13:19:33.003

Reputation: 250

@TimSeguine Warnings output on screen though right? You'll have to use @ to suppress warnings. – ericw31415 – 2016-05-05T13:42:22.287

@eric I haven't been active in a while so the opinions might have changed, but in the past it was deemed acceptable to output irrelevant data to standard error. – Tim Seguine – 2016-05-05T15:09:05.460

It's allowed? If that is true, then I didn't know that. – ericw31415 – 2016-05-05T16:41:22.857

It's shorter than my php attempt. You can save two characters by gitting rid of the "s around "trim". php will give a warning, but it works just fine. – Tim Seguine – 2014-01-04T12:39:54.730

2

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)&

Murta

Posted 2014-01-03T13:19:33.003

Reputation: 339

I can't test this one, so can you verify that it removes traling whitespace on the ends of lines? Also this doesn't appear(at first glance) to define a function, which the rules require. – Tim Seguine – 2014-01-04T12:54:03.263

hi @Tim, now it is a function f!.. tks – Murta – 2014-01-04T13:03:35.370

2

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

chinese perl goth

Posted 2014-01-03T13:19:33.003

Reputation: 1 089

2

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}%

Test it here.

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.";

Martin Ender

Posted 2014-01-03T13:19:33.003

Reputation: 184 808

Eligible or not, it is a great late answer. Seems like the hardest part for this answer was dealing with the trailing spaces. – Tim Seguine – 2015-04-25T10:35:13.000

@TimSeguine Indeed. Without a built-in trimming operator, doing this manually in CJam is surprisingly cumbersome (user23013's suggestion already improved it considerably). – Martin Ender – 2015-04-25T13:00:00.617

1

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;}

Try it online!

gastropner

Posted 2014-01-03T13:19:33.003

Reputation: 3 264

1

Pyth, 11 bytes

# aYcw1;.tY

Try it online!

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.

Try it online!

KSmarts

Posted 2014-01-03T13:19:33.003

Reputation: 1 830

1

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?

Bolce Bussiere

Posted 2014-01-03T13:19:33.003

Reputation: 970

I would use cutLF. – FrownyFrog – 2017-12-06T03:56:32.993

1Save 1 character with 0|:>@cutLF – FrownyFrog – 2017-12-06T04:10:27.740

1

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

Try it online!

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 :)

Visckmart

Posted 2014-01-03T13:19:33.003

Reputation: 151

1There's nothing wrong with multiple answers in the same language. Even identical answers are allowed to an extent (though it's encouraged to at least check if you're posting the a similar solution) – Jo King – 2018-07-25T06:56:02.660

Unfortunately Your result must not have trailing whitespace on any line. – Jo King – 2018-07-30T07:33:12.080

But I can't see trailing whitespaces on the output of my code. There's no spaces after the line ends and no blank line at the end. – Visckmart – 2018-07-30T07:35:55.620

The part that seems to catch people out is *on any line*. e.g. This has extra whitespace on the second line

– Jo King – 2018-07-30T07:40:41.607

Ohhh now I got it! Sorry. I'll try to make it work as soon as I have time. I think the problem was that there's only 1 example test and I thought that would be the "stress" test hahah But ok, thanks for telling me :) – Visckmart – 2018-07-30T07:44:04.020

1

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

Try it online!

Chas Brown

Posted 2014-01-03T13:19:33.003

Reputation: 8 959

Unfortunately Your result must not have trailing whitespace on any line. Also it seems to print a lot of extra newlines. – Jo King – 2018-07-30T07:32:49.320

@Jo King: Thx - My new toy did not work here! – Chas Brown – 2018-07-30T07:44:06.910

This still has trailing whitespace on some lines for example

– Jo King – 2018-07-30T07:46:29.783

@Jo King: Ah yes. Fixed now. – Chas Brown – 2018-07-30T07:59:07.210

1

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.

Jacob Watson

Posted 2014-01-03T13:19:33.003

Reputation: 131

"Your result must not have trailing whitespace on any line." – Tim Seguine – 2018-07-30T09:04:29.067

You don't need to include the f= in the byte count. And, you can probably shorten transpose(char(s)) to char(s)' (the single quote operator acts as a transpose here). – sundar - Reinstate Monica – 2018-07-31T14:58:44.727

@sundar You're right! I use the single quote operator all the time but for some reason it totally slipped my mind while golfing... how annoying. – Jacob Watson – 2018-07-31T15:29:28.397

1

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)

Kevin Cruijssen

Posted 2014-01-03T13:19:33.003

Reputation: 67 575

1

MATL, 5 bytes

!Z{Zv

Try it on MATL Online

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

sundar - Reinstate Monica

Posted 2014-01-03T13:19:33.003

Reputation: 5 296

1

Octave, 35 29 bytes

@(s)strjoin(cellstr(s'),'\n')

Try it online!

(-1 byte thanks to Luis Mendo, -5 bytes thanks to strjoin from this SO answer)

sundar - Reinstate Monica

Posted 2014-01-03T13:19:33.003

Reputation: 5 296

You can remove the .. Best practices go out of the window in code golf :-P – Luis Mendo – 2018-07-31T15:08:14.210

@LuisMendo Ha, I didn't even realize I'd added the ., automatic muscle memory. – sundar - Reinstate Monica – 2018-07-31T15:12:24.237

1

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?`));

MattH

Posted 2014-01-03T13:19:33.003

Reputation: 171

Seems like there is still potential to golf this; a lot of big names and movable snippets – MattH – 2018-07-31T17:08:15.157

Using the same basic idea, I was able to get 92 by replacing reduce with map then filter then join(sounds longer, but you save the ternary, an assignment and some parens) – Tim Seguine – 2018-08-01T10:06:24.150

without the string parameter golfing it looks like this: q=>[...q].map((x,i)=>w.map(x=>x[i]||" ").join("").trimEnd(),w=q.split("\n")).filter(x=>x).join("\n") – Tim Seguine – 2018-08-01T10:10:33.777

Nevermind, I realized that will delete empty lines – Tim Seguine – 2018-08-01T11:54:15.503

You've made me realize my solution incorrectly handles empty lines. Regardless, thanks for your solution. – MattH – 2018-08-01T14:08:42.557

1

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;
}

David

Posted 2014-01-03T13:19:33.003

Reputation: 111

I assume you use using namespace std;. – Konrad Borowski – 2014-01-03T18:59:05.137

@xfix Not normally, but I did for this – David – 2014-01-03T19:06:13.317

1If I am being picky, I would say using namespace std; should be added to the character count. – Tim Seguine – 2014-01-04T12:45:32.627

1

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

0x90

Posted 2014-01-03T13:19:33.003

Reputation: 111

You are not stripping the trailing whitespace on your lines like the rules require. – Tim Seguine – 2014-01-04T12:35:49.920

Also, it's actually 116 bytes, \n is considered by len to be a single char, but it's two :) – Joachim Isaksson – 2014-01-04T13:22:29.617

1@JoachimIsaksson on unix \n is one. So I say one is fine. – Tim Seguine – 2014-01-04T15:44:48.113

@Tim len("\n") will show 1, although it's certainly 2 separate characters in the source code. Saving the source to a file will make ls display 116. Just saying that len isn't the best way to measure code size due to escape characters being processed before measuring :) – Joachim Isaksson – 2014-01-04T15:51:38.977

@JoachimIsaksson oh, sorry I misunderstood your point. – Tim Seguine – 2014-01-04T21:58:01.263

1

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.

Ilmari Karonen

Posted 2014-01-03T13:19:33.003

Reputation: 19 513

Your assumption is correct. It should work on any ASCII text under the assumptions allowed in the rules. – Tim Seguine – 2014-01-04T13:03:59.250

1

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. :^)

TrevorM

Posted 2014-01-03T13:19:33.003

Reputation: 111

not a function. – Tim Seguine – 2014-01-04T13:24:48.620

@Tim My bad, fixed. Anyway my solution is inferior to Joachim Isaksson's. I wonder if there's any short way to solve this problem with recursion. – TrevorM – 2014-01-04T21:08:16.210

1

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)))

tasegula

Posted 2014-01-03T13:19:33.003

Reputation: 141

1

Haskell

import Data.List
main = interact (unlines . transpose . lines)

It was so short, I needed to add in white space...

randomusername

Posted 2014-01-03T13:19:33.003

Reputation: 127

I'm almost sure you can remove some of the whitespace here. But otherwise, great solution. – Konrad Borowski – 2014-01-04T09:05:17.900

3This doesn't quite work on my system. It's a bit hard to show in a comment, but if you run it twice you get I am a text..? Transpose met Can you do i. – marinus – 2014-01-04T10:42:43.680

Yeah, I am thinking maybe you are not padding the lines to keep the columns intact like the example does. Theorectally, the result of running the function twice should be the original string(with possibly the addition or removal of the final newline.) – Tim Seguine – 2014-01-04T12:33:12.457

1

Mathematica, 95 chars

f=""<>Riffle[Thread@PadRight@Characters@StringSplit[#,"\n"]//.{0->" ",{x___," "..}:>{x}},"\n"]&

alephalpha

Posted 2014-01-03T13:19:33.003

Reputation: 23 988

1

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"

tmartin

Posted 2014-01-03T13:19:33.003

Reputation: 3 917

The output appears to be an array of strings? – Tim Seguine – 2014-03-19T17:02:37.550

@Tim It is. If you want a single string then add three chars. {\/:x@'/:!max@#:'x:`:x}` for 26. – tmartin – 2014-03-19T17:39:38.123

You also have a problem with trailing whitespace. And "If it accepts a filename, then you return the name of the file where you saved the result." You need to return output in the same manner you accept input. – Tim Seguine – 2014-03-20T10:18:25.250

@Tim should be fixed now. Kills my bytecount though – tmartin – 2014-03-20T12:09:06.787

I suspected it might :( , but a spec is a spec. – Tim Seguine – 2014-03-20T12:13:05.590

1

Groovy, 98 chars

{i->o=[].withDefault{''};i.readLines().each{it.toList().eachWithIndex{c,d->o[d]+=c}};o.join('\n')}

online

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
}

Krzysztof Atłasik

Posted 2014-01-03T13:19:33.003

Reputation: 189

0

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.

Titus

Posted 2014-01-03T13:19:33.003

Reputation: 13 814

In general, I like this answer, but there are a number of issues; read the spec: "Your result must not have trailing whitespace on any line". Also, the rules for I/O are slightly ambiguous, but this isn't technically one of the allowed options, and this definitely isn't a complete program since you have to invoke the interpreter with non-default options. – Tim Seguine – 2017-12-02T14:03:21.640

Unless I am more rusty at PHP than I thought, the way you are calling file(f) will result in a warning being printed to stderr, which since you are using stdout as your output method is also not allowed. If there is a specific version of the PHP interpreter that no longer has this behviour(it used to IIRC), then please specify or correct me if I am wrong. – Tim Seguine – 2017-12-02T14:06:23.753

The simplest correction to everything but the endline issue that I can think of at the moment results in 8 additional characters. The simplest solution for the endline issue I can think of adds an extra 7. That still makes it by far the shortest PHP entry. – Tim Seguine – 2017-12-02T14:10:55.467

@TimSeguine 1) -n (no config file) tells the compiler to run with the default options. 2) The rules are ridiculous, but I´ll look into resolving the "issues" anyway. – Titus – 2017-12-02T15:15:48.593

@TimSeguine ... and the default options include error_reporting=E_ALL&~E_NOTICE (undefined constant "f", assuming string is a notice, not a warning) – Titus – 2017-12-02T16:05:18.430

If you don't like the rules then don't post an answer, it's that simple. Being able to follow a spec exactly is an important part of being a good engineer. I have relatively little interest in this site anymore, so any time spent on arguing about the spec is time I consider wasted. – Tim Seguine – 2017-12-02T16:14:59.170

@TimSeguine Sorry. let me rephrase: not "ridiculous" but "unusual". But ok. I´d love to see your solutions to the issues. – Titus – 2017-12-03T11:20:26.263

1I have a few ideas for how to shave characters, but I don't have time to try any out for now. What I see is no reason to use $argn instead of STDIN for the purpose of the challenge. And is the $x=> important? looks like just a waste of 4 chars to me. If you are curious, the rules were an attempt at leveling the playing field with code golfing specific languages. How successful I was in that goal is debatable. – Tim Seguine – 2017-12-04T14:26:42.547

0

Perl 5, 81 bytes

chomp(@a=<>);say((join"",map{(substr$_,0,1,"")||$"}@a)=~s/\s+$//r)while"@a"=~/\S/

Try it online!

Xcali

Posted 2014-01-03T13:19:33.003

Reputation: 7 671

0

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

Try it online!

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

dragonite44

Posted 2014-01-03T13:19:33.003

Reputation: 91

0

Pyth, 2 bytes

.t

Try it here!

Performs the built in transpose function on an input list, outputting a list of lines.


Pyth, 7 bytes

V.t.zdN

Try it here!

The above program, modified to use the input and output format specified in the challenge.

hakr14

Posted 2014-01-03T13:19:33.003

Reputation: 1 295

From the spec: *"Your result must not have trailing whitespace on any line."* - it caught me out as well. – Shaggy – 2018-07-19T13:45:30.717

0

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

Taylor Scott

Posted 2014-01-03T13:19:33.003

Reputation: 6 709

0

Charcoal, 7 3 bytes (non-competing)

↓S‖

-4 bytes thanks to @ASCII-only.

Try it online (verbose) or try it online (pure).

Non-competing because it contains trailing spaces.

Explanation:

Print the multi-line input in a downward direction:

Print(:Down, InputString());
↓S

Reflect everything so the lines are outputted in the correct order:

Reflect();
‖

Kevin Cruijssen

Posted 2014-01-03T13:19:33.003

Reputation: 67 575

I think there is a similar challenge that has the rules people seem to expect for trailing whitespace. – Tim Seguine – 2018-07-30T09:13:36.993

@TimSeguine Do you perhaps have a link to that similar challenge? Then I will delete this answer here and post it there. – Kevin Cruijssen – 2018-07-30T09:22:32.750

http://codegolf.stackexchange.com/q/85255 expects the input strings to all be the same size, so they didn't have to invent any special rules for jagged input like I did. – Tim Seguine – 2018-07-30T09:27:48.863

1maybe 3 :P – ASCII-only – 2018-08-06T06:18:52.163

@ASCII-only Thanks! Btw, is there any way in Charcoal to remove those trailing spaces to make it compatible? – Kevin Cruijssen – 2018-08-06T06:54:14.013

@KevinCruijssen There is, kinda but there needs to be absolutely nothing there (i.e. not been written on before). I'm not sure what would be the best way to introduce a delete command. Maybe a new "printable" character (like \x00, \n and \r)?

– ASCII-only – 2018-08-06T06:58:13.770

@ASCII-only I indeed saw the ToggleTrim, but unfortunately it doesn't work with the challenge. Probably because of what you state: there should be nothing written on before. And a replace or delete function would be useful, but I wouldn't add it just for the sake of this challenge. Having to remove trailing whitespaces is kinda an exception for code-golf challenges..

– Kevin Cruijssen – 2018-08-06T07:04:56.870

@KevinCruijssen Yeah, IMO the biggest issue would be supporting a wide range of ways to delete (i.e. same capabilities as the current printing methods) – ASCII-only – 2018-08-06T07:07:45.557

0

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));

Tim Seguine

Posted 2014-01-03T13:19:33.003

Reputation: 824

0

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)

Impredicative

Posted 2014-01-03T13:19:33.003

Reputation: 101

It's usually good to add some explanatory text. It helps those who don't know the language to decide to vote you up. :) – luser droog – 2014-01-06T15:37:36.120

0

K (oK), 43 bytes

Solution:

{"\n"/{(-+/&\32=|x)_x}@'+(|/#:'x)$x:"\n"\x}

Try it online!

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"

streetster

Posted 2014-01-03T13:19:33.003

Reputation: 3 635

0

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.

ericw31415

Posted 2014-01-03T13:19:33.003

Reputation: 2 229