Skip to content

Commit cb5b74e

Browse files
authored
Add perfect-numbers (#590)
* Add `perfect-numbers` * Remove empty classificaton enum
1 parent 07a8c93 commit cb5b74e

File tree

8 files changed

+232
-0
lines changed

8 files changed

+232
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,14 @@
350350
"math"
351351
]
352352
},
353+
{
354+
"slug": "perfect-numbers",
355+
"name": "Perfect Numbers",
356+
"uuid": "696b5088-ec86-4d60-8ac1-2cc1d89dee52",
357+
"practices": [],
358+
"prerequisites": [],
359+
"difficulty": 2
360+
},
353361
{
354362
"slug": "isbn-verifier",
355363
"name": "ISBN Verifier",
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Instructions
2+
3+
Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.
4+
5+
The Greek mathematician [Nicomachus][nicomachus] devised a classification scheme for positive integers, identifying each as belonging uniquely to the categories of [perfect](#perfect), [abundant](#abundant), or [deficient](#deficient) based on their [aliquot sum][aliquot-sum].
6+
The _aliquot sum_ is defined as the sum of the factors of a number not including the number itself.
7+
For example, the aliquot sum of `15` is `1 + 3 + 5 = 9`.
8+
9+
## Perfect
10+
11+
A number is perfect when it equals its aliquot sum.
12+
For example:
13+
14+
- `6` is a perfect number because `1 + 2 + 3 = 6`
15+
- `28` is a perfect number because `1 + 2 + 4 + 7 + 14 = 28`
16+
17+
## Abundant
18+
19+
A number is abundant when it is less than its aliquot sum.
20+
For example:
21+
22+
- `12` is an abundant number because `1 + 2 + 3 + 4 + 6 = 16`
23+
- `24` is an abundant number because `1 + 2 + 3 + 4 + 6 + 8 + 12 = 36`
24+
25+
## Deficient
26+
27+
A number is deficient when it is greater than its aliquot sum.
28+
For example:
29+
30+
- `8` is a deficient number because `1 + 2 + 4 = 7`
31+
- Prime numbers are deficient
32+
33+
## Task
34+
35+
Implement a way to determine whether a given number is [perfect](#perfect).
36+
Depending on your language track, you may also need to implement a way to determine whether a given number is [abundant](#abundant) or [deficient](#deficient).
37+
38+
[nicomachus]: https://en.wikipedia.org/wiki/Nicomachus
39+
[aliquot-sum]: https://en.wikipedia.org/wiki/Aliquot_sum
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"BNAndras"
4+
],
5+
"files": {
6+
"solution": [
7+
"lib/perfect_numbers.dart"
8+
],
9+
"test": [
10+
"test/perfect_numbers_test.dart"
11+
],
12+
"example": [
13+
".meta/lib/example.dart"
14+
]
15+
},
16+
"blurb": "Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.",
17+
"source": "Taken from Chapter 2 of Functional Thinking by Neal Ford.",
18+
"source_url": "https://www.oreilly.com/library/view/functional-thinking/9781449365509/"
19+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
enum Classification {
2+
perfect,
3+
abundant,
4+
deficient,
5+
}
6+
7+
class PerfectNumbers {
8+
Classification classify(int number) {
9+
if (number <= 0) {
10+
throw ArgumentError('Number must be greater than 0');
11+
}
12+
13+
var sum = 0;
14+
for (var i = 1; i < number; i++) {
15+
if (number % i == 0) {
16+
sum += i;
17+
}
18+
}
19+
20+
if (sum == number) {
21+
return Classification.perfect;
22+
} else if (sum > number) {
23+
return Classification.abundant;
24+
} else {
25+
return Classification.deficient;
26+
}
27+
}
28+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[163e8e86-7bfd-4ee2-bd68-d083dc3381a3]
13+
description = "Perfect numbers -> Smallest perfect number is classified correctly"
14+
15+
[169a7854-0431-4ae0-9815-c3b6d967436d]
16+
description = "Perfect numbers -> Medium perfect number is classified correctly"
17+
18+
[ee3627c4-7b36-4245-ba7c-8727d585f402]
19+
description = "Perfect numbers -> Large perfect number is classified correctly"
20+
21+
[80ef7cf8-9ea8-49b9-8b2d-d9cb3db3ed7e]
22+
description = "Abundant numbers -> Smallest abundant number is classified correctly"
23+
24+
[3e300e0d-1a12-4f11-8c48-d1027165ab60]
25+
description = "Abundant numbers -> Medium abundant number is classified correctly"
26+
27+
[ec7792e6-8786-449c-b005-ce6dd89a772b]
28+
description = "Abundant numbers -> Large abundant number is classified correctly"
29+
30+
[e610fdc7-2b6e-43c3-a51c-b70fb37413ba]
31+
description = "Deficient numbers -> Smallest prime deficient number is classified correctly"
32+
33+
[0beb7f66-753a-443f-8075-ad7fbd9018f3]
34+
description = "Deficient numbers -> Smallest non-prime deficient number is classified correctly"
35+
36+
[1c802e45-b4c6-4962-93d7-1cad245821ef]
37+
description = "Deficient numbers -> Medium deficient number is classified correctly"
38+
39+
[47dd569f-9e5a-4a11-9a47-a4e91c8c28aa]
40+
description = "Deficient numbers -> Large deficient number is classified correctly"
41+
42+
[a696dec8-6147-4d68-afad-d38de5476a56]
43+
description = "Deficient numbers -> Edge case (no factors other than itself) is classified correctly"
44+
45+
[72445cee-660c-4d75-8506-6c40089dc302]
46+
description = "Invalid inputs -> Zero is rejected (as it is not a positive integer)"
47+
48+
[2d72ce2c-6802-49ac-8ece-c790ba3dae13]
49+
description = "Invalid inputs -> Negative integer is rejected (as it is not a positive integer)"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// define the Classification enum
2+
3+
class PerfectNumbers {
4+
// Put your code here
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
name: 'perfect_numbers'
2+
environment:
3+
sdk: '>=3.2.0 <4.0.0'
4+
dev_dependencies:
5+
test: '<2.0.0'
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import 'package:perfect_numbers/perfect_numbers.dart';
2+
import 'package:test/test.dart';
3+
4+
void main() {
5+
final perfectNumbers = PerfectNumbers();
6+
7+
group('PerfectNumbers', () {
8+
group('Perfect numbers', () {
9+
test('Smallest perfect number is classified correctly', () {
10+
final result = perfectNumbers.classify(6);
11+
expect(result, equals(Classification.perfect));
12+
}, skip: false);
13+
14+
test('Medium perfect number is classified correctly', () {
15+
final result = perfectNumbers.classify(28);
16+
expect(result, equals(Classification.perfect));
17+
}, skip: true);
18+
19+
test('Large perfect number is classified correctly', () {
20+
final result = perfectNumbers.classify(33550336);
21+
expect(result, equals(Classification.perfect));
22+
}, skip: true);
23+
});
24+
25+
group('Abundant numbers', () {
26+
test('Smallest abundant number is classified correctly', () {
27+
final result = perfectNumbers.classify(12);
28+
expect(result, equals(Classification.abundant));
29+
}, skip: true);
30+
31+
test('Medium abundant number is classified correctly', () {
32+
final result = perfectNumbers.classify(30);
33+
expect(result, equals(Classification.abundant));
34+
}, skip: true);
35+
36+
test('Large abundant number is classified correctly', () {
37+
final result = perfectNumbers.classify(33550335);
38+
expect(result, equals(Classification.abundant));
39+
}, skip: true);
40+
});
41+
42+
group('Deficient numbers', () {
43+
test('Smallest prime deficient number is classified correctly', () {
44+
final result = perfectNumbers.classify(2);
45+
expect(result, equals(Classification.deficient));
46+
}, skip: true);
47+
48+
test('Smallest non-prime deficient number is classified correctly', () {
49+
final result = perfectNumbers.classify(4);
50+
expect(result, equals(Classification.deficient));
51+
}, skip: true);
52+
53+
test('Medium deficient number is classified correctly', () {
54+
final result = perfectNumbers.classify(32);
55+
expect(result, equals(Classification.deficient));
56+
}, skip: true);
57+
58+
test('Large deficient number is classified correctly', () {
59+
final result = perfectNumbers.classify(33550337);
60+
expect(result, equals(Classification.deficient));
61+
}, skip: true);
62+
63+
test('Edge case (no factors other than itself) is classified correctly', () {
64+
final result = perfectNumbers.classify(1);
65+
expect(result, equals(Classification.deficient));
66+
}, skip: true);
67+
});
68+
69+
group('Invalid inputs', () {
70+
test('Zero is rejected (as it is not a positive integer)', () {
71+
expect(() => perfectNumbers.classify(0), throwsArgumentError);
72+
}, skip: true);
73+
74+
test('Negative integer is rejected (as it is not a positive integer)', () {
75+
expect(() => perfectNumbers.classify(-1), throwsArgumentError);
76+
}, skip: true);
77+
});
78+
});
79+
}

0 commit comments

Comments
 (0)