diff --git a/config.json b/config.json index a88f0606..120c05c0 100644 --- a/config.json +++ b/config.json @@ -660,6 +660,14 @@ "prerequisites": [], "difficulty": 3 }, + { + "slug": "pythagorean-triplet", + "name": "Pythagorean Triplet", + "uuid": "7d3309b4-8efb-4357-8893-c654ccee7e79", + "practices": [], + "prerequisites": [], + "difficulty": 3 + }, { "slug": "ocr-numbers", "name": "OCR Numbers", 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/PythagoreanTriplet.example.ps1 b/exercises/practice/pythagorean-triplet/.meta/PythagoreanTriplet.example.ps1 new file mode 100644 index 00000000..76813bb0 --- /dev/null +++ b/exercises/practice/pythagorean-triplet/.meta/PythagoreanTriplet.example.ps1 @@ -0,0 +1,56 @@ +Function Get-PythagoreanTriplet() { + <# + .SYNOPSIS + Given input integer N, find all Pythagorean triplets for which 'a + b + c = N'. + + .DESCRIPTION + Given an integer, find all the possible Pythagorean triplets whose sum is equal to that integer. + Return the array of Pythagorean triplets in sorted ascending order. + + A Pythagorean triplet is a set of three natural numbers, {a, b, c}, for which: + a² + b² = c² + a < b < c + + .PARAMETER Number + The sum of a Pythagorean triplet + + .EXAMPLE + Get-PythagoreanTriplet -Sum 12 + Return: @( ,@(3, 4, 5)) + #> + [CmdletBinding()] + Param( + [int]$Sum + ) + # Logic : If a is at maximum, it still less than b, and b less than c. So c at mimimum but be around N/3 + # For a + b + c = N and a² + b² = c² to be valid, c at maximum cant be larger than N/2 + $rangeOfc = [math]::Floor($Sum / 3)..[math]::Floor($Sum / 2) + $triplets = @() + + foreach ($c in $rangeOfc) { + $abSum = $Sum - $c + $abProd = [math]::Floor(($abSum * $abSum - $c * $c) / 2) + if ($abProd -gt 0) { + $a, $b = Get-AB $abSum $abProd + $validTriple = ($a * $a + $b * $b) -eq ($c * $c) + if ($a -and $b -and $validTriple) { + $triplets += ,@($a, $b, $c) + } + } + } + $triplets | Sort-Object { $_[0] } +} + +function Get-AB($abSum, $abProd) { + <# + .DESCRIPTION + Helper function using the identity (x+y)2−4xy=(x−y)2 aka ab_sum*2−4*ab_prod = (x−y)^2 + to find a and b + #> + $abDifSqr = [math]::Pow($abSum, 2) - 4 * $abProd + if ($abDifSqr -gt 0) { + $abDif = [math]::Floor([math]::Sqrt($abDifSqr)) + $b, $a = [math]::Floor(($abSum + $abDif) / 2) , [math]::Floor(($abSum - $abDif) / 2) + $a, $b + } +} \ No newline at end of file diff --git a/exercises/practice/pythagorean-triplet/.meta/config.json b/exercises/practice/pythagorean-triplet/.meta/config.json new file mode 100644 index 00000000..c6e754bb --- /dev/null +++ b/exercises/practice/pythagorean-triplet/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "glaxxie" + ], + "files": { + "solution": [ + "PythagoreanTriplet.ps1" + ], + "test": [ + "PythagoreanTriplet.tests.ps1" + ], + "example": [ + ".meta/PythagoreanTriplet.example.ps1" + ] + }, + "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/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.ps1 b/exercises/practice/pythagorean-triplet/PythagoreanTriplet.ps1 new file mode 100644 index 00000000..7eb609d4 --- /dev/null +++ b/exercises/practice/pythagorean-triplet/PythagoreanTriplet.ps1 @@ -0,0 +1,26 @@ +Function Get-PythagoreanTriplet() { + <# + .SYNOPSIS + Given input integer N, find all Pythagorean triplets for which 'a + b + c = N'. + + .DESCRIPTION + Given an integer, find all the possible Pythagorean triplets whose sum is equal to that integer. + Return the array of Pythagorean triplets in sorted ascending order. + + A Pythagorean triplet is a set of three natural numbers, {a, b, c}, for which: + a² + b² = c² + a < b < c + + .PARAMETER Number + The sum of a Pythagorean triplet + + .EXAMPLE + Get-PythagoreanTriplet -Sum 12 + Return: @( ,@(3, 4, 5)) + #> + [CmdletBinding()] + Param( + [int]$Sum + ) + Throw "Please implement this function" +} \ No newline at end of file diff --git a/exercises/practice/pythagorean-triplet/PythagoreanTriplet.tests.ps1 b/exercises/practice/pythagorean-triplet/PythagoreanTriplet.tests.ps1 new file mode 100644 index 00000000..4727b6ba --- /dev/null +++ b/exercises/practice/pythagorean-triplet/PythagoreanTriplet.tests.ps1 @@ -0,0 +1,68 @@ +BeforeAll { + . "./PythagoreanTriplet.ps1" +} + +Describe "PythagoreanTriplet test cases" { + It "triplets whose sum is 12" { + $got = Get-PythagoreanTriplet -Sum 12 + $want = @( ,@(3, 4, 5)) + + ,$got | Should -BeExactly $want + } + + It "triplets whose sum is 108" { + $got = Get-PythagoreanTriplet -Sum 108 + $want = @( ,@(27, 36, 45)) + + ,$got | Should -BeExactly $want + } + + It "triplets whose sum is 1000" { + $got = Get-PythagoreanTriplet -Sum 1000 + $want = @( ,@(200, 375, 425)) + + ,$got | Should -BeExactly $want + } + + It "no matching triplets for 1001" { + $got = Get-PythagoreanTriplet -Sum 1001 + + $got | Should -BeNullOrEmpty + } + + It "returns all matching triplets" { + $got = Get-PythagoreanTriplet -Sum 90 + $want = @( @(9, 40, 41), @(15, 36, 39)) + + $got | Should -BeExactly $want + } + + It "several matching triplets" { + $got = Get-PythagoreanTriplet -Sum 840 + $want = @( + @(40, 399, 401), + @(56, 390, 394), + @(105, 360, 375), + @(120, 350, 370), + @(140, 336, 364), + @(168, 315, 357), + @(210, 280, 350), + @(240, 252, 348) + ) + + $got | Should -BeExactly $want + } + + It "triplets for large number" { + $got = Get-PythagoreanTriplet -Sum 30000 + $want = @( + @(1200, 14375, 14425), + @(1875, 14000, 14125), + @(5000, 12000, 13000), + @(6000, 11250, 12750), + @(7500, 10000, 12500) + ) + + $got | Should -BeExactly $want + } +}