Skip to content

* add practice exercise: transpose #128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,14 @@
"prerequisites": [],
"difficulty": 8
},
{
"slug": "transpose",
"name": "Transpose",
"uuid": "501d8d8b-4dd9-457d-866f-88120f046277",
"practices": [],
"prerequisites": [],
"difficulty": 8
},
{
"slug": "word-count",
"name": "Word Count",
Expand Down
61 changes: 61 additions & 0 deletions exercises/practice/transpose/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Instructions

Given an input text output it transposed.

Roughly explained, the transpose of a matrix:

```text
ABC
DEF
```

is given by:

```text
AD
BE
CF
```

Rows become columns and columns become rows.
See [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:

```text
ABC
DE
```

results in:

```text
AD
BE
C
```

And transposing:

```text
AB
DEF
```

results in:

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

[transpose]: https://en.wikipedia.org/wiki/Transpose
19 changes: 19 additions & 0 deletions exercises/practice/transpose/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"jimmytty"
],
"files": {
"solution": [
"transpose.sql"
],
"test": [
"transpose_test.sql"
],
"example": [
".meta/example.sql"
]
},
"blurb": "Take input text and output it transposed.",
"source": "Reddit r/dailyprogrammer challenge #270 [Easy].",
"source_url": "https://web.archive.org/web/20230630051421/https://old.reddit.com/r/dailyprogrammer/comments/4msu2x/challenge_270_easy_transpose_the_input_text/"
}
63 changes: 63 additions & 0 deletions exercises/practice/transpose/.meta/example.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
DROP TABLE IF EXISTS jmatrix;
CREATE TEMPORARY TABLE jmatrix AS
SELECT lines,
(
WITH to_line (line) AS (
WITH RECURSIVE split_lines (string, line) AS (
VALUES (REPLACE(lines, ' ', CHAR(7))||CHAR(10), NULL)
UNION ALL
SELECT SUBSTR(string, INSTR(string, CHAR(10)) + 1),
SUBSTR(string, 1, INSTR(string, CHAR(10)) - 1)
FROM split_lines
WHERE string <> ''
)
SELECT line FROM split_lines WHERE line NOTNULL
)
SELECT JSON_GROUP_ARRAY(
(
WITH RECURSIVE to_letter (string, letter) AS (
VALUES (
PRINTF('%-*s', (SELECT MAX(LENGTH(line)) FROM to_line), line),
NULL
)
UNION ALL
SELECT SUBSTR(string, 2), SUBSTR(string, 1, 1)
FROM to_letter
WHERE string <> ''
)
SELECT JSON_GROUP_ARRAY(letter)
FROM to_letter
WHERE letter NOTNULL
)
) AS matrix
FROM to_line
) AS matrix
FROM transpose
;

UPDATE transpose SET result = '' WHERE lines = '';

UPDATE transpose
SET result = (
WITH RECURSIVE to_transpose (jarray, idx, ncols, new_row) AS (
VALUES (
jmatrix.matrix,
0,
JSON_ARRAY_LENGTH(JSON_EXTRACT(jmatrix.matrix, '$[0]')),
NULL
)
UNION ALL
SELECT jarray, idx + 1, ncols, (
SELECT GROUP_CONCAT(JSON_EXTRACT(j.value, PRINTF('$[%d]', idx)), '')
FROM JSON_EACH(jarray) j
)
FROM to_transpose
WHERE idx < ncols
)
SELECT GROUP_CONCAT(REPLACE(RTRIM(new_row,' '), CHAR(7), ' '), CHAR(10))
FROM to_transpose
)
FROM jmatrix
WHERE transpose.lines = jmatrix.lines
AND result ISNULL
;
46 changes: 46 additions & 0 deletions exercises/practice/transpose/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[404b7262-c050-4df0-a2a2-0cb06cd6a821]
description = "empty string"

[a89ce8a3-c940-4703-a688-3ea39412fbcb]
description = "two characters in a row"

[855bb6ae-4180-457c-abd0-ce489803ce98]
description = "two characters in a column"

[5ceda1c0-f940-441c-a244-0ced197769c8]
description = "simple"

[a54675dd-ae7d-4a58-a9c4-0c20e99a7c1f]
description = "single line"

[0dc2ec0b-549d-4047-aeeb-8029fec8d5c5]
description = "first line longer than second line"

[984e2ec3-b3d3-4b53-8bd6-96f5ef404102]
description = "second line longer than first line"

[eccd3784-45f0-4a3f-865a-360cb323d314]
description = "mixed line length"

[85b96b3f-d00c-4f80-8ca2-c8a5c9216c2d]
description = "square"

[b9257625-7a53-4748-8863-e08e9d27071d]
description = "rectangle"

[b80badc9-057e-4543-bd07-ce1296a1ea2c]
description = "triangle"

[76acfd50-5596-4d05-89f1-5116328a7dd9]
description = "jagged triangle"
11 changes: 11 additions & 0 deletions exercises/practice/transpose/create_fixture.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
DROP TABLE IF EXISTS transpose;
CREATE TABLE transpose (
lines TEXT NOT NULL,
result TEXT
);

.mode csv
.import ./data.csv transpose

