Skip to content

Commit a7c63c1

Browse files
committed
..
1 parent aeb2233 commit a7c63c1

File tree

9 files changed

+238
-0
lines changed

9 files changed

+238
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"authors": [
3+
"jiegillet"
4+
],
5+
"files": {
6+
"solution": [
7+
"src/perfect_numbers.gleam"
8+
],
9+
"test": [
10+
"test/perfect_numbers_test.gleam"
11+
],
12+
"example": [
13+
".meta/example.gleam"
14+
],
15+
"invalidator": [
16+
"gleam.toml",
17+
"manifest.toml"
18+
]
19+
},
20+
"blurb": "Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.",
21+
"source": "Taken from Chapter 2 of Functional Thinking by Neal Ford.",
22+
"source_url": "https://www.oreilly.com/library/view/functional-thinking/9781449365509/"
23+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"track":"gleam","exercise":"perfect-numbers","id":"05a9ec6e71ca413fbe81f9eea619d6de","url":"https://exercism.org/tracks/gleam/exercises/perfect-numbers","handle":"nicklatch","is_requester":true,"auto_approve":false}

gleam/perfect-numbers/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.beam
2+
*.ez
3+
build
4+
erl_crash.dump

gleam/perfect-numbers/HELP.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Help
2+
3+
## Running the tests
4+
5+
To run the tests, run the command `gleam test` from within the exercise directory.
6+
7+
## Submitting your solution
8+
9+
You can submit your solution using the `exercism submit src/perfect_numbers.gleam` command.
10+
This command will upload your solution to the Exercism website and print the solution page's URL.
11+
12+
It's possible to submit an incomplete solution which allows you to:
13+
14+
- See how others have completed the exercise
15+
- Request help from a mentor
16+
17+
## Need to get help?
18+
19+
If you'd like help solving the exercise, check the following pages:
20+
21+
- The [Gleam track's documentation](https://exercism.org/docs/tracks/gleam)
22+
- The [Gleam track's programming category on the forum](https://forum.exercism.org/c/programming/gleam)
23+
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
24+
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
25+
26+
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
27+
28+
To get help if you're having trouble, you can use one of the following resources:
29+
30+
- [gleam.run](https://gleam.run/documentation/) is the gleam official documentation.
31+
- [Discord](https://discord.gg/Fm8Pwmy) is the discord channel.
32+
- [StackOverflow](https://stackoverflow.com/questions/tagged/gleam) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.

gleam/perfect-numbers/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Perfect Numbers
2+
3+
Welcome to Perfect Numbers on Exercism's Gleam Track.
4+
If you need help running the tests or submitting your code, check out `HELP.md`.
5+
6+
## Instructions
7+
8+
Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.
9+
10+
The Greek mathematician [Nicomachus][nicomachus] devised a classification scheme for positive integers, identifying each as belonging uniquely to the categories of **perfect**, **abundant**, or **deficient** based on their [aliquot sum][aliquot-sum].
11+
The aliquot sum is defined as the sum of the factors of a number not including the number itself.
12+
For example, the aliquot sum of `15` is `1 + 3 + 5 = 9`.
13+
14+
- **Perfect**: aliquot sum = number
15+
- 6 is a perfect number because (1 + 2 + 3) = 6
16+
- 28 is a perfect number because (1 + 2 + 4 + 7 + 14) = 28
17+
- **Abundant**: aliquot sum > number
18+
- 12 is an abundant number because (1 + 2 + 3 + 4 + 6) = 16
19+
- 24 is an abundant number because (1 + 2 + 3 + 4 + 6 + 8 + 12) = 36
20+
- **Deficient**: aliquot sum < number
21+
- 8 is a deficient number because (1 + 2 + 4) = 7
22+
- Prime numbers are deficient
23+
24+
Implement a way to determine whether a given number is **perfect**.
25+
Depending on your language track, you may also need to implement a way to determine whether a given number is **abundant** or **deficient**.
26+
27+
[nicomachus]: https://en.wikipedia.org/wiki/Nicomachus
28+
[aliquot-sum]: https://en.wikipedia.org/wiki/Aliquot_sum
29+
30+
## Source
31+
32+
### Created by
33+
34+
- @jiegillet
35+
36+
### Based on
37+
38+
Taken from Chapter 2 of Functional Thinking by Neal Ford. - https://www.oreilly.com/library/view/functional-thinking/9781449365509/

gleam/perfect-numbers/gleam.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name = "perfect_numbers"
2+
version = "0.1.0"
3+
4+
[dependencies]
5+
gleam_bitwise = "~> 1.2"
6+
gleam_otp = "~> 0.7 or ~> 1.0"
7+
gleam_stdlib = "~> 0.32 or ~> 1.0"
8+
simplifile = "~> 1.0"
9+
10+
[dev-dependencies]
11+
exercism_test_runner = "~> 1.4"

gleam/perfect-numbers/manifest.toml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# This file was generated by Gleam
2+
# You typically do not need to edit this file
3+
4+
packages = [
5+
{ name = "argv", version = "1.0.1", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "A6E9009E50BBE863EB37D963E4315398D41A3D87D0075480FC244125808F964A" },
6+
{ name = "exercism_test_runner", version = "1.7.0", build_tools = ["gleam"], requirements = ["argv", "gap", "glance", "gleam_community_ansi", "gleam_erlang", "gleam_json", "gleam_stdlib", "simplifile"], otp_app = "exercism_test_runner", source = "hex", outer_checksum = "2FC1BADB19BEC2AE77BFD2D3A606A014C85412A7B874CAFC4BA8CF04B0B257CD" },
7+
{ name = "gap", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_stdlib"], otp_app = "gap", source = "hex", outer_checksum = "2EE1B0A17E85CF73A0C1D29DA315A2699117A8F549C8E8D89FA8261BE41EDEB1" },
8+
{ name = "glance", version = "0.8.2", build_tools = ["gleam"], requirements = ["gleam_stdlib", "glexer"], otp_app = "glance", source = "hex", outer_checksum = "ACF09457E8B564AD7A0D823DAFDD326F58263C01ACB0D432A9BEFDEDD1DA8E73" },
9+
{ name = "gleam_bitwise", version = "1.3.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_bitwise", source = "hex", outer_checksum = "B36E1D3188D7F594C7FD4F43D0D2CE17561DE896202017548578B16FE1FE9EFC" },
10+
{ name = "gleam_community_ansi", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "FE79E08BF97009729259B6357EC058315B6FBB916FAD1C2FF9355115FEB0D3A4" },
11+
{ name = "gleam_community_colour", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "A49A5E3AE8B637A5ACBA80ECB9B1AFE89FD3D5351FF6410A42B84F666D40D7D5" },
12+
{ name = "gleam_erlang", version = "0.24.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "26BDB52E61889F56A291CB34167315780EE4AA20961917314446542C90D1C1A0" },
13+
{ name = "gleam_json", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "8B197DD5D578EA6AC2C0D4BDC634C71A5BCA8E7DB5F47091C263ECB411A60DF3" },
14+
{ name = "gleam_otp", version = "0.10.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "0B04FE915ACECE539B317F9652CAADBBC0F000184D586AAAF2D94C100945D72B" },
15+
{ name = "gleam_stdlib", version = "0.36.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "C0D14D807FEC6F8A08A7C9EF8DFDE6AE5C10E40E21325B2B29365965D82EB3D4" },
16+
{ name = "glexer", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glexer", source = "hex", outer_checksum = "4484942A465482A0A100936E1E5F12314DB4B5AC0D87575A7B9E9062090B96BE" },
17+
{ name = "simplifile", version = "1.5.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "EB9AA8E65E5C1E3E0FDCFC81BC363FD433CB122D7D062750FFDF24DE4AC40116" },
18+
{ name = "thoas", version = "0.4.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "4918D50026C073C4AB1388437132C77A6F6F7C8AC43C60C13758CC0ADCE2134E" },
19+
]
20+
21+
[requirements]
22+
exercism_test_runner = { version = "~> 1.4" }
23+
gleam_bitwise = { version = "~> 1.2" }
24+
gleam_otp = { version = "~> 0.7 or ~> 1.0" }
25+
gleam_stdlib = { version = "~> 0.32 or ~> 1.0" }
26+
simplifile = { version = "~> 1.0" }
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import gleam/list
2+
import gleam/int.{compare, sum}
3+
import gleam/order.{Eq, Gt, Lt}
4+
5+
pub type Classification {
6+
Perfect
7+
Abundant
8+
Deficient
9+
}
10+
11+
pub type Error {
12+
NonPositiveInt
13+
}
14+
15+
pub fn classify(number: Int) -> Result(Classification, Error) {
16+
case number > 0 {
17+
True ->
18+
case compare(alq_sum(number), number) {
19+
Lt -> Ok(Deficient)
20+
Eq -> Ok(Perfect)
21+
Gt -> Ok(Abundant)
22+
}
23+
False -> Error(NonPositiveInt)
24+
}
25+
}
26+
27+
fn alq_sum(number: Int) -> Int {
28+
list.range(1, number / 2)
29+
|> list.filter(fn(num) { num != number && number % num == 0 })
30+
|> sum
31+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import exercism/should
2+
import exercism/test_runner
3+
import perfect_numbers.{Abundant, Deficient, NonPositiveInt, Perfect}
4+
5+
pub fn main() {
6+
test_runner.main()
7+
}
8+
9+
pub fn perfect_numbers_smallest_perfect_number_is_classified_correctly_test() {
10+
perfect_numbers.classify(6)
11+
|> should.equal(Ok(Perfect))
12+
}
13+
14+
pub fn perfect_numbers_medium_perfect_number_is_classified_correctly_test() {
15+
perfect_numbers.classify(28)
16+
|> should.equal(Ok(Perfect))
17+
}
18+
19+
pub fn perfect_numbers_large_perfect_number_is_classified_correctly_test() {
20+
perfect_numbers.classify(33_550_336)
21+
|> should.equal(Ok(Perfect))
22+
}
23+
24+
pub fn abundant_numbers_smallest_abundant_number_is_classified_correctly_test() {
25+
perfect_numbers.classify(12)
26+
|> should.equal(Ok(Abundant))
27+
}
28+
29+
pub fn abundant_numbers_medium_abundant_number_is_classified_correctly_test() {
30+
perfect_numbers.classify(30)
31+
|> should.equal(Ok(Abundant))
32+
}
33+
34+
pub fn abundant_numbers_large_abundant_number_is_classified_correctly_test() {
35+
perfect_numbers.classify(33_550_335)
36+
|> should.equal(Ok(Abundant))
37+
}
38+
39+
pub fn deficient_numbers_smallest_prime_deficient_number_is_classified_correctly_test() {
40+
perfect_numbers.classify(2)
41+
|> should.equal(Ok(Deficient))
42+
}
43+
44+
pub fn deficient_numbers_smallest_non_prime_deficient_number_is_classified_correctly_test() {
45+
perfect_numbers.classify(4)
46+
|> should.equal(Ok(Deficient))
47+
}
48+
49+
pub fn deficient_numbers_medium_deficient_number_is_classified_correctly_test() {
50+
perfect_numbers.classify(32)
51+
|> should.equal(Ok(Deficient))
52+
}
53+
54+
pub fn deficient_numbers_large_deficient_number_is_classified_correctly_test() {
55+
perfect_numbers.classify(33_550_337)
56+
|> should.equal(Ok(Deficient))
57+
}
58+
59+
pub fn deficient_numbers_edge_case_no_factors_other_than_itself_is_classified_correctly_test() {
60+
perfect_numbers.classify(1)
61+
|> should.equal(Ok(Deficient))
62+
}
63+
64+
pub fn invalid_inputs_zero_is_rejected_as_it_is_not_a_positive_integer_test() {
65+
perfect_numbers.classify(0)
66+
|> should.equal(Error(NonPositiveInt))
67+
}
68+
69+
pub fn invalid_inputs_negative_integer_is_rejected_as_it_is_not_a_positive_integer_test() {
70+
perfect_numbers.classify(-1)
71+
|> should.equal(Error(NonPositiveInt))
72+
}

0 commit comments

Comments
 (0)