I thought that rewriting "Math puzzles that train the programmer's brain more" with Rust might be just right for preventing blurring.
Ruby
q18_2.rb
N = 16
@memo = {0 => 0, 1 => 1}
def steps(n)
return @memo[n] if @memo[n]
none = (~n)
movable = (none << 1) + 1
moved = (n & (~movable)) | ((n >> 1) & none)
@memo[n] = 1 + steps(moved)
end
sum = 0
(1..((1 << N) - 1)).each do |i|
sum += steps(i)
end
puts sum
Rust
main.rs
use std::collections::HashMap;
fn main() {
let mut q18 = Q18::new();
println!("{}", q18.sum(16));
}
struct Q18 {
memo: HashMap<u64, u64>,
}
impl Q18 {
fn new() -> Q18 {
let mut q18 = Q18 {
memo: HashMap::new(),
};
q18.memo.insert(0, 0);
q18.memo.insert(1, 1);
q18
}
fn steps(&mut self, n: u64) -> u64 {
match self.memo.get(&n) {
Some(v) => return *v,
_ => {
let none = !n;
let movable = (none << 1) + 1;
let moved = (n & !movable) | ((n >> 1) & none);
let result = 1 + self.steps(moved);
self.memo.insert(n, result);
result
}
}
}
fn sum(&mut self, number_of_steps: u64) -> u64 {
(1..=((1 << number_of_steps) - 1)).fold(0, |acc, i| acc + self.steps(i))
}
}
If you don't divide the @ memo [n] = 1 + steps (moved)
part of the original Ruby code into two lines, a Borrowing error will occur ("cannot borrow * self
as mutable more than once at". Since a time "), the result is temporarily stored in the variable as result.
Inevitably, the code will be clear.
Recommended Posts