3
\$\begingroup\$

Let's say you've got a table of data:

meter_id date   0000 0600 1200 1800
0        030915 10   20   30   40
1        030915 15   7    49   2

where the last four columns are meter readings at different times. You want to output

meter_id date   time reading
0        030915 0000 10
0        030915 0600 20

etc.

Your input and output will not have headers, unlike in this example. The set of columns you'll transpose will be provided as numeric arguments to your program, from 1 onwards. Input is stdin and output is stdout.

So here's an example of it actually being used.

$ ./tpose 3 4 5 6

Stdin:

0        030915 10   20   30   40
1        030915 15   7    49   2

Stdout:

0       030915  3       10
0       030915  4       20
0       030915  5       30
0       030915  6       40
1       030915  3       15
1       030915  4       7
1       030915  5       49
1       030915  6       2

The third column contains values from 3 to 6. This is because the reading is from columns 3 to 6 from the input table.

Happy golfing.

\$\endgroup\$
  • 4
    \$\begingroup\$ Can you post some example inputs and outputs? \$\endgroup\$ – kirbyfan64sos Oct 9 '15 at 14:18
  • \$\begingroup\$ Is 0600 30 in the example just wrong (1200 is 30), or are you trying to do cumulative readings (so adding the current 20 to the previous 10)? \$\endgroup\$ – Geobits Oct 9 '15 at 14:20
  • \$\begingroup\$ @Geobits Fixed. \$\endgroup\$ – jkabrg Oct 9 '15 at 14:21
  • \$\begingroup\$ You say in the text that the values in the third column of the output are 3 to 6, but they are actually 2 to 5. Which one is right? Right now, it looks like you're using 1-based column indices in the input, and 0-based in the output. \$\endgroup\$ – Reto Koradi Oct 9 '15 at 15:16
  • 1
    \$\begingroup\$ Do the columns to be transposed always form a contiguous range? Can other columns appear after them? If yes, where should the transposed columns appear in the output? Are the columns to be transposed always given in ascending order, and can they contain the same column twice? And if so, can we reorder them in the output, or collapse duplicates? \$\endgroup\$ – Ilmari Karonen Oct 10 '15 at 17:00
3
\$\begingroup\$

kdb k, 101 bytes

