Skip to content

Commit

Permalink
armstrong-numbers: add larger testcases (#1601)
Browse files Browse the repository at this point in the history
Add some extra Armstrong number tests for larger numbers. In particular, the ten-digit solutions can cause naive solutions to overflow; it might be reasonable to gate them behind a feature flag or bonus exercise.

The test case 4106098957 is particularly interesting: if the addition is done using `wrapping_add`, this number will appear as an Armstrong number, even though it really isn't. This is because the sum is equal to exactly 2^32 + 4106098957. This might be a worthwhile testcase to add to other languages too to check for overflow bugs. (Rust should panic in debug mode, but this will also catch folks who try to use wrapping_add to get around the panic).

The example needs to be updated to handle wrapping properly.
Use checked_add to gracefully handle the case where the sum overflows.

Note that the individual powers cannot overflow (9^10 < 2^32).
  • Loading branch information
nneonneo authored Dec 11, 2022
1 parent ff73af7 commit d2a5ba3
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
4 changes: 2 additions & 2 deletions exercises/practice/armstrong-numbers/.meta/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ pub fn is_armstrong_number(num: u32) -> bool {
let l = s.len();
s.chars()
.map(|c| c.to_digit(10).unwrap().pow(l as u32))
.sum::<u32>()
== num
.try_fold(0u32, u32::checked_add)
== Some(num)
}
27 changes: 27 additions & 0 deletions exercises/practice/armstrong-numbers/tests/armstrong-numbers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,30 @@ fn test_seven_digit_armstrong_number() {
fn test_seven_digit_non_armstrong_number() {
assert!(!is_armstrong_number(9_926_316))
}

#[test]
#[ignore]
fn test_nine_digit_armstrong_number() {
assert!(is_armstrong_number(912_985_153));
}

#[test]
#[ignore]
fn test_nine_digit_non_armstrong_number() {
assert!(!is_armstrong_number(999_999_999));
}

#[test]
#[ignore]
fn test_ten_digit_non_armstrong_number() {
assert!(!is_armstrong_number(3_999_999_999));
}

// The following number has an Armstrong sum equal to 2^32 plus itself,
// and therefore will be detected as an Armstrong number if you are
// incorrectly using wrapping arithmetic.
#[test]
#[ignore]
fn test_properly_handles_overflow() {
assert!(!is_armstrong_number(4_106_098_957));
}

0 comments on commit d2a5ba3

Please sign in to comment.