use std::cmp::Ordering;

#[derive(Debug)]
pub struct Job {
    pub weight: i64,
    pub length: i64,
}

pub type Jobs = Vec<Job>;

fn weighted_completion_time(jobs: &Jobs) -> i64 {
    let mut time = 0;
    let mut weighted_completion_time = 0;

    for job in jobs {
        let completion_time = time + job.length;
        weighted_completion_time += completion_time * job.weight;
        time += job.length;
    }

    weighted_completion_time
}

fn compare_1(a: &Job, b: &Job) -> Ordering {
    let da = a.weight - a.length;
    let db = b.weight - b.length;
    if da == db {
        b.weight.cmp(&a.weight)
    } else {
        db.cmp(&da)
    }
}

fn compare_2(a: &Job, b: &Job) -> Ordering {
    let da: f64 = a.weight as f64 / a.length as f64;
    let db: f64 = b.weight as f64 / b.length as f64;
    db.partial_cmp(&da).unwrap()
}

pub fn jobs_1(jobs: &mut Jobs) -> i64 {
    jobs.sort_by(compare_1);
    weighted_completion_time(&jobs)
}

pub fn jobs_2(jobs: &mut Jobs) -> i64 {
    jobs.sort_by(compare_2);
    weighted_completion_time(&jobs)
}
