Use of Hospital Facilities, ACM/ICPC World Finals 1991, UVa212 rust solution

There are n (n≤10) operating rooms and m (m≤30) recovery rooms in the hospital. Each patient is first assigned to an operating room and then to a recovery room after surgery. The time from any operating room to any recovery room is t1, and the time to prepare an operating room and recovery room is t2 and t3 respectively (all operating rooms and recovery rooms are prepared at the beginning, and only after receiving a patient are needed Preparing for the next patient).
K patients (k ≤ 100) line up according to the order of the roster, and the operating room is opened on time at T o’clock. Whenever there are prepared operating rooms, the first patient enters the operating room with the lowest number. After surgery, the patient should immediately enter the recovery room with the lowest number. If multiple patients complete their operations at the same time, the patient who underwent surgery in the operating room with a smaller number will have priority to enter the recovery room with a smaller number. Entering ensures patients don’t have to wait in line for a recovery room.
Input the names, operation time and recovery time of n, m, T, t1, t2, t3, k and k patients to simulate this process.

Example:
enter

5 12 07 5 15 10 16
Jones
28 140
Smith
120 200
Thompson
23 75
Albright
19 82
Poucher
133 209
Comer
74 101
Perry
93 188
Page
111 223
Roggio
69 122
Brigham
42 79
Nute
22 71
Young
38 140
Bush
26 121
Cates
120 248
Johnson
86 181
White
92 140

output

 Patient Operating Room Recovery Room
 # Name Room # Begin End Bed # Begin End
 -------------------------------------------------- ----
 1 Jones 1 7:00 7:28 3 7:33 9:53
 2 Smith 2 7:00 9:00 1 9:05 12:25
 3 Thompson 3 7:00 7:23 2 7:28 8:43
 4 Albright 4 7:00 7:19 1 7:24 8:46
 5 Poucher 5 7:00 9:13 5 9:18 12:47
 6 Comer 4 7:34 8:48 4 8:53 10:34
 7 Perry 3 7:38 9:11 2 9:16 12:24
 8 Page 1 7:43 9:34 6 9:39 13:22
 9 Roggio 4 9:03 10:12 9 10:17 12:19
10 Brigham 2 9:15 9:57 8 10:02 11:21
11 Nute 3 9:26 9:48 7 9:53 11:04
12 Young 5 9:28 10:06 3 10:11 12:31
13 Bush 1 9:49 10:15 10 10:20 12:21
14 Cates 3 10:03 12:03 8 12:08 16:16
15 Johnson 2 10:12 11:38 4 11:43 14:44
16 White 5 10:21 11:53 7 11:58 14:18

Facility Utilization
Type # Minutes % Used
-----------------------
Room 1 165 29.68
Room 2 248 44.60
Room 3 258 46.40
Room 4 162 29.14
Room 5 263 47.30
Bed 1 282 50.72
Bed 2 263 47.30
Bed 3 280 50.36
Bed 4 282 50.72
Bed 5 209 37.59
Bed 6 223 40.11
Bed 7 211 37.95
Bed 8 327 58.81
Bed 9 122 21.94
Bed 10 121 21.76
Bed 11 0 0.00
Bed 12 0 0.00

solution:

use std::{<!-- -->cmp::Ordering, collections::BinaryHeap, io};
#[derive(Debug)]
struct Patient {<!-- -->
    id: usize,
    name: String,
    operation_time: usize,
    recovery_time: usize,
    room_id: usize,
    room_begin_time: usize,
    room_end_time: usize,
    bed_id: usize,
    bed_begin_time: usize,
    bed_end_time: usize,
}
#[derive(Debug, PartialEq, Eq)]
struct Room {<!-- -->
    id: usize,
    start_available_time: usize,
}
impl Ord for Room {<!-- -->
    fn cmp( & amp;self, other: & amp;Self) -> std::cmp::Ordering {<!-- -->
        if self.start_available_time != other.start_available_time {<!-- -->
            other.start_available_time.cmp( & self.start_available_time)
        } else {<!-- -->
            other.id.cmp(&self.id)
        }
    }
}
impl PartialOrd for Room {<!-- -->
    fn partial_cmp( & amp;self, other: & amp;Self) -> Option<Ordering> {<!-- -->
        Some(self.cmp(other))
    }
}

