Chapter 2 exercises: memoize fib and timeit

This commit is contained in:
Vladan Popovic 2019-08-12 14:10:05 +02:00
parent c6c48de95f
commit 54df888af7
3 changed files with 87 additions and 0 deletions

6
chapter-2/Cargo.lock generated Normal file
View File

@ -0,0 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "chapter-2"
version = "0.1.0"

9
chapter-2/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "chapter-2"
version = "0.1.0"
authors = ["Vladan Popovic <vladanovic@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

72
chapter-2/src/main.rs Normal file
View File

@ -0,0 +1,72 @@
use std::collections::HashMap;
use std::hash::Hash;
use std::time::Instant;
fn memoize<A: Copy + Hash + Eq, B: Clone, F>(f: F, mut store: HashMap<A, B>) -> impl FnMut(A) -> B
where
F: Fn(A) -> B,
{
move |x: A| {
let res = store.entry(x).or_insert_with(|| f(x));
res.clone()
}
}
fn fib(n: u64) -> u64 {
match n {
0 => 1,
1 => 1,
_ => fib(n - 1) + fib(n - 2),
}
}
fn fibt(n: u64) -> u64 {
fn fib_tailrec(nt: u64, ct: u64, previous: u64, current: u64) -> u64 {
match ct {
1 => fib_tailrec(nt, 2, 1, 1),
_ => {
if ct != nt {
fib_tailrec(nt, ct + 1, current, previous + current)
} else {
current
}
}
}
}
fib_tailrec(n + 1, 1, 0, 1)
}
// mut f because of the mutable hash in memoize and hence the return FnMut
fn timeit<T, F>(mut f: F) -> (T, u128)
where
F: FnMut() -> T,
{
let now = Instant::now();
let res = f();
(res, now.elapsed().as_micros())
}
fn main() {
let mut mem_fib = memoize(fib, HashMap::new());
let mut mem_fibt = memoize(fibt, HashMap::new());
let (res, duration) = timeit(|| mem_fib(40));
println!(
"Finished regular fib(40) = {} in {} microseconds",
res, duration
);
let (res, duration) = timeit(|| mem_fib(40));
println!(
"Finished memoized fib(40) = {} in {} microseconds",
res, duration
);
let (res, duration) = timeit(|| mem_fibt(40));
println!(
"Finished regular tailrec fib(40) = {} in {} microseconds",
res, duration
);
let (res, duration) = timeit(|| mem_fibt(40));
println!(
"Finished memoized tailrec fib(40) = {} in {} microseconds",
res, duration
);
}