Reputation: 2053
How can I tell the compiler that this is a type that should have a function pow()
?
pub fn is_armstrong_number(num: u32) -> bool {
[1, 2, 3, 4, 5, 6, 7, 8, 9].iter()
.zip( num.to_string().chars()
.map(|c| c.to_digit(10).unwrap()) )
.map(|(x, y)| *x.pow(y))
.fold(0, |acc, x| acc + x) == num
}
Error:
error[E0599]: no method named `pow` found for type `&{integer}` in the current scope
--> src/lib.rs:10:47
|
10 | .map(|(x, y)| *x.pow(y))
| ^^^
Upvotes: 1
Views: 651
Reputation: 382150
You can cast with as
.
Change
.map(|(x, y)| *x.pow(y))
to
.map(|(x, y)| (*x as u32).pow(y))
Upvotes: 2
Reputation: 26727
Currently, the compiler doesn't guess what the type of your integer is.
The compiler needs a hint:
pub fn is_armstrong_number(num: u32) -> bool {
(1..10u32) // [1, 2, 3, 4, 5, 6, 7, 8, 9].iter()
.zip(num.to_string().chars().map(|c| c.to_digit(10).unwrap()))
.map(|(x, y)| x.pow(y))
.sum::<u32>() // .fold(0, |acc, x| acc + x)
== num
}
Also note that your implementation of armstrong_number is wrong, a correct one could be:
fn is_armstrong_number(num: u32) -> bool {
let buf = num.to_string();
let y = buf.chars().count() as u32;
buf.chars()
.map(|c| c.to_digit(10).unwrap())
.map(|x| x.pow(y))
.sum::<u32>()
== num
}
fn main() {
assert!(is_armstrong_number(153));
assert!(!is_armstrong_number(11));
}
I also tried this one for fun:
extern crate num; // 0.2.0
#[derive(Clone, Copy)]
struct DigitInteger<T> {
num: T,
radix: T,
}
impl<T> Iterator for DigitInteger<T>
where
T: num::Unsigned + num::Zero + Copy,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.num != T::zero() {
let ret = self.num % self.radix;
self.num = self.num / self.radix;
Some(ret)
} else {
None
}
}
}
fn is_armstrong_number<T>(num: T, radix: T) -> bool
where
T: num::Unsigned,
T: num::pow::Pow<T>,
T: num::FromPrimitive,
T: std::iter::Sum<<<DigitInteger<T> as std::iter::Iterator>::Item as num::traits::Pow<T>>::Output>,
T: Copy,
{
use num::pow::Pow;
let d = DigitInteger { num, radix };
let y = T::from_usize(d.count()).unwrap();
d.map(|x| Pow::pow(x, y)).sum::<T>() == num
}
fn main() {
assert!(is_armstrong_number(153u32, 10));
assert!(!is_armstrong_number(11u32, 10));
assert!(is_armstrong_number(1u32, 2));
assert!(!is_armstrong_number(2u32, 2));
}
Upvotes: 3