UPDATE transpose SET result = NULL;
UPDATE transpose SET lines = REPLACE(lines, '\n', CHAR(10));
34 changes: 34 additions & 0 deletions exercises/practice/transpose/create_test_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
DROP TABLE IF EXISTS tests;
CREATE TABLE IF NOT EXISTS tests (
-- uuid and description are taken from the test.toml file
uuid TEXT PRIMARY KEY,
description TEXT NOT NULL,
-- The following section is needed by the online test-runner
status TEXT DEFAULT 'fail',
message TEXT,
output TEXT,
test_code TEXT,
task_id INTEGER DEFAULT NULL,
-- Here are columns for the actual tests
lines TEXT NOT NULL,
expected TEXT NOT NULL
);

INSERT INTO tests (uuid, description, lines, expected)
VALUES
('404b7262-c050-4df0-a2a2-0cb06cd6a821', 'empty string', '', ''),
('a89ce8a3-c940-4703-a688-3ea39412fbcb', 'two characters in a row', 'A1', 'A\n1'),
('855bb6ae-4180-457c-abd0-ce489803ce98', 'two characters in a column', 'A\n1', 'A1'),
('5ceda1c0-f940-441c-a244-0ced197769c8', 'simple', 'ABC\n123', 'A1\nB2\nC3'),
('a54675dd-ae7d-4a58-a9c4-0c20e99a7c1f', 'single line', 'Single line.', 'S\ni\nn\ng\nl\ne\n \nl\ni\nn\ne\n.'),
('0dc2ec0b-549d-4047-aeeb-8029fec8d5c5', 'first line longer than second line', 'The fourth line.\nThe fifth line.', 'TT\nhh\nee\n \nff\noi\nuf\nrt\nth\nh \n l\nli\nin\nne\ne.\n.'),
('984e2ec3-b3d3-4b53-8bd6-96f5ef404102', 'second line longer than first line', 'The first line.\nThe second line.', 'TT\nhh\nee\n \nfs\nie\nrc\nso\ntn\n d\nl \nil\nni\nen\n.e\n .'),
('eccd3784-45f0-4a3f-865a-360cb323d314', 'mixed line length', 'The longest line.\nA long line.\nA longer line.\nA line.', 'TAAA\nh \nelll\n ooi\nlnnn\nogge\nn e.\nglr\nei \nsnl\ntei\n .n\nl e\ni .\nn\ne\n.'),
('85b96b3f-d00c-4f80-8ca2-c8a5c9216c2d', 'square', 'HEART\nEMBER\nABUSE\nRESIN\nTREND', 'HEART\nEMBER\nABUSE\nRESIN\nTREND'),
('b9257625-7a53-4748-8863-e08e9d27071d', 'rectangle', 'FRACTURE\nOUTLINED\nBLOOMING\nSEPTETTE', 'FOBS\nRULE\nATOP\nCLOT\nTIME\nUNIT\nRENT\nEDGE'),
('b80badc9-057e-4543-bd07-ce1296a1ea2c', 'triangle', 'T\nEE\nAAA\nSSSS\nEEEEE\nRRRRRR', 'TEASER\n EASER\n ASER\n SER\n ER\n R'),
('76acfd50-5596-4d05-89f1-5116328a7dd9', 'jagged triangle', '11\n2\n3333\n444\n555555\n66666', '123456\n1 3456\n 3456\n 3 56\n 56\n 5');

UPDATE tests
SET lines = REPLACE(lines, '\n', CHAR(10)),
expected = REPLACE(expected, '\n', CHAR(10));
12 changes: 12 additions & 0 deletions exercises/practice/transpose/data.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"",
"A1",
"A\n1",
"ABC\n123",
"Single line.",
"The fourth line.\nThe fifth line.",
"The first line.\nThe second line.",
"The longest line.\nA long line.\nA longer line.\nA line.",
"HEART\nEMBER\nABUSE\nRESIN\nTREND",
"FRACTURE\nOUTLINED\nBLOOMING\nSEPTETTE",
"T\nEE\nAAA\nSSSS\nEEEEE\nRRRRRR",
"11\n2\n3333\n444\n555555\n66666",
7 changes: 7 additions & 0 deletions exercises/practice/transpose/transpose.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- Schema:
-- CREATE TABLE transpose (
-- lines TEXT NOT NULL,
-- result TEXT
-- );
--
-- Task: update the transpose table and set the result based on the lines.
40 changes: 40 additions & 0 deletions exercises/practice/transpose/transpose_test.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
-- Create database:
.read ./create_fixture.sql

-- Read user student solution and save any output as markdown in user_output.md:
.mode markdown
.output user_output.md
.read ./transpose.sql
.output

-- Create a clean testing environment:
.read ./create_test_table.sql

-- Comparison of user input and the tests updates the status for each test:
UPDATE tests
SET status = 'pass'
FROM (SELECT lines, result FROM transpose) AS actual
WHERE (actual.lines, actual.result) = (tests.lines, tests.expected);

-- Update message for failed tests to give helpful information:
UPDATE tests
SET message = (
'Result for "'
|| tests.lines
|| '"'
|| ' is <' || COALESCE(actual.result, 'NULL')
|| '> but should be <' || tests.expected || '>'
)
FROM (SELECT lines, result FROM transpose) AS actual
WHERE actual.lines = tests.lines AND tests.status = 'fail';

-- Save results to ./output.json (needed by the online test-runner)
.mode json
.once './output.json'
SELECT description, status, message, output, test_code, task_id
FROM tests;

-- Display test results in readable form for the student:
.mode table
SELECT description, status, message
FROM tests;