 # paulfioravanti's solution

## to Transpose in the Ruby Track

Published at May 20 2019 · 0 comments
Instructions
Test suite
Solution

#### Note:

This exercise has changed since this solution was written.

Given an input text output it transposed.

Roughly explained, the transpose of a matrix:

``````ABC
DEF
``````

is given by:

``````AD
BE
CF
``````

Rows become columns and columns become rows. See https://en.wikipedia.org/wiki/Transpose.

If the input has rows of different lengths, this is to be solved as follows:

• Pad to the left with spaces.
• Don't pad to the right.

Therefore, transposing this matrix:

``````ABC
DE
``````

results in:

``````AD
BE
C
``````

And transposing:

``````AB
DEF
``````

results in:

``````AD
BE
F
``````

In general, all characters from the input should also be present in the transposed output. That means that if a column in the input text contains only spaces on its bottom-most row(s), the corresponding output row should contain the spaces in its right-most column(s).

For installation and learning resources, refer to the Ruby resources page.

For running the tests provided, you will need the Minitest gem. Open a terminal window and run the following command to install minitest:

``````gem install minitest
``````

If you would like color output, you can `require 'minitest/pride'` in the test file, or note the alternative instruction, below, for running the test file.

Run the tests from the exercise directory using the following command:

``````ruby transpose_test.rb
``````

To include color from the command line:

``````ruby -r minitest/pride transpose_test.rb
``````

## Source

Reddit r/dailyprogrammer challenge #270 [Easy]. https://www.reddit.com/r/dailyprogrammer/comments/4msu2x/challenge_270_easy_transpose_the_input_text

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### transpose_test.rb

``````require 'minitest/autorun'
require_relative 'transpose'

# Common test data version: 1.1.0 92bc877
class TransposeTest < Minitest::Test
def test_empty_string
# skip
input = <<~INPUT.strip

INPUT

expected = <<~EXPECTED.strip

EXPECTED

assert_equal expected, Transpose.transpose(input)
end

def test_two_characters_in_a_row
skip
input = <<~INPUT.strip
A1
INPUT

expected = <<~EXPECTED.strip
A
1
EXPECTED

assert_equal expected, Transpose.transpose(input)
end

def test_two_characters_in_a_column
skip
input = <<~INPUT.strip
A
1
INPUT

expected = <<~EXPECTED.strip
A1
EXPECTED

assert_equal expected, Transpose.transpose(input)
end

def test_simple
skip
input = <<~INPUT.strip
ABC
123
INPUT

expected = <<~EXPECTED.strip
A1
B2
C3
EXPECTED

assert_equal expected, Transpose.transpose(input)
end

def test_single_line
skip
input = <<~INPUT.strip
Single line.
INPUT

expected = <<~EXPECTED.strip
S
i
n
g
l
e

l
i
n
e
.
EXPECTED

assert_equal expected, Transpose.transpose(input)
end

def test_first_line_longer_than_second_line
skip
input = <<~INPUT.strip
The fourth line.
The fifth line.
INPUT

expected = <<~EXPECTED.strip
TT
hh
ee

ff
oi
uf
rt
th
h
l
li
in
ne
e.
.
EXPECTED

assert_equal expected, Transpose.transpose(input)
end

def test_second_line_longer_than_first_line
skip
input = <<~INPUT.strip
The first line.
The second line.
INPUT

expected = <<~EXPECTED.strip
TT
hh
ee

fs
ie
rc
so
tn
d
l
il
ni
en
.e
.
EXPECTED

assert_equal expected, Transpose.transpose(input)
end

def test_mixed_line_length
skip
input = <<~INPUT.strip
The longest line.
A long line.
A longer line.
A line.
INPUT

expected = <<~EXPECTED.strip
TAAA
h
elll
ooi
lnnn
ogge
n e.
glr
ei
snl
tei
.n
l e
i .
n
e
.
EXPECTED

assert_equal expected, Transpose.transpose(input)
end

def test_square
skip
input = <<~INPUT.strip
HEART
EMBER
ABUSE
RESIN
TREND
INPUT

expected = <<~EXPECTED.strip
HEART
EMBER
ABUSE
RESIN
TREND
EXPECTED

assert_equal expected, Transpose.transpose(input)
end

def test_rectangle
skip
input = <<~INPUT.strip
FRACTURE
OUTLINED
BLOOMING
SEPTETTE
INPUT

expected = <<~EXPECTED.strip
FOBS
RULE
ATOP
CLOT
TIME
UNIT
RENT
EDGE
EXPECTED

assert_equal expected, Transpose.transpose(input)
end

def test_triangle
skip
input = <<~INPUT.strip
T
EE
AAA
SSSS
EEEEE
RRRRRR
INPUT

expected = <<~EXPECTED.strip
TEASER
EASER
ASER
SER
ER
R
EXPECTED

assert_equal expected, Transpose.transpose(input)
end
end``````
``````# frozen_string_literal: true

module Transpose
NEWLINE = "\n"
private_constant :NEWLINE
SPACE = " "
private_constant :SPACE

module_function

def transpose(input)
return "" if input.empty?

lines = generate_lines(input)
max_line_width = max_line_width(lines)
lines
.each
.with_object(max_line_width)
.transpose
.join(NEWLINE)
end

def generate_lines(input)
input
.split(NEWLINE)
.map(&:chars)
end
private_class_method :generate_lines

def max_line_width(lines)
lines
.map(&:length)
.max
end
private_class_method :max_line_width

line.values_at(0...max_line_width)
end

lines
.lazy
.map(&method(:replace_nils_with_spaces))
.map(&:join)
.to_a
end

line
.reverse
.drop_while(&:nil?)
.reverse
end

def replace_nils_with_spaces(line)
line.map { |char| char || SPACE }
end
private_class_method :replace_nils_with_spaces
end``````