diff --git a/config.json b/config.json index 80564110..2d641654 100644 --- a/config.json +++ b/config.json @@ -178,6 +178,14 @@ ], "difficulty": 1 }, + { + "slug": "armstrong-numbers", + "name": "Armstrong Numbers", + "uuid": "bbc8720e-597c-4ae9-b39b-2f0fb8e6578d", + "practices": [], + "prerequisites": [], + "difficulty": 3 + }, { "slug": "atbash-cipher", "name": "Atbash Cipher", diff --git a/exercises/practice/armstrong-numbers/.docs/instructions.md b/exercises/practice/armstrong-numbers/.docs/instructions.md new file mode 100644 index 00000000..5e56bbe4 --- /dev/null +++ b/exercises/practice/armstrong-numbers/.docs/instructions.md @@ -0,0 +1,14 @@ +# Instructions + +An [Armstrong number][armstrong-number] is a number that is the sum of its own digits each raised to the power of the number of digits. + +For example: + +- 9 is an Armstrong number, because `9 = 9^1 = 9` +- 10 is _not_ an Armstrong number, because `10 != 1^2 + 0^2 = 1` +- 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153` +- 154 is _not_ an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190` + +Write some code to determine whether a number is an Armstrong number. + +[armstrong-number]: https://en.wikipedia.org/wiki/Narcissistic_number diff --git a/exercises/practice/armstrong-numbers/.meta/config.json b/exercises/practice/armstrong-numbers/.meta/config.json new file mode 100644 index 00000000..7262e84e --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "glennj" + ], + "files": { + "solution": [ + "lib/ArmstrongNumbers.pm" + ], + "test": [ + "t/armstrong-numbers.t" + ], + "example": [ + ".meta/solutions/lib/ArmstrongNumbers.pm" + ] + }, + "blurb": "Determine if a number is an Armstrong number.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Narcissistic_number" +} diff --git a/exercises/practice/armstrong-numbers/.meta/solutions/lib/ArmstrongNumbers.pm b/exercises/practice/armstrong-numbers/.meta/solutions/lib/ArmstrongNumbers.pm new file mode 100644 index 00000000..9d3f9e61 --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/solutions/lib/ArmstrongNumbers.pm @@ -0,0 +1,24 @@ +package ArmstrongNumbers; + +use strict; +use warnings; +use experimental qw; + +use Exporter qw; +our @EXPORT_OK = qw; + +use bignum; + +sub is_armstrong_number ($number) { + my $n = $number->copy(); + my $size = $n->length(); + my $sum = Math::BigInt->bzero(); + my $rem; + while ( $n->is_positive() ) { + ( $n, $rem ) = $n->bdiv(10); + $sum = $sum->badd( $rem->bpow($size) ); + } + return $sum->beq($number); +} + +1; diff --git a/exercises/practice/armstrong-numbers/.meta/solutions/t/armstrong-numbers.t b/exercises/practice/armstrong-numbers/.meta/solutions/t/armstrong-numbers.t new file mode 120000 index 00000000..b8ae3144 --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/solutions/t/armstrong-numbers.t @@ -0,0 +1 @@ +../../../t/armstrong-numbers.t \ No newline at end of file diff --git a/exercises/practice/armstrong-numbers/.meta/template-data.yaml b/exercises/practice/armstrong-numbers/.meta/template-data.yaml new file mode 100644 index 00000000..32886e09 --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/template-data.yaml @@ -0,0 +1,34 @@ +subs: is_armstrong_number +modules: + - use: bignum; +properties: + isArmstrongNumber: + test: |- + use Data::Dmp; + sprintf(<<'END', $case->{input}{number}, $case->{expected} ? ('T', '# True') : ('DF', '# Defined but False'), dmp($case->{description})); + is( + is_armstrong_number(%s), + %s, %s + %s + ); + END + +stub: |- + sub is_armstrong_number ($number) { + return undef; + } + +example: |- + use bignum; + + sub is_armstrong_number ($number) { + my $n = $number->copy(); + my $size = $n->length(); + my $sum = Math::BigInt->bzero(); + my $rem; + while ($n->is_positive()) { + ($n, $rem) = $n->bdiv(10); + $sum = $sum->badd($rem->bpow($size)); + } + return $sum->beq($number); + } diff --git a/exercises/practice/armstrong-numbers/.meta/tests.toml b/exercises/practice/armstrong-numbers/.meta/tests.toml new file mode 100644 index 00000000..b3f09e4c --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/tests.toml @@ -0,0 +1,43 @@ +# 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. + +[c1ed103c-258d-45b2-be73-d8c6d9580c7b] +description = "Zero is an Armstrong number" + +[579e8f03-9659-4b85-a1a2-d64350f6b17a] +description = "Single-digit numbers are Armstrong numbers" + +[2d6db9dc-5bf8-4976-a90b-b2c2b9feba60] +description = "There are no two-digit Armstrong numbers" + +[509c087f-e327-4113-a7d2-26a4e9d18283] +description = "Three-digit number that is an Armstrong number" + +[7154547d-c2ce-468d-b214-4cb953b870cf] +description = "Three-digit number that is not an Armstrong number" + +[6bac5b7b-42e9-4ecb-a8b0-4832229aa103] +description = "Four-digit number that is an Armstrong number" + +[eed4b331-af80-45b5-a80b-19c9ea444b2e] +description = "Four-digit number that is not an Armstrong number" + +[f971ced7-8d68-4758-aea1-d4194900b864] +description = "Seven-digit number that is an Armstrong number" + +[7ee45d52-5d35-4fbd-b6f1-5c8cd8a67f18] +description = "Seven-digit number that is not an Armstrong number" + +[5ee2fdf8-334e-4a46-bb8d-e5c19c02c148] +description = "Armstrong number containing seven zeroes" + +[12ffbf10-307a-434e-b4ad-c925680e1dd4] +description = "The largest and last Armstrong number" diff --git a/exercises/practice/armstrong-numbers/lib/ArmstrongNumbers.pm b/exercises/practice/armstrong-numbers/lib/ArmstrongNumbers.pm new file mode 100644 index 00000000..8efecee7 --- /dev/null +++ b/exercises/practice/armstrong-numbers/lib/ArmstrongNumbers.pm @@ -0,0 +1,12 @@ +package ArmstrongNumbers; + +use v5.40; + +use Exporter qw; +our @EXPORT_OK = qw; + +sub is_armstrong_number ($number) { + return undef; +} + +1; diff --git a/exercises/practice/armstrong-numbers/t/armstrong-numbers.t b/exercises/practice/armstrong-numbers/t/armstrong-numbers.t new file mode 100755 index 00000000..d111f8a8 --- /dev/null +++ b/exercises/practice/armstrong-numbers/t/armstrong-numbers.t @@ -0,0 +1,76 @@ +#!/usr/bin/env perl +use Test2::V0; + +use FindBin qw<$Bin>; +use lib "$Bin/../lib", "$Bin/../local/lib/perl5"; + +use ArmstrongNumbers qw; +use bignum; + +is( # begin: c1ed103c-258d-45b2-be73-d8c6d9580c7b + is_armstrong_number(0), + T, # True + "Zero is an Armstrong number" +); # end: c1ed103c-258d-45b2-be73-d8c6d9580c7b + +is( # begin: 579e8f03-9659-4b85-a1a2-d64350f6b17a + is_armstrong_number(5), + T, # True + "Single-digit numbers are Armstrong numbers" +); # end: 579e8f03-9659-4b85-a1a2-d64350f6b17a + +is( # begin: 2d6db9dc-5bf8-4976-a90b-b2c2b9feba60 + is_armstrong_number(10), + DF, # Defined but False + "There are no two-digit Armstrong numbers" +); # end: 2d6db9dc-5bf8-4976-a90b-b2c2b9feba60 + +is( # begin: 509c087f-e327-4113-a7d2-26a4e9d18283 + is_armstrong_number(153), + T, # True + "Three-digit number that is an Armstrong number" +); # end: 509c087f-e327-4113-a7d2-26a4e9d18283 + +is( # begin: 7154547d-c2ce-468d-b214-4cb953b870cf + is_armstrong_number(100), + DF, # Defined but False + "Three-digit number that is not an Armstrong number" +); # end: 7154547d-c2ce-468d-b214-4cb953b870cf + +is( # begin: 6bac5b7b-42e9-4ecb-a8b0-4832229aa103 + is_armstrong_number(9474), + T, # True + "Four-digit number that is an Armstrong number" +); # end: 6bac5b7b-42e9-4ecb-a8b0-4832229aa103 + +is( # begin: eed4b331-af80-45b5-a80b-19c9ea444b2e + is_armstrong_number(9475), + DF, # Defined but False + "Four-digit number that is not an Armstrong number" +); # end: eed4b331-af80-45b5-a80b-19c9ea444b2e + +is( # begin: f971ced7-8d68-4758-aea1-d4194900b864 + is_armstrong_number(9926315), + T, # True + "Seven-digit number that is an Armstrong number" +); # end: f971ced7-8d68-4758-aea1-d4194900b864 + +is( # begin: 7ee45d52-5d35-4fbd-b6f1-5c8cd8a67f18 + is_armstrong_number(9926314), + DF, # Defined but False + "Seven-digit number that is not an Armstrong number" +); # end: 7ee45d52-5d35-4fbd-b6f1-5c8cd8a67f18 + +is( # begin: 5ee2fdf8-334e-4a46-bb8d-e5c19c02c148 + is_armstrong_number(186709961001538790100634132976990), + T, # True + "Armstrong number containing seven zeroes" +); # end: 5ee2fdf8-334e-4a46-bb8d-e5c19c02c148 + +is( # begin: 12ffbf10-307a-434e-b4ad-c925680e1dd4 + is_armstrong_number(115132219018763992565095597973971522401), + T, # True + "The largest and last Armstrong number" +); # end: 12ffbf10-307a-434e-b4ad-c925680e1dd4 + +done_testing;