diff --git a/config.json b/config.json
index c4fb9de2..28f15107 100644
--- a/config.json
+++ b/config.json
@@ -589,6 +589,15 @@
"prerequisites": [],
"difficulty": 1,
"topics": []
+ },
+ {
+ "slug": "matrix",
+ "name": "Matrix",
+ "uuid": "50ba9ec3-93a7-4963-868e-0d08f7c01acd",
+ "practices": [],
+ "prerequisites": [],
+ "difficulty": 1,
+ "topics": []
}
]
},
diff --git a/exercises/practice/matrix/.docs/instructions.md b/exercises/practice/matrix/.docs/instructions.md
new file mode 100644
index 00000000..dadea8ac
--- /dev/null
+++ b/exercises/practice/matrix/.docs/instructions.md
@@ -0,0 +1,38 @@
+# Instructions
+
+Given a string representing a matrix of numbers, return the rows and columns of that matrix.
+
+So given a string with embedded newlines like:
+
+```text
+9 8 7
+5 3 2
+6 6 7
+```
+
+representing this matrix:
+
+```text
+ 1 2 3
+ |---------
+1 | 9 8 7
+2 | 5 3 2
+3 | 6 6 7
+```
+
+your code should be able to spit out:
+
+- A list of the rows, reading each row left-to-right while moving top-to-bottom across the rows,
+- A list of the columns, reading each column top-to-bottom while moving from left-to-right.
+
+The rows for our example matrix:
+
+- 9, 8, 7
+- 5, 3, 2
+- 6, 6, 7
+
+And its columns:
+
+- 9, 5, 6
+- 8, 3, 6
+- 7, 2, 7
diff --git a/exercises/practice/matrix/.meta/config.json b/exercises/practice/matrix/.meta/config.json
new file mode 100644
index 00000000..d9e2d3bf
--- /dev/null
+++ b/exercises/practice/matrix/.meta/config.json
@@ -0,0 +1,19 @@
+{
+ "authors": [
+ "habere-et-dispertire"
+ ],
+ "files": {
+ "solution": [
+ "Matrix.rakumod"
+ ],
+ "test": [
+ "matrix.rakutest"
+ ],
+ "example": [
+ ".meta/solutions/Matrix.rakumod"
+ ]
+ },
+ "blurb": "Given a string representing a matrix of numbers, return the rows and columns of that matrix.",
+ "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.",
+ "source_url": "https://turing.edu"
+}
diff --git a/exercises/practice/matrix/.meta/solutions/Matrix.rakumod b/exercises/practice/matrix/.meta/solutions/Matrix.rakumod
new file mode 100644
index 00000000..7605f63a
--- /dev/null
+++ b/exercises/practice/matrix/.meta/solutions/Matrix.rakumod
@@ -0,0 +1,9 @@
+unit module Matrix;
+
+sub extract-row(:$string, :$index) is export {
+ $string.lines[$index.pred].words
+}
+
+sub extract-column(:$string, :$index) is export {
+ gather for $string.lines { take .words[$index.pred] }
+}
diff --git a/exercises/practice/matrix/.meta/solutions/matrix.rakutest b/exercises/practice/matrix/.meta/solutions/matrix.rakutest
new file mode 120000
index 00000000..bf3e3f25
--- /dev/null
+++ b/exercises/practice/matrix/.meta/solutions/matrix.rakutest
@@ -0,0 +1 @@
+../../matrix.rakutest
\ No newline at end of file
diff --git a/exercises/practice/matrix/.meta/template-data.yaml b/exercises/practice/matrix/.meta/template-data.yaml
new file mode 100644
index 00000000..469f7f0e
--- /dev/null
+++ b/exercises/practice/matrix/.meta/template-data.yaml
@@ -0,0 +1,38 @@
+properties:
+ row:
+ test: |-
+ sprintf(q:to/END/, %case.raku, %case, %case.List<>.raku, %case.raku);
+ cmp-ok(
+ extract-row( :string(%s), :index(%s) ),
+ "~~",
+ %s,
+ %s,
+ );
+ END
+ column:
+ test: |-
+ sprintf(q:to/END/, %case.raku, %case, %case.List<>.raku, %case.raku);
+ cmp-ok(
+ extract-column( :string(%s), :index(%s) ),
+ "~~",
+ %s,
+ %s,
+ );
+ END
+
+unit: module
+example: |-
+ sub extract-row(:$string, :$index) is export {
+ $string.lines[$index.pred].words
+ }
+
+ sub extract-column(:$string, :$index) is export {
+ gather for $string.lines { take .words[$index.pred] }
+ }
+
+stub: |-
+ sub extract-row(:$string, :$index) is export {
+ }
+
+ sub extract-column(:$string, :$index) is export {
+ }
diff --git a/exercises/practice/matrix/.meta/tests.toml b/exercises/practice/matrix/.meta/tests.toml
new file mode 100644
index 00000000..90b509c4
--- /dev/null
+++ b/exercises/practice/matrix/.meta/tests.toml
@@ -0,0 +1,34 @@
+# 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.
+
+[ca733dab-9d85-4065-9ef6-a880a951dafd]
+description = "extract row from one number matrix"
+
+[5c93ec93-80e1-4268-9fc2-63bc7d23385c]
+description = "can extract row"
+
+[2f1aad89-ad0f-4bd2-9919-99a8bff0305a]
+description = "extract row where numbers have different widths"
+
+[68f7f6ba-57e2-4e87-82d0-ad09889b5204]
+description = "can extract row from non-square matrix with no corresponding column"
+
+[e8c74391-c93b-4aed-8bfe-f3c9beb89ebb]
+description = "extract column from one number matrix"
+
+[7136bdbd-b3dc-48c4-a10c-8230976d3727]
+description = "can extract column"
+
+[ad64f8d7-bba6-4182-8adf-0c14de3d0eca]
+description = "can extract column from non-square matrix with no corresponding row"
+
+[9eddfa5c-8474-440e-ae0a-f018c2a0dd89]
+description = "extract column where numbers have different widths"
diff --git a/exercises/practice/matrix/Matrix.rakumod b/exercises/practice/matrix/Matrix.rakumod
new file mode 100644
index 00000000..187372ff
--- /dev/null
+++ b/exercises/practice/matrix/Matrix.rakumod
@@ -0,0 +1,7 @@
+unit module Matrix;
+
+sub extract-row(:$string, :$index) is export {
+}
+
+sub extract-column(:$string, :$index) is export {
+}
diff --git a/exercises/practice/matrix/matrix.rakutest b/exercises/practice/matrix/matrix.rakutest
new file mode 100755
index 00000000..f5f71ca0
--- /dev/null
+++ b/exercises/practice/matrix/matrix.rakutest
@@ -0,0 +1,62 @@
+#!/usr/bin/env raku
+use Test;
+use lib $?FILE.IO.dirname;
+use Matrix;
+
+cmp-ok( # begin: ca733dab-9d85-4065-9ef6-a880a951dafd
+ extract-row( :string("1"), :index(1) ),
+ "~~",
+ (1,),
+ "extract row from one number matrix",
+); # end: ca733dab-9d85-4065-9ef6-a880a951dafd
+
+cmp-ok( # begin: 5c93ec93-80e1-4268-9fc2-63bc7d23385c
+ extract-row( :string("1 2\n3 4"), :index(2) ),
+ "~~",
+ (3, 4),
+ "can extract row",
+); # end: 5c93ec93-80e1-4268-9fc2-63bc7d23385c
+
+cmp-ok( # begin: 2f1aad89-ad0f-4bd2-9919-99a8bff0305a
+ extract-row( :string("1 2\n10 20"), :index(2) ),
+ "~~",
+ (10, 20),
+ "extract row where numbers have different widths",
+); # end: 2f1aad89-ad0f-4bd2-9919-99a8bff0305a
+
+cmp-ok( # begin: 68f7f6ba-57e2-4e87-82d0-ad09889b5204
+ extract-row( :string("1 2 3\n4 5 6\n7 8 9\n8 7 6"), :index(4) ),
+ "~~",
+ (8, 7, 6),
+ "can extract row from non-square matrix with no corresponding column",
+); # end: 68f7f6ba-57e2-4e87-82d0-ad09889b5204
+
+cmp-ok( # begin: e8c74391-c93b-4aed-8bfe-f3c9beb89ebb
+ extract-column( :string("1"), :index(1) ),
+ "~~",
+ (1,),
+ "extract column from one number matrix",
+); # end: e8c74391-c93b-4aed-8bfe-f3c9beb89ebb
+
+cmp-ok( # begin: 7136bdbd-b3dc-48c4-a10c-8230976d3727
+ extract-column( :string("1 2 3\n4 5 6\n7 8 9"), :index(3) ),
+ "~~",
+ (3, 6, 9),
+ "can extract column",
+); # end: 7136bdbd-b3dc-48c4-a10c-8230976d3727
+
+cmp-ok( # begin: ad64f8d7-bba6-4182-8adf-0c14de3d0eca
+ extract-column( :string("1 2 3 4\n5 6 7 8\n9 8 7 6"), :index(4) ),
+ "~~",
+ (4, 8, 6),
+ "can extract column from non-square matrix with no corresponding row",
+); # end: ad64f8d7-bba6-4182-8adf-0c14de3d0eca
+
+cmp-ok( # begin: 9eddfa5c-8474-440e-ae0a-f018c2a0dd89
+ extract-column( :string("89 1903 3\n18 3 1\n9 4 800"), :index(2) ),
+ "~~",
+ (1903, 3, 4),
+ "extract column where numbers have different widths",
+); # end: 9eddfa5c-8474-440e-ae0a-f018c2a0dd89
+
+done-testing;