1@"\n"/:{"\n"/:{" "/:(r@&{~#&x=a}'!#r),(,$1+a@x),,c@x}'!#c::(r::" "\:x)@a::-1+.:'.z.x}'-1_"\n"\:0::0;

Me: (reads the word "transpose" in the title) K will be perfect for this! It'll kick everything else's hind!

20 minutes and 101 bytes later

Me: Idiot.

\$\endgroup\$
2
\$\begingroup\$

Ruby, 88 84 bytes

Input is tab-separated. Annoyingly, Ruby gets pulls from files whose names match those from ARGV, but those don't exist so the program errors out. To work around this, I have to use STDIN.gets to get the actual correct input.

-4 bytes by remembering that I don't actually need to use scan since I'm only matching the pattern once per line anyways, so =~ for a single regex match saves bytes.

($_=~/(\d+	\w+	)(.*)/;i=-1;puts$2.split.map{|s|"#$1#{$*[i+=1]}	"+s})while STDIN.gets

Try it online!

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

Perl 5, 87 bytes

perl -E'while(<STDIN>){@f=(0,split);@i=0..$#f,@i[@ARGV]=0;say"@f[grep$_,@i] $_ $f[$_]"for@ARGV}'
\$\endgroup\$
1
\$\begingroup\$

Haskell (195 bytes)

import System.Environment
main=do s<-getArgs>>=return.map(\a->read a-1);interact$unlines.map unwords.t s.map words.lines
t g r=[[a!!j|j<-[0..length a-1],not$j`elem`g]++show(j+1):[a!!j]|a<-r,j<-g]

Ungolfed Haskell (398 bytes):

import System.Environment
import Prelude

main = do js <- getArgs >>= return . map (\a -> read a - 1)
          interact $ unbr . (`tpose` js) . br

br = map words . lines

xs `excludingFrom` es = [xs !! j | j <- [0..length xs - 1], not $ j `elem` es]

tpose rows js = [row `excludingFrom` js ++ [show (j+1)] ++ [row !! j] | row <- rows, j <- js]

unbr = unlines . map (foldr1 $ \t a -> t++"\t"++a)
\$\endgroup\$
  • \$\begingroup\$ p>>=return.f should generally be written f<$>p. In this case, though, you can golf more by just using s<-getArgs and applying the parsing inline. Since you use map three times, you should write m=map on its own line and use that. \$\endgroup\$ – dfeuer Jul 3 at 4:02
1
\$\begingroup\$

PHP, 90 bytes

while($r=fgetcsv(STDIN,0,' '))foreach($argv as$a)if($a|0)echo"$r[0] $r[1] $a {$r[$a-1]}
";

Input and output with single space delimiter.

Try it online!

PHP, 109 bytes

while($r=preg_split("/\s+/",fgets(STDIN),0,1))foreach($argv as$a)if($a|0)echo"$r[0]\t$r[1]\t$a\t{$r[$a-1]}
";

Or with I/O exactly as shown above, using fixed width columns.

Try it online!

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

APL (Dyalog Unicode), 56 bytesSBCS

Anonymous prefix lambda. Takes column numbers for "transposition" as right argument and prompts via stdin for filename of table.

{(t[;⍵~⍨⍳≢⍉t]⌿⍨≢⍵),(⍪,⍨⍵⍴⍨≢),t[;⍵]⊣t←↑(∊∘⎕D⊆⊢)¨⊃⎕NGET⍞1}

Try it online!

{} "dfn"; right argument (column numbers) is :

⍞1 prompt for file name from stdin and juxtapose with 1 (indicating that we want a list of strings)
  ["tpose",1]

⎕NGETget the native file's (content,encoding,newline)
  [["0 030915 10 20 30 40","1 030915 15 7 49 2"],"UTF-8-NOBOM",[10]]

 pick the first of those (content)
  ["0 030915 10 20 30 40","1 030915 15 7 49 2"]

( apply the following tacit function to each line:

   the characters that are members
   of
  ⎕D the set of digits
   [[1,0,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1],[1,0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1]]

   indicate the sub-partitions of

   the line
   [["0","030915","10","20","30","40"],["1","030915","15","7","49","2"]]

 up the rank by mixing the list (rank 1) of lists into a matrix (rank 2)
  [["0","030915","10","20","30","40"],
   ["1","030915","15","7" ,"49","2" ]]

t← assign that to t (for table)

 discard that in favour of

t[;⍵] all rows of the subset of columns of t enumerated in the argument
  [["10","20","30","40"],
   ["15","7" ,"49","2" ]]

, ravel (flatten that)
  ["10","20","30","40","15","7","49","2"]

() apply the following tacit function to that:

   the tally of elements
   8

  ⍵⍴⍨ use that to reshape the number of columns to be "transposed"
   [3,4,5,6,3,4,5,6]

,⍨ to that, append

 the table-fied (made into single-column table) argument (the "transposed" columns)
  [[3,"10"],
   [4,"20"],
   [5,"30"],
   [6,"40"],
   [3,"15"],
   [4,"7" ],
   [5,"49"],
   [6,"2" ]]

(), prepend the following:

  ≢⍵ the tally of columns to be "transposed"
   4

  …⌿⍨ use that to vertically replicate the rows of…

   t[;] all rows of the following columns of the table:

    ⍉t transpose the table
     [["0" ,"1" ],
      ["030915","030915"],
      ["10" ,"15" ],
      ["20" ,"7" ],
      ["30" ,"49" ],
      ["40" ,"2" ]]

     the tally of rows
     6

    ɩndices until that
     [1,2,3,4,5,6]

    ⍵~⍨ except the "transposed" column numbers
     [1,2]

   [["0","030915"],
    ["1","030915"]]

  [["0","030915"],
   ["0","030915"],
   ["0","030915"],
   ["0","030915"],
   ["1","030915"],
   ["1","030915"],
   ["1","030915"],
   ["1","030915"]]

[["0","030915",3,"10"],
["0","030915",4,"20"],
["0","030915",5,"30"],
["0","030915",6,"40"],
["1","030915",3,"15"],
["1","030915",4,"7" ],
["1","030915",5,"49"],
["1","030915",6,"2" ]]

\$\endgroup\$

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.