fn main() {<!-- -->
    let mut buf = String::new();
    io::stdin().read_line( & amp;mut buf).unwrap();
    let v: Vec<usize> = buf.split_whitespace().map(|e| e.parse().unwrap()).collect();
    let n = v[0];
    let m = v[1];
    let start_time = v[2] * 60;
    let t1 = v[3];
    let t2 = v[4];
    let t3 = v[5];
    let k = v[6];
    let mut rooms = BinaryHeap::new();
    for i in 0..n {<!-- -->
        let room = Room {<!-- -->
            id: i + 1,
            start_available_time: start_time,
        };
        rooms.push(room);
    }

    let mut patients: Vec<Patient> = vec![];
    for i in 0..k {<!-- -->
        let mut buf = String::new();
        io::stdin().read_line( & amp;mut buf).unwrap();
        let name = buf.trim().to_string();
        let mut buf = String::new();
        io::stdin().read_line( & amp;mut buf).unwrap();
        let t: Vec<usize> = buf.split_whitespace().map(|e| e.parse().unwrap()).collect();

        let patient = Patient {<!-- -->
            id: i + 1,
            name: name,
            operation_time: t[0],
            recovery_time: t[1],
            room_id: 0,
            room_begin_time: 0,
            room_end_time: 0,
            bed_id: 0,
            bed_begin_time: 0,
            bed_end_time: 0,
        };
        patients.push(patient);
    }
    let mut room_used_time: Vec<usize> = vec![0; n];
    for patient in patients.iter_mut() {<!-- -->
        let aroom = rooms.pop().unwrap();
        patient.room_id = aroom.id;
        patient.room_begin_time = aroom.start_available_time;
        patient.room_end_time = patient.room_begin_time + patient.operation_time;
        rooms.push(Room {<!-- -->
            id: aroom.id,
            start_available_time: patient.room_end_time + t2,
        });
        room_used_time[aroom.id - 1] + = patient.operation_time;
    }

    patients.sort_by(|a, b| {<!-- -->
        if a.room_end_time != b.room_end_time {<!-- -->
            a.room_end_time.cmp( & amp;b.room_end_time)
        } else {<!-- -->
            a.room_id.cmp( & amp;b.room_id)
        }
    });

    let mut beds: Vec<usize> = vec![start_time; m];
    let mut bed_used_time: Vec<usize> = vec![0; m];
    let mut final_time = start_time;
    for patient in patients.iter_mut() {<!-- -->
        for j in 0..m {<!-- -->
            if beds[j] <= patient.room_end_time {<!-- -->
                patient.bed_id = j + 1;
                patient.bed_begin_time = patient.room_end_time + t1;
                patient.bed_end_time = patient.bed_begin_time + patient.recovery_time;
                beds[j] = patient.bed_end_time + t3;
                bed_used_time[j] + = patient.recovery_time;
                final_time = final_time.max(patient.bed_end_time);
                break;
            }
        }
    }
    patients.sort_by(|a, b| a.id.cmp( & amp;b.id));
    println!("Patient Operating Room Recovery Room");
    println!(" # Name Room# Begin End Bed# Begin End");
    println!("------------------------------------------------ ---------");
    for i in patients.iter() {<!-- -->
        print!("{:2} {:<10}", i.id, i.name);
        print!(
            "{:2} {:2}:{:02} {:2}:{:02}",
            i.room_id,
            i.room_begin_time / 60,
            i.room_begin_time % 60,
            i.room_end_time / 60,
            i.room_end_time % 60
        );
        println!(
            "{:2} {:2}:{:02} {:2}:{:02}",
            i.bed_id,
            i.bed_begin_time / 60,
            i.bed_begin_time % 60,
            i.bed_end_time / 60,
            i.bed_end_time % 60
        );
    }
    println!();
    println!("Facility Utilization");
    println!("Type # Minutes % Used");
    println!("-------------------------");

    let all_time = final_time - start_time;
    for i in 0..n {<!-- -->
        println!(
            "Room {:2} {:4} {:5.2}",
            i+1,
            room_used_time[i],
            100.0 * room_used_time[i] as f64 / all_time as f64
        );
    }
    for i in 0..m {<!-- -->
        println!(
            "Bed {:2} {:4} {:5.2}",
            i+1,
            bed_used_time[i],
            100.0 * bed_used_time[i] as f64 / all_time as f64
        );
    }
}