Skip to content

Commit

Permalink
Add perfect-numbers (#590)
Browse files Browse the repository at this point in the history
* Add `perfect-numbers`

* Remove empty classificaton enum
  • Loading branch information
BNAndras authored Sep 23, 2024
1 parent 07a8c93 commit cb5b74e
Show file tree
Hide file tree
Showing 8 changed files with 232 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,14 @@
"math"
]
},
{
"slug": "perfect-numbers",
"name": "Perfect Numbers",
"uuid": "696b5088-ec86-4d60-8ac1-2cc1d89dee52",
"practices": [],
"prerequisites": [],
"difficulty": 2
},
{
"slug": "isbn-verifier",
"name": "ISBN Verifier",
Expand Down
39 changes: 39 additions & 0 deletions exercises/practice/perfect-numbers/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Instructions

Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.

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].
The _aliquot sum_ is defined as the sum of the factors of a number not including the number itself.
For example, the aliquot sum of `15` is `1 + 3 + 5 = 9`.

## Perfect

A number is perfect when it equals its aliquot sum.
For example:

- `6` is a perfect number because `1 + 2 + 3 = 6`
- `28` is a perfect number because `1 + 2 + 4 + 7 + 14 = 28`

## Abundant

A number is abundant when it is less than its aliquot sum.
For example:

- `12` is an abundant number because `1 + 2 + 3 + 4 + 6 = 16`
- `24` is an abundant number because `1 + 2 + 3 + 4 + 6 + 8 + 12 = 36`

## Deficient

A number is deficient when it is greater than its aliquot sum.
For example:

- `8` is a deficient number because `1 + 2 + 4 = 7`
- Prime numbers are deficient

## Task

Implement a way to determine whether a given number is [perfect](#perfect).
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).

[nicomachus]: https://en.wikipedia.org/wiki/Nicomachus
[aliquot-sum]: https://en.wikipedia.org/wiki/Aliquot_sum
19 changes: 19 additions & 0 deletions exercises/practice/perfect-numbers/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"BNAndras"
],
"files": {
"solution": [
"lib/perfect_numbers.dart"
],
"test": [
"test/perfect_numbers_test.dart"
],
"example": [
".meta/lib/example.dart"
]
},
"blurb": "Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.",
"source": "Taken from Chapter 2 of Functional Thinking by Neal Ford.",
"source_url": "https://www.oreilly.com/library/view/functional-thinking/9781449365509/"
}
28 changes: 28 additions & 0 deletions exercises/practice/perfect-numbers/.meta/lib/example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
enum Classification {
perfect,
abundant,
deficient,
}

class PerfectNumbers {
Classification classify(int number) {
if (number <= 0) {
throw ArgumentError('Number must be greater than 0');
}

var sum = 0;
for (var i = 1; i < number; i++) {
if (number % i == 0) {
sum += i;
}
}

if (sum == number) {
return Classification.perfect;
} else if (sum > number) {
return Classification.abundant;
} else {
return Classification.deficient;
}
}
}
49 changes: 49 additions & 0 deletions exercises/practice/perfect-numbers/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 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.

[163e8e86-7bfd-4ee2-bd68-d083dc3381a3]
description = "Perfect numbers -> Smallest perfect number is classified correctly"

[169a7854-0431-4ae0-9815-c3b6d967436d]
description = "Perfect numbers -> Medium perfect number is classified correctly"

[ee3627c4-7b36-4245-ba7c-8727d585f402]
description = "Perfect numbers -> Large perfect number is classified correctly"

[80ef7cf8-9ea8-49b9-8b2d-d9cb3db3ed7e]
description = "Abundant numbers -> Smallest abundant number is classified correctly"

[3e300e0d-1a12-4f11-8c48-d1027165ab60]
description = "Abundant numbers -> Medium abundant number is classified correctly"

[ec7792e6-8786-449c-b005-ce6dd89a772b]
description = "Abundant numbers -> Large abundant number is classified correctly"

