forked from TheAlgorithms/Rust
-
Notifications
You must be signed in to change notification settings - Fork 0
/
egg_dropping.rs
91 lines (73 loc) · 2.11 KB
/
egg_dropping.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/// # Egg Dropping Puzzle
/// `egg_drop(eggs, floors)` returns the least number of egg droppings
/// required to determine the highest floor from which an egg will not
/// break upon dropping
///
/// Assumptions: n > 0
pub fn egg_drop(eggs: u32, floors: u32) -> u32 {
assert!(eggs > 0);
// Explicity handle edge cases (optional)
if eggs == 1 || floors == 0 || floors == 1 {
return floors;
}
let eggs_index = eggs as usize;
let floors_index = floors as usize;
// Store solutions to subproblems in 2D Vec,
// where egg_drops[i][j] represents the solution to the egg dropping
// problem with i eggs and j floors
let mut egg_drops: Vec<Vec<u32>> = vec![vec![0; floors_index + 1]; eggs_index + 1];
// Assign solutions for egg_drop(n, 0) = 0, egg_drop(n, 1) = 1
for egg_drop in egg_drops.iter_mut().skip(1) {
egg_drop[0] = 0;
egg_drop[1] = 1;
}
// Assign solutions to egg_drop(1, k) = k
for j in 1..=floors_index {
egg_drops[1][j] = j as u32;
}
// Complete solutions vector using optimal substructure property
for i in 2..=eggs_index {
for j in 2..=floors_index {
egg_drops[i][j] = std::u32::MAX;
for k in 1..=j {
let res = 1 + std::cmp::max(egg_drops[i - 1][k - 1], egg_drops[i][j - k]);
if res < egg_drops[i][j] {
egg_drops[i][j] = res;
}
}
}
}
egg_drops[eggs_index][floors_index]
}
#[cfg(test)]
mod tests {
use super::egg_drop;
#[test]
fn zero_floors() {
assert_eq!(egg_drop(5, 0), 0);
}
#[test]
fn one_egg() {
assert_eq!(egg_drop(1, 8), 8);
}
#[test]
fn eggs2_floors2() {
assert_eq!(egg_drop(2, 2), 2);
}
#[test]
fn eggs3_floors5() {
assert_eq!(egg_drop(3, 5), 3);
}
#[test]
fn eggs2_floors10() {
assert_eq!(egg_drop(2, 10), 4);
}
#[test]
fn eggs2_floors36() {
assert_eq!(egg_drop(2, 36), 8);
}
#[test]
fn large_floors() {
assert_eq!(egg_drop(2, 100), 14);
}
}