This article is part of a series where I'll be diving head first into the Project Euler puzzles. I want to document the challenge of solving such a puzzle and how I got to the answer. I want to prefix this by stating that I can't cheat for any of these challenges; with that I mean I can't look up any other implementations online. After the implementation, I will validate the answer by using this document or a similar sheet.
In this article I'll be solving: Project Euler #36.
“Find the sum of all numbers, less than one million, which are palindromic in base 10 and base 2.”
I’ve already solved this Euler puzzle some time ago, and this is the code I used:
fn is_palindrome(string: String) -> bool {
let len = string.len() - 1;
let end = string.len() / 2;
string[0..end]
.chars()
.enumerate()
.all(|(i,n)| n == string.chars().nth(len - i).unwrap())
}
fn sum_palindrome_base2_10(digits: u32) -> u32 {
let mut sum_pal = 0;
for i in 0..digits {
let i_base10 = format!("{}", i);
let i_base2 = format!("{:b}", i);
if is_palindrome(i_base10) && is_palindrome(i_base2) {
sum_pal += i;
}
}
sum_pal
}
#[test]
fn palindrome_numbers_test() {
assert_eq!(sum_palindrome_base2_10(586), 1055);
assert_eq!(sum_palindrome_base2_10(1_000_000), 872187);
}
Nothing too complicated, I’d say. The only change I made is swapping out the is_palindrome()
method with the one from “Largest palindrome product”. Added to that, I made a small little improvement by using fold()
to sum the matched digits:
fn sum_palindrome_base2_10(digits: u32) -> u32 {
(0..digits).fold(0, |acc, i| {
let i_base10 = format!("{}", i);
let i_base2 = format!("{:b}", i);
if is_palindrome(i_base10) && is_palindrome(i_base2) {
acc + i
} else {
acc
}
})
}
#[test]
fn palindrome_numbers_test() {
assert_eq!(sum_palindrome_base2_10(586), 1055);
assert_eq!(sum_palindrome_base2_10(1_000_000), 872187);
}
The full solution is available on GitHub.