[e610fdc7-2b6e-43c3-a51c-b70fb37413ba]
description = "Deficient numbers -> Smallest prime deficient number is classified correctly"

[0beb7f66-753a-443f-8075-ad7fbd9018f3]
description = "Deficient numbers -> Smallest non-prime deficient number is classified correctly"

[1c802e45-b4c6-4962-93d7-1cad245821ef]
description = "Deficient numbers -> Medium deficient number is classified correctly"

[47dd569f-9e5a-4a11-9a47-a4e91c8c28aa]
description = "Deficient numbers -> Large deficient number is classified correctly"

[a696dec8-6147-4d68-afad-d38de5476a56]
description = "Deficient numbers -> Edge case (no factors other than itself) is classified correctly"

[72445cee-660c-4d75-8506-6c40089dc302]
description = "Invalid inputs -> Zero is rejected (as it is not a positive integer)"

[2d72ce2c-6802-49ac-8ece-c790ba3dae13]
description = "Invalid inputs -> Negative integer is rejected (as it is not a positive integer)"
5 changes: 5 additions & 0 deletions exercises/practice/perfect-numbers/lib/perfect_numbers.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// define the Classification enum

class PerfectNumbers {
// Put your code here
}
5 changes: 5 additions & 0 deletions exercises/practice/perfect-numbers/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: 'perfect_numbers'
environment:
sdk: '>=3.2.0 <4.0.0'
dev_dependencies:
test: '<2.0.0'
79 changes: 79 additions & 0 deletions exercises/practice/perfect-numbers/test/perfect_numbers_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import 'package:perfect_numbers/perfect_numbers.dart';
import 'package:test/test.dart';

void main() {
final perfectNumbers = PerfectNumbers();

group('PerfectNumbers', () {
group('Perfect numbers', () {
test('Smallest perfect number is classified correctly', () {
final result = perfectNumbers.classify(6);
expect(result, equals(Classification.perfect));
}, skip: false);

test('Medium perfect number is classified correctly', () {
final result = perfectNumbers.classify(28);
expect(result, equals(Classification.perfect));
}, skip: true);

test('Large perfect number is classified correctly', () {
final result = perfectNumbers.classify(33550336);
expect(result, equals(Classification.perfect));
}, skip: true);
});

group('Abundant numbers', () {
test('Smallest abundant number is classified correctly', () {
final result = perfectNumbers.classify(12);
expect(result, equals(Classification.abundant));
}, skip: true);

test('Medium abundant number is classified correctly', () {
final result = perfectNumbers.classify(30);
expect(result, equals(Classification.abundant));
}, skip: true);

test('Large abundant number is classified correctly', () {
final result = perfectNumbers.classify(33550335);
expect(result, equals(Classification.abundant));
}, skip: true);
});

group('Deficient numbers', () {
test('Smallest prime deficient number is classified correctly', () {
final result = perfectNumbers.classify(2);
expect(result, equals(Classification.deficient));
}, skip: true);

test('Smallest non-prime deficient number is classified correctly', () {
final result = perfectNumbers.classify(4);
expect(result, equals(Classification.deficient));
}, skip: true);

test('Medium deficient number is classified correctly', () {
final result = perfectNumbers.classify(32);
expect(result, equals(Classification.deficient));
}, skip: true);

test('Large deficient number is classified correctly', () {
final result = perfectNumbers.classify(33550337);
expect(result, equals(Classification.deficient));
}, skip: true);

test('Edge case (no factors other than itself) is classified correctly', () {
final result = perfectNumbers.classify(1);
expect(result, equals(Classification.deficient));
}, skip: true);
});

group('Invalid inputs', () {
test('Zero is rejected (as it is not a positive integer)', () {
expect(() => perfectNumbers.classify(0), throwsArgumentError);
}, skip: true);

test('Negative integer is rejected (as it is not a positive integer)', () {
expect(() => perfectNumbers.classify(-1), throwsArgumentError);
}, skip: true);
});
});
}

0 comments on commit cb5b74e

Please sign in to comment.