Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- type WeightType = u32;
- const TARGET_WEIGHT: WeightType = 150;
- #[derive(Clone, Debug)]
- pub struct Boy {
- name: String,
- weight: WeightType,
- }
- pub type CubPack = Vec<Boy>;
- #[derive(Debug)]
- pub enum Canoe {
- Solo(Boy),
- Duet(Boy, Boy),
- }
- impl Canoe {
- fn weight(&self) -> WeightType {
- match *self {
- Canoe::Solo(ref boy) => boy.weight,
- Canoe::Duet(ref b0, ref b1) => b0.weight + b1.weight,
- }
- }
- }
- pub type Canoes = Vec<Canoe>;
- pub fn assign_canoes(cubs: &CubPack) -> Canoes {
- let mut canoes: Canoes = Vec::new();
- let mut cubs = cubs.clone();
- cubs.sort_by_key(|boy| boy.weight + 0);
- let mut assigned: Vec<bool> = cubs.iter().map(|_| false).collect();
- let mut heavy = cubs.len();
- for light in 0..cubs.len() {
- if assigned[light] {
- continue;
- }
- while !assigned[light] && heavy > light + 1 {
- if cubs[light].weight + cubs[heavy - 1].weight <= TARGET_WEIGHT {
- assigned[light] = true;
- assigned[heavy - 1] = true;
- canoes.push(Canoe::Duet(cubs[light].clone(),
- cubs[heavy - 1].clone()));
- }
- heavy -= 1;
- }
- if !assigned[light] {
- canoes.push(Canoe::Solo(cubs[light].clone()));
- assigned[light] = true;
- }
- }
- canoes
- }
- fn cub_pack() -> CubPack {
- vec![
- Boy { name: "Billy".to_string(), weight: 93 },
- Boy { name: "Timmy".to_string(), weight: 67 },
- Boy { name: "Johnny".to_string(), weight: 119 },
- Boy { name: "Bobby".to_string(), weight: 113 },
- Boy { name: "Ralphie".to_string(), weight: 110 },
- Boy { name: "Bart".to_string(), weight: 114 },
- Boy { name: "Carter".to_string(), weight: 83 },
- Boy { name: "Davey".to_string(), weight: 101 },
- Boy { name: "Kevin".to_string(), weight: 47 },
- Boy { name: "Alan".to_string(), weight: 112 },
- Boy { name: "Eric".to_string(), weight: 49 },
- Boy { name: "Craig".to_string(), weight: 54 },
- Boy { name: "Brad".to_string(), weight: 85 },
- ]
- }
- fn main() {
- let canoes = assign_canoes(&cub_pack());
- for canoe in canoes {
- match canoe {
- Canoe::Solo(ref boy) => {
- println!("{} lb: {}", canoe.weight(), boy.name)
- }
- Canoe::Duet(ref b0, ref b1) => {
- println!("{} lb: {}, {}", canoe.weight(), b0.name, b1.name)
- }
- }
- }
- }
- #[cfg(test)]
- mod tests {
- use super::*;
- #[test]
- fn test_none() {
- let cub_pack: CubPack = vec![];
- let canoes = assign_canoes(&cub_pack);
- assert!(canoes.len() == 0);
- }
- #[test]
- fn test_solos() {
- let cub_pack: CubPack = vec![
- Boy { name: "Billy".to_string(), weight: 85 },
- Boy { name: "Timmy".to_string(), weight: 80 },
- ];
- let canoes = assign_canoes(&cub_pack);
- assert!(canoes.len() == 2);
- if let Canoe::Solo(ref boy) = canoes[0] {
- assert!(boy.name == "Timmy");
- assert!(boy.weight == 80);
- } else {
- panic!("");
- }
- if let Canoe::Solo(ref boy) = canoes[1] {
- assert!(boy.name == "Billy");
- assert!(boy.weight == 85);
- } else {
- panic!("");
- }
- }
- #[test]
- fn test_duet() {
- let cub_pack: CubPack = vec![
- Boy { name: "Billy".to_string(), weight: 80 },
- Boy { name: "Timmy".to_string(), weight: 70 },
- ];
- let canoes = assign_canoes(&cub_pack);
- assert!(canoes.len() == 1);
- if let Canoe::Duet(ref b0, ref b1) = canoes[0] {
- assert!(b0.name == "Timmy");
- assert!(b0.weight == 70);
- assert!(b1.name == "Billy");
- assert!(b1.weight == 80);
- } else {
- panic!("");
- }
- }
- #[test]
- fn test_mixed() {
- let cub_pack: CubPack = vec![
- Boy { name: "Billy".to_string(), weight: 80 },
- Boy { name: "Kevin".to_string(), weight: 70 },
- Boy { name: "Timmy".to_string(), weight: 70 },
- ];
- let canoes = assign_canoes(&cub_pack);
- assert!(canoes.len() == 2);
- if let Canoe::Duet(ref b0, ref b1) = canoes[0] {
- assert!(b0.name == "Kevin");
- assert!(b0.weight == 70);
- assert!(b1.name == "Billy");
- assert!(b1.weight == 80);
- } else {
- panic!("");
- }
- if let Canoe::Solo(ref boy) = canoes[1] {
- assert!(boy.name == "Timmy");
- assert!(boy.weight == 70);
- } else {
- panic!("");
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement