diff --git a/config.json b/config.json
index 6f7d8b69..3e363a3b 100644
--- a/config.json
+++ b/config.json
@@ -571,6 +571,15 @@
"prerequisites": [],
"difficulty": 1,
"topics": []
+ },
+ {
+ "slug": "pythagorean-triplet",
+ "name": "Pythagorean Triplet",
+ "uuid": "7e517674-28b6-4b47-97ee-cf4517402430",
+ "practices": [],
+ "prerequisites": [],
+ "difficulty": 1,
+ "topics": []
}
]
},
diff --git a/exercises/practice/pythagorean-triplet/.docs/instructions.md b/exercises/practice/pythagorean-triplet/.docs/instructions.md
new file mode 100644
index 00000000..1c1a8aea
--- /dev/null
+++ b/exercises/practice/pythagorean-triplet/.docs/instructions.md
@@ -0,0 +1,23 @@
+# Instructions
+
+A Pythagorean triplet is a set of three natural numbers, {a, b, c}, for which,
+
+```text
+a² + b² = c²
+```
+
+and such that,
+
+```text
+a < b < c
+```
+
+For example,
+
+```text
+3² + 4² = 5².
+```
+
+Given an input integer N, find all Pythagorean triplets for which `a + b + c = N`.
+
+For example, with N = 1000, there is exactly one Pythagorean triplet for which `a + b + c = 1000`: `{200, 375, 425}`.
diff --git a/exercises/practice/pythagorean-triplet/.meta/config.json b/exercises/practice/pythagorean-triplet/.meta/config.json
new file mode 100644
index 00000000..000d92d6
--- /dev/null
+++ b/exercises/practice/pythagorean-triplet/.meta/config.json
@@ -0,0 +1,19 @@
+{
+ "authors": [
+ "habere-et-dispertire"
+ ],
+ "files": {
+ "solution": [
+ "PythagoreanTriplet.rakumod"
+ ],
+ "test": [
+ "pythagorean-triplet.rakutest"
+ ],
+ "example": [
+ ".meta/solutions/PythagoreanTriplet.rakumod"
+ ]
+ },
+ "blurb": "There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product a * b * c.",
+ "source": "Problem 9 at Project Euler",
+ "source_url": "https://projecteuler.net/problem=9"
+}
diff --git a/exercises/practice/pythagorean-triplet/.meta/solutions/PythagoreanTriplet.rakumod b/exercises/practice/pythagorean-triplet/.meta/solutions/PythagoreanTriplet.rakumod
new file mode 100644
index 00000000..e6b539b5
--- /dev/null
+++ b/exercises/practice/pythagorean-triplet/.meta/solutions/PythagoreanTriplet.rakumod
@@ -0,0 +1,15 @@
+unit module PythagoreanTriplet;
+
+sub triplets-sum ($sum) is export {
+ gather for 1 .. $sum
+ -> $a {
+ given 2×$a² + $sum² - 2×$sum×$a, 2×( $sum - $a )
+ -> ( $numerator, $denominator ) {
+ if $numerator %% $denominator {
+ my $c = $numerator / $denominator;
+ my $b = $sum - $a - $c;
+ take [ $a, $b, $c ] if $b > $a;
+ }
+ }
+ }
+}
diff --git a/exercises/practice/pythagorean-triplet/.meta/solutions/pythagorean-triplet.rakutest b/exercises/practice/pythagorean-triplet/.meta/solutions/pythagorean-triplet.rakutest
new file mode 120000
index 00000000..64ffc669
--- /dev/null
+++ b/exercises/practice/pythagorean-triplet/.meta/solutions/pythagorean-triplet.rakutest
@@ -0,0 +1 @@
+../../pythagorean-triplet.rakutest
\ No newline at end of file
diff --git a/exercises/practice/pythagorean-triplet/.meta/template-data.yaml b/exercises/practice/pythagorean-triplet/.meta/template-data.yaml
new file mode 100644
index 00000000..ae12e382
--- /dev/null
+++ b/exercises/practice/pythagorean-triplet/.meta/template-data.yaml
@@ -0,0 +1,31 @@
+properties:
+ tripletsWithSum:
+ test: |-
+ sprintf(q:to/END/, %case.raku, %case.map(*.List).List.raku, %case.raku);
+ cmp-ok(
+ triplets-sum(%s),
+ "~~",
+ %s,
+ %s,
+ );
+ END
+
+unit: module
+example: |-
+ sub triplets-sum ($sum) is export {
+ gather for 1 .. $sum
+ -> $a {
+ given 2×$a² + $sum² - 2×$sum×$a, 2×( $sum - $a )
+ -> ( $numerator, $denominator ) {
+ if $numerator %% $denominator {
+ my $c = $numerator / $denominator;
+ my $b = $sum - $a - $c;
+ take [ $a, $b, $c ] if $b > $a;
+ }
+ }
+ }
+ }
+
+stub: |-
+ sub triplets-sum ($sum) is export {
+ }
diff --git a/exercises/practice/pythagorean-triplet/.meta/tests.toml b/exercises/practice/pythagorean-triplet/.meta/tests.toml
new file mode 100644
index 00000000..719620a9
--- /dev/null
+++ b/exercises/practice/pythagorean-triplet/.meta/tests.toml
@@ -0,0 +1,31 @@
+# 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.
+
+[a19de65d-35b8-4480-b1af-371d9541e706]
+description = "triplets whose sum is 12"
+
+[48b21332-0a3d-43b2-9a52-90b2a6e5c9f5]
+description = "triplets whose sum is 108"
+
+[dffc1266-418e-4daa-81af-54c3e95c3bb5]
+description = "triplets whose sum is 1000"
+
+[5f86a2d4-6383-4cce-93a5-e4489e79b186]
+description = "no matching triplets for 1001"
+
+[bf17ba80-1596-409a-bb13-343bdb3b2904]
+description = "returns all matching triplets"
+
+[9d8fb5d5-6c6f-42df-9f95-d3165963ac57]
+description = "several matching triplets"
+
+[f5be5734-8aa0-4bd1-99a2-02adcc4402b4]
+description = "triplets for large number"
diff --git a/exercises/practice/pythagorean-triplet/PythagoreanTriplet.rakumod b/exercises/practice/pythagorean-triplet/PythagoreanTriplet.rakumod
new file mode 100644
index 00000000..802c2779
--- /dev/null
+++ b/exercises/practice/pythagorean-triplet/PythagoreanTriplet.rakumod
@@ -0,0 +1,4 @@
+unit module PythagoreanTriplet;
+
+sub triplets-sum ($sum) is export {
+}
diff --git a/exercises/practice/pythagorean-triplet/pythagorean-triplet.rakutest b/exercises/practice/pythagorean-triplet/pythagorean-triplet.rakutest
new file mode 100755
index 00000000..19af8951
--- /dev/null
+++ b/exercises/practice/pythagorean-triplet/pythagorean-triplet.rakutest
@@ -0,0 +1,55 @@
+#!/usr/bin/env raku
+use Test;
+use lib $?FILE.IO.dirname;
+use PythagoreanTriplet;
+
+cmp-ok( # begin: a19de65d-35b8-4480-b1af-371d9541e706
+ triplets-sum(12),
+ "~~",
+ ((3, 4, 5),),
+ "triplets whose sum is 12",
+); # end: a19de65d-35b8-4480-b1af-371d9541e706
+
+cmp-ok( # begin: 48b21332-0a3d-43b2-9a52-90b2a6e5c9f5
+ triplets-sum(108),
+ "~~",
+ ((27, 36, 45),),
+ "triplets whose sum is 108",
+); # end: 48b21332-0a3d-43b2-9a52-90b2a6e5c9f5
+
+cmp-ok( # begin: dffc1266-418e-4daa-81af-54c3e95c3bb5
+ triplets-sum(1000),
+ "~~",
+ ((200, 375, 425),),
+ "triplets whose sum is 1000",
+); # end: dffc1266-418e-4daa-81af-54c3e95c3bb5
+
+cmp-ok( # begin: 5f86a2d4-6383-4cce-93a5-e4489e79b186
+ triplets-sum(1001),
+ "~~",
+ (),
+ "no matching triplets for 1001",
+); # end: 5f86a2d4-6383-4cce-93a5-e4489e79b186
+
+cmp-ok( # begin: bf17ba80-1596-409a-bb13-343bdb3b2904
+ triplets-sum(90),
+ "~~",
+ ((9, 40, 41), (15, 36, 39)),
+ "returns all matching triplets",
+); # end: bf17ba80-1596-409a-bb13-343bdb3b2904
+
+cmp-ok( # begin: 9d8fb5d5-6c6f-42df-9f95-d3165963ac57
+ triplets-sum(840),
+ "~~",
+ ((40, 399, 401), (56, 390, 394), (105, 360, 375), (120, 350, 370), (140, 336, 364), (168, 315, 357), (210, 280, 350), (240, 252, 348)),
+ "several matching triplets",
+); # end: 9d8fb5d5-6c6f-42df-9f95-d3165963ac57
+
+cmp-ok( # begin: f5be5734-8aa0-4bd1-99a2-02adcc4402b4
+ triplets-sum(30000),
+ "~~",
+ ((1200, 14375, 14425), (1875, 14000, 14125), (5000, 12000, 13000), (6000, 11250, 12750), (7500, 10000, 12500)),
+ "triplets for large number",
+); # end: f5be5734-8aa0-4bd1-99a2-02adcc4402b4
+
+done-testing;