diff --git a/config.json b/config.json index d9cdc899..3df444e7 100644 --- a/config.json +++ b/config.json @@ -644,6 +644,14 @@ "prerequisites": [], "difficulty": 4 }, + { + "slug": "transpose", + "name": "Transpose", + "uuid": "486e4c05-1741-4b33-8191-86bd3f50149d", + "practices": [], + "prerequisites": [], + "difficulty": 4 + }, { "slug": "twelve-days", "name": "Twelve Days", diff --git a/exercises/practice/transpose/.docs/instructions.md b/exercises/practice/transpose/.docs/instructions.md new file mode 100644 index 00000000..6033af74 --- /dev/null +++ b/exercises/practice/transpose/.docs/instructions.md @@ -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 diff --git a/exercises/practice/transpose/.meta/config.json b/exercises/practice/transpose/.meta/config.json new file mode 100644 index 00000000..5fcabc9f --- /dev/null +++ b/exercises/practice/transpose/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "keiravillekode" + ], + "files": { + "solution": [ + "transpose.el" + ], + "test": [ + "transpose-test.el" + ], + "example": [ + ".meta/example.el" + ] + }, + "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/" +} diff --git a/exercises/practice/transpose/.meta/example.el b/exercises/practice/transpose/.meta/example.el new file mode 100644 index 00000000..26c61bbe --- /dev/null +++ b/exercises/practice/transpose/.meta/example.el @@ -0,0 +1,33 @@ +;;; transpose.el --- Transpose (exercism) -*- lexical-binding: t; -*- + +;;; Commentary: + +;;; Code: + +(require 'cl-lib) + +(defun column (col reversed height) + (cond ((null reversed) "") + ((<= (length (car reversed)) col) (column col (cdr reversed) (1- height))) + (t (let ((word (make-string height ?\s))) + (cl-loop + for row from (1- height) downto 0 + for line = (car reversed) + + when (< col (length line)) + do (aset word row (aref line col)) + + do (setq reversed (cdr reversed))) + word)))) + +(defun transpose (lines) + (when lines + (let ((height (length lines)) + (width (apply #'max (mapcar #'length lines))) + (reversed (reverse lines))) + (cl-loop for col from 0 below width + collect (column col reversed height))))) + +(provide 'transpose) +;;; transpose.el ends here + diff --git a/exercises/practice/transpose/.meta/tests.toml b/exercises/practice/transpose/.meta/tests.toml new file mode 100644 index 00000000..32e366fb --- /dev/null +++ b/exercises/practice/transpose/.meta/tests.toml @@ -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" diff --git a/exercises/practice/transpose/transpose-test.el b/exercises/practice/transpose/transpose-test.el new file mode 100644 index 00000000..21d57ed4 --- /dev/null +++ b/exercises/practice/transpose/transpose-test.el @@ -0,0 +1,178 @@ +;;; transpose-test.el --- Tests for Transpose (exercism) -*- lexical-binding: t; -*- + +;;; Commentary: + +;;; Code: + + +(load-file "transpose.el") +(declare-function transpose "transpose.el" (lines)) + + +(ert-deftest empty-string () + (let ((expected '())) + (should (equal (transpose '()) expected)))) + + +(ert-deftest two-characters-in-a-row () + (let ((expected '("A" + "1"))) + (should (equal (transpose '("A1")) expected)))) + + +(ert-deftest two-characters-in-a-column () + (let ((expected '("A1"))) + (should (equal (transpose '("A" + "1")) expected)))) + + +(ert-deftest simple () + (let ((expected '("A1" + "B2" + "C3"))) + (should (equal (transpose '("ABC" + "123")) expected)))) + + +(ert-deftest single-line () + (let ((expected '("S" + "i" + "n" + "g" + "l" + "e" + " " + "l" + "i" + "n" + "e" + "."))) + (should (equal (transpose '("Single line.")) expected)))) + + +(ert-deftest first-line-longer-than-second-line () + (let ((expected '("TT" + "hh" + "ee" + " " + "ff" + "oi" + "uf" + "rt" + "th" + "h " + " l" + "li" + "in" + "ne" + "e." + "."))) + (should (equal (transpose '("The fourth line." + "The fifth line.")) expected)))) + + +(ert-deftest second-line-longer-than-first-line () + (let ((expected '("TT" + "hh" + "ee" + " " + "fs" + "ie" + "rc" + "so" + "tn" + " d" + "l " + "il" + "ni" + "en" + ".e" + " ."))) + (should (equal (transpose '("The first line." + "The second line.")) expected)))) + + +(ert-deftest mixed-line-length () + (let ((expected '("TAAA" + "h " + "elll" + " ooi" + "lnnn" + "ogge" + "n e." + "glr" + "ei " + "snl" + "tei" + " .n" + "l e" + "i ." + "n" + "e" + "."))) + (should (equal (transpose '("The longest line." + "A long line." + "A longer line." + "A line.")) expected)))) + + +(ert-deftest square () + (let ((expected '("HEART" + "EMBER" + "ABUSE" + "RESIN" + "TREND"))) + (should (equal (transpose '("HEART" + "EMBER" + "ABUSE" + "RESIN" + "TREND")) expected)))) + + +(ert-deftest rectangle () + (let ((expected '("FOBS" + "RULE" + "ATOP" + "CLOT" + "TIME" + "UNIT" + "RENT" + "EDGE"))) + (should (equal (transpose '("FRACTURE" + "OUTLINED" + "BLOOMING" + "SEPTETTE")) expected)))) + + +(ert-deftest triangle () + (let ((expected '("TEASER" + " EASER" + " ASER" + " SER" + " ER" + " R"))) + (should (equal (transpose '("T" + "EE" + "AAA" + "SSSS" + "EEEEE" + "RRRRRR")) expected)))) + + +(ert-deftest jagged-triangle () + (let ((expected '("123456" + "1 3456" + " 3456" + " 3 56" + " 56" + " 5"))) + (should (equal (transpose '("11" + "2" + "3333" + "444" + "555555" + "66666")) expected)))) + + +(provide 'transpose-test) +;;; transpose-test.el ends here diff --git a/exercises/practice/transpose/transpose.el b/exercises/practice/transpose/transpose.el new file mode 100644 index 00000000..2ec344b5 --- /dev/null +++ b/exercises/practice/transpose/transpose.el @@ -0,0 +1,14 @@ +;;; transpose.el --- Transpose (exercism) -*- lexical-binding: t; -*- + +;;; Commentary: + +;;; Code: + + +(defun transpose (lines) + (error "Delete this S-Expression and write your own implementation")) + + +(provide 'transpose) +;;; transpose.el ends here +