Skip to content

Commit d2a5ba3

Browse files
authored
armstrong-numbers: add larger testcases (#1601)
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).
1 parent ff73af7 commit d2a5ba3

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

exercises/practice/armstrong-numbers/.meta/example.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ pub fn is_armstrong_number(num: u32) -> bool {
33
let l = s.len();
44
s.chars()
55
.map(|c| c.to_digit(10).unwrap().pow(l as u32))
6-
.sum::<u32>()
7-
== num
6+
.try_fold(0u32, u32::checked_add)
7+
== Some(num)
88
}

exercises/practice/armstrong-numbers/tests/armstrong-numbers.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,30 @@ fn test_seven_digit_armstrong_number() {
5252
fn test_seven_digit_non_armstrong_number() {
5353
assert!(!is_armstrong_number(9_926_316))
5454
}
55+
56+
#[test]
57+
#[ignore]
58+
fn test_nine_digit_armstrong_number() {
59+
assert!(is_armstrong_number(912_985_153));
60+
}
61+
62+
#[test]
63+
#[ignore]
64+
fn test_nine_digit_non_armstrong_number() {
65+
assert!(!is_armstrong_number(999_999_999));
66+
}
67+
68+
#[test]
69+
#[ignore]
70+
fn test_ten_digit_non_armstrong_number() {
71+
assert!(!is_armstrong_number(3_999_999_999));
72+
}
73+
74+
// The following number has an Armstrong sum equal to 2^32 plus itself,
75+
// and therefore will be detected as an Armstrong number if you are
76+
// incorrectly using wrapping arithmetic.
77+
#[test]
78+
#[ignore]
79+
fn test_properly_handles_overflow() {
80+
assert!(!is_armstrong_number(4_106_098_957));
81+
}

0 commit comments

Comments
 (0)