Skip to content

Commit

Permalink
Add pythagorean-triplet exercise (#143)
Browse files Browse the repository at this point in the history
* Add pythagorean-triplet exercise
* Return Set Triplet rather than List Triplet to ignore order, as suggested by Isaac
  • Loading branch information
ageron authored Oct 10, 2024
1 parent 29bd7c6 commit 4c414a8
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,14 @@
"prerequisites": [],
"difficulty": 3
},
{
"slug": "pythagorean-triplet",
"name": "Pythagorean Triplet",
"uuid": "0b50a6d7-79fc-46a2-a62c-9d003c815896",
"practices": [],
"prerequisites": [],
"difficulty": 3
},
{
"slug": "queen-attack",
"name": "Queen Attack",
Expand Down
23 changes: 23 additions & 0 deletions exercises/practice/pythagorean-triplet/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -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}`.
23 changes: 23 additions & 0 deletions exercises/practice/pythagorean-triplet/.meta/Example.roc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module [tripletsWithSum]

Triplet : (U64, U64, U64)

tripletsWithSum : U64 -> Set Triplet
tripletsWithSum = \sum ->
help = \triplets, a, b ->
if a + b + b + 1 > sum then
# c would have to be too small (≤ b)
if 3 * (a + 1) > sum then
# we can't increment a so we're done
triplets
else
help triplets (a + 1) (a + 2) # increment a
else
c = sum - a - b
newTriplets =
if a * a + b * b == c * c then
triplets |> List.append (a, b, c) # success!
else
triplets
help newTriplets a (b + 1) # increment b
help [] 1 2 |> Set.fromList
19 changes: 19 additions & 0 deletions exercises/practice/pythagorean-triplet/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"ageron"
],
"files": {
"solution": [
"PythagoreanTriplet.roc"
],
"test": [
"pythagorean-triplet-test.roc"
],
"example": [
".meta/Example.roc"
]
},
"blurb": "There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the triplet.",
"source": "Problem 9 at Project Euler",
"source_url": "https://projecteuler.net/problem=9"
}
16 changes: 16 additions & 0 deletions exercises/practice/pythagorean-triplet/.meta/template.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{%- import "generator_macros.j2" as macros with context -%}
{{ macros.canonical_ref() }}
{{ macros.header() }}

import {{ exercise | to_pascal }} exposing [{{ cases[0]["property"] | to_camel }}]

{% for case in cases -%}
# {{ case["description"] }}
expect
result = {{ case["property"] | to_camel }} {{ case["input"]["n"] }}
expected = Set.fromList [{%- for triplet in case["expected"] %}
({{ triplet[0] }}, {{ triplet[1] }}, {{ triplet[2] }}),
{%- endfor %}]
result == expected

{% endfor %}
31 changes: 31 additions & 0 deletions exercises/practice/pythagorean-triplet/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -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"
7 changes: 7 additions & 0 deletions exercises/practice/pythagorean-triplet/PythagoreanTriplet.roc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module [tripletsWithSum]

Triplet : (U64, U64, U64)

tripletsWithSum : U64 -> Set Triplet
tripletsWithSum = \sum ->
crash "Please implement the 'tripletsWithSum' function"
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# These tests are auto-generated with test data from:
# https://github.com/exercism/problem-specifications/tree/main/exercises/pythagorean-triplet/canonical-data.json
# File last updated on 2024-10-10
app [main] {
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.15.0/SlwdbJ-3GR7uBWQo6zlmYWNYOxnvo8r6YABXD-45UOw.tar.br",
}

main =
Task.ok {}

import PythagoreanTriplet exposing [tripletsWithSum]

# triplets whose sum is 12
expect
result = tripletsWithSum 12
expected = Set.fromList [
(3, 4, 5),
]
result == expected

# triplets whose sum is 108
expect
result = tripletsWithSum 108
expected = Set.fromList [
(27, 36, 45),
]
result == expected

# triplets whose sum is 1000
expect
result = tripletsWithSum 1000
expected = Set.fromList [
(200, 375, 425),
]
result == expected

# no matching triplets for 1001
expect
result = tripletsWithSum 1001
expected = Set.fromList []
result == expected

# returns all matching triplets
expect
result = tripletsWithSum 90
expected = Set.fromList [
(9, 40, 41),
(15, 36, 39),
]
result == expected

# several matching triplets
expect
result = tripletsWithSum 840
expected = Set.fromList [
(40, 399, 401),
(56, 390, 394),
(105, 360, 375),
(120, 350, 370),
(140, 336, 364),
(168, 315, 357),
(210, 280, 350),
(240, 252, 348),
]
result == expected

# triplets for large number
expect
result = tripletsWithSum 30000
expected = Set.fromList [
(1200, 14375, 14425),
(1875, 14000, 14125),
(5000, 12000, 13000),
(6000, 11250, 12750),
(7500, 10000, 12500),
]
result == expected

0 comments on commit 4c414a8

Please sign in to comment.