Skip to content

Commit 3c484ce

Browse files
authored
refactor(exercise/armstrong-numbers): optimize implementation to use custom iterator type (#21)
1 parent 31f11d0 commit 3c484ce

File tree

2 files changed

+46
-11
lines changed

2 files changed

+46
-11
lines changed

.pre-commit-config.yaml

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
repos:
2-
- repo: https://github.com/doublify/pre-commit-rust
3-
rev: v1.0
2+
# - repo: https://github.com/doublify/pre-commit-rust
3+
# rev: v1.0
4+
# hooks:
5+
# - id: fmt
6+
# - id: cargo-check
7+
# - id: clippy
8+
- repo: https://github.com/pre-commit/pre-commit-hooks
9+
rev: v4.4.0
410
hooks:
5-
- id: fmt
6-
- id: cargo-check
7-
- id: clippy
11+
- id: end-of-file-fixer
12+
- id: trailing-whitespace
+36-6
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,48 @@
11
pub fn is_armstrong_number(num: u32) -> bool {
2-
let digits = digits(num);
3-
let exponent = digits.len() as u32;
2+
let digits = Digits::new(num);
3+
let exponent = digits.num_digits;
44

55
if exponent >= 10 {
6+
// skip the calculation if the exponent is too large
67
return false;
78
}
89

9-
num == digits.iter().map(|digit| digit.pow(exponent)).sum()
10+
num == Digits::new(num).map(|digit| digit.pow(exponent)).sum()
1011
}
1112

12-
fn digits(num: u32) -> Vec<u32> {
13+
struct Digits {
14+
num: u32,
15+
num_digits: u32,
16+
}
17+
18+
impl Digits {
19+
fn new(num: u32) -> Self {
20+
Digits {
21+
num,
22+
num_digits: number_of_digits(num),
23+
}
24+
}
25+
}
26+
27+
impl Iterator for Digits {
28+
type Item = u32;
29+
30+
fn next(&mut self) -> Option<Self::Item> {
31+
if self.num_digits == 0 {
32+
None
33+
} else {
34+
let digit = self.num % 10;
35+
self.num /= 10;
36+
self.num_digits -= 1;
37+
Some(digit)
38+
}
39+
}
40+
}
41+
42+
fn number_of_digits(num: u32) -> u32 {
1343
if num < 10 {
14-
vec![num]
44+
1
1545
} else {
16-
[vec![num % 10], digits(num / 10)].concat()
46+
1 + number_of_digits(num / 10)
1747
}
1848
}

0 commit comments

Comments
 (0)