DEV Community

Discussion on: Challenge: find 'Kaprekar numbers'

Collapse
 
yondrin profile image
Alex Doroshenko • Edited

And if you consider that parts of a number should not necessarily be of equal size, the solution becomes a bit more wordy (suppose, a lot can be improved here):

fn main() {
    (1usize..)
        .into_iter()
        .filter(is_kaprekar)
        .take(8)
        .for_each(|num| println!("{}", num));
}

fn is_kaprekar(num: &usize) -> bool {
    NumberParts::of(num * num)
        .any(|(left, right)| {
            right > 0 && left + right == *num
        })
}

struct NumberParts {
    original_number: usize,
    split_position: usize,
}

impl NumberParts {
    fn of(original_number: usize) -> Self {
        NumberParts {
            original_number,
            split_position: 10usize.pow(
                (original_number as f64).log(10f64) as u32 + 1,
            ),
        }
    }
}

impl Iterator for NumberParts {
    type Item = (usize, usize);

    fn next(&mut self) -> Option<Self::Item> {
        let split = self.split_position;

        if split == 1 {
            None
        } else {
            self.split_position /= 10;
            Some((
                self.original_number / split,
                self.original_number % split,
            ))
        }
    }
}