Skip to content

Commit

Permalink
P31: bottom-to-top dynamic programming.
Browse files Browse the repository at this point in the history
  • Loading branch information
tfpf committed Feb 11, 2024
1 parent 6b671e9 commit 1b04045
Showing 1 changed file with 24 additions and 39 deletions.
63 changes: 24 additions & 39 deletions src/solutions/coin_sums.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1,30 @@
struct CacheMap {
map: std::collections::HashMap<(usize, i32), i32>,
denominations: [i32; 8],
}
impl CacheMap {
fn new(denominations: [i32; 8]) -> CacheMap {
CacheMap {
map: std::collections::HashMap::new(),
denominations,
}
pub fn solve() -> i64 {
let denominations = [1, 2, 5, 10, 20, 50, 100, 200];

// Any element in this matrix be the number of ways to obtain a sum equal
// to the column index using coins at indices less than or equal to the row
// index.
let (rows, cols) = (denominations.len(), denominations.iter().max().unwrap() + 1);
let mut ways = vec![vec![0; cols]; rows];

// Bottom-up dynamic programming.
for idx in 0..rows {
ways[idx][0] = 1;
}
/// Count the number of ways to obtain the remaining amount of money using
/// denominations at the given index and above.
///
/// * `key` - Tuple of the index and remaining amount.
///
/// -> Number of ways.
fn get(&mut self, key: (usize, i32)) -> i32 {
let (index, remaining) = key;
if index >= 8 || remaining < 0 {
return 0;
}
if remaining == 0 {
return 1;
}
match self.map.get(&key) {
Some(&value) => value,
None => {
let without = self.get((index + 1, remaining));
let with = self.get((index, remaining - self.denominations[index]));
let value = without + with;
self.map.insert(key, value);
value
}
for sum in 1..cols {
ways[0][sum] = if sum % denominations[0] == 0 { 1 } else { 0 };
}
for idx in 1..rows {
for sum in 1..cols {
ways[idx][sum] = ways[idx - 1][sum]
+ if sum >= denominations[idx] {
ways[idx][sum - denominations[idx]]
} else {
0
};
}
}
}

pub fn solve() -> i64 {
let denominations = [1, 2, 5, 10, 20, 50, 100, 200];
let mut cache_map = CacheMap::new(denominations);
let result = cache_map.get((0, 200));
let result = ways[rows - 1][cols - 1];

assert_eq!(result, 73682);
result as i64
Expand Down

0 comments on commit 1b04045

Please sign in to comment.