Finish course 3 week 1

master
Felix Martin 2021-02-02 14:26:50 -05:00
parent b69713fb5e
commit a13fae6ceb
6 changed files with 226 additions and 164 deletions

View File

@ -4,31 +4,32 @@ struct MinHeap<T> {
}
fn parent_index(index: usize) -> usize {
(index + 1) / 2 - 1
(index + 1) / 2 - 1
}
fn child_indices(index: usize) -> (usize, usize) {
((index + 1) * 2 - 1, (index + 1) * 2 + 1 - 1)
((index + 1) * 2 - 1, (index + 1) * 2 + 1 - 1)
}
impl<T: std::cmp::PartialOrd> MinHeap<T> {
fn new() -> Self {
Self { nodes: Vec::with_capacity(128) }
Self {
nodes: Vec::with_capacity(128),
}
}
fn smaller_than_parent(&self, index: usize) -> bool {
if index == 0 {
false
} else {
self.nodes[index] < self.nodes[parent_index(index)]
}
if index == 0 {
false
} else {
self.nodes[index] < self.nodes[parent_index(index)]
}
}
fn bubble_up(&mut self, index: usize) -> usize {
let parent_index = parent_index(index);
self.nodes.swap(index, parent_index);
parent_index
let parent_index = parent_index(index);
self.nodes.swap(index, parent_index);
parent_index
}
fn insert(&mut self, e: T) -> () {
@ -37,57 +38,57 @@ impl<T: std::cmp::PartialOrd> MinHeap<T> {
let mut bubble_index = last;
while self.smaller_than_parent(bubble_index) {
bubble_index = self.bubble_up(bubble_index);
bubble_index = self.bubble_up(bubble_index);
}
}
fn greater_than_children(&self, index: usize) -> bool {
let length = self.nodes.len();
let (left_index, right_index) = child_indices(index);
if left_index < length && self.nodes[index] > self.nodes[left_index] {
true
} else if right_index < length && self.nodes[index] > self.nodes[right_index] {
true
} else {
false
}
let length = self.nodes.len();
let (left_index, right_index) = child_indices(index);
if left_index < length && self.nodes[index] > self.nodes[left_index] {
true
} else if right_index < length && self.nodes[index] > self.nodes[right_index] {
true
} else {
false
}
}
fn bubble_down(&mut self, index: usize) -> usize {
let length = self.nodes.len();
let (left_index, right_index) = child_indices(index);
let mut target_index = index;
let length = self.nodes.len();
let (left_index, right_index) = child_indices(index);
let mut target_index = index;
if left_index < length && self.nodes[target_index] > self.nodes[left_index] {
target_index = left_index;
}
if left_index < length && self.nodes[target_index] > self.nodes[left_index] {
target_index = left_index;
}
if right_index < length && self.nodes[right_index] < self.nodes[target_index] {
target_index = right_index;
}
self.nodes.swap(index, target_index);
target_index
if right_index < length && self.nodes[right_index] < self.nodes[target_index] {
target_index = right_index;
}
self.nodes.swap(index, target_index);
target_index
}
fn extract_min(&mut self) -> T {
if self.nodes.len() == 0 {
panic!("Cannot extract key from empty heap");
}
if self.nodes.len() == 0 {
panic!("Cannot extract key from empty heap");
}
let mut bubble_index = 0;
let last = self.nodes.len() - 1;
self.nodes.swap(bubble_index, last);
let result = self.nodes.pop().unwrap();
let mut bubble_index = 0;
let last = self.nodes.len() - 1;
self.nodes.swap(bubble_index, last);
let result = self.nodes.pop().unwrap();
while self.greater_than_children(bubble_index) {
bubble_index = self.bubble_down(bubble_index);
}
while self.greater_than_children(bubble_index) {
bubble_index = self.bubble_down(bubble_index);
}
result
result
}
fn size(&self) -> usize {
self.nodes.len()
self.nodes.len()
}
}
@ -95,32 +96,32 @@ pub fn heap(v: &Vec<i64>) -> i64 {
let mut hl: MinHeap<i64> = MinHeap::new();
let mut hh: MinHeap<i64> = MinHeap::new();
let mut iter = v.into_iter();
let mut iter = v.into_iter();
let mut current_median = *iter.next().unwrap();
let mut median_sum = current_median;
hl.insert(-current_median);
for e in iter {
let e = *e;
if e < current_median {
hl.insert(-e);
} else {
hh.insert(e);
}
let e = *e;
if e < current_median {
hl.insert(-e);
} else {
hh.insert(e);
}
while hl.size() < hh.size() {
let e = hh.extract_min();
hl.insert(-e);
}
while hl.size() < hh.size() {
let e = hh.extract_min();
hl.insert(-e);
}
while hl.size() > hh.size() + 1 {
let e = -hl.extract_min();
hh.insert(e);
}
while hl.size() > hh.size() + 1 {
let e = -hl.extract_min();
hh.insert(e);
}
current_median = -hl.extract_min();
median_sum = (median_sum + current_median) % 10000;
hl.insert(-current_median);
current_median = -hl.extract_min();
median_sum = (median_sum + current_median) % 10000;
hl.insert(-current_median);
}
median_sum

View File

@ -2,47 +2,47 @@ use std::cmp::Ordering;
#[derive(Debug)]
pub struct Job {
pub weight: i64,
pub length: i64,
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;
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;
}
for job in jobs {
let completion_time = time + job.length;
weighted_completion_time += completion_time * job.weight;
time += job.length;
}
weighted_completion_time
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)
}
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()
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)
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)
jobs.sort_by(compare_2);
weighted_completion_time(&jobs)
}

View File

@ -1,25 +1,24 @@
mod dijkstra;
mod heap;
mod jobs;
mod merge_sort;
mod min_cut;
mod prims;
mod quick_sort;
mod ssc;
mod util;
mod two_sum;
mod jobs;
mod prims;
mod util;
use std::cmp::min;
use crate::dijkstra::dijkstra;
use crate::heap::heap;
use crate::jobs::{jobs_1, jobs_2};
use crate::merge_sort::merge_sort_inversions;
use crate::min_cut::min_cut;
use crate::prims::prims;
use crate::quick_sort::quick_sort;
use crate::ssc::ssc;
use crate::two_sum::find_two_sums;
use crate::jobs::{jobs_1, jobs_2};
use crate::prims::prims;
use std::cmp::min;
#[allow(dead_code)]
fn c1a2() {
@ -86,20 +85,25 @@ fn c2a4() {
let mut v = util::read_to_vector("data/c2a4.txt").unwrap();
let r = find_two_sums(&mut v);
println!("c2a4={:?}", r);
// c2a4=427
// c2a4=427
}
#[allow(dead_code)]
fn c3a1() {
let mut jobs = util::read_jobs("data/c3a1_jobs.txt").unwrap();
let r1 = jobs_1(&mut jobs);
let r2 = jobs_2(&mut jobs);
// belongs to c3a1
let mut jobs = util::read_jobs("data/c3a1_jobs.txt").unwrap();
let r1 = jobs_1(&mut jobs);
let r2 = jobs_2(&mut jobs);
let g = util::read_weighted_graph("data/c3a1_edges.txt").unwrap();
let r3 = prims(&g);
println!("r1 = {}; r2 = {}; r3 = {} ", r1, r2, r3);
let g = util::read_weighted_graph("data/c3a1_edges.txt").unwrap();
let r3 = prims(&g);
// r1 = 69119377652; r2 = 67311454237; r3 = -3612829
}
println!("r1 = {}; r2 = {}; r3 = {} ", r1, r2, r3);
// r1 = 69119377652; r2 != 67311454237;
#[allow(dead_code)]
fn c3a2() {
println!("let's go");
}
fn main() {
@ -110,5 +114,6 @@ fn main() {
// c2a2();
// c2a3();
// c2a4();
c3a1();
// c3a1();
c3a2();
}

View File

@ -1,14 +1,49 @@
#[derive(Debug, Clone)]
use std::collections::HashSet;
#[derive(Debug, Clone, Copy)]
pub struct Edge {
pub node_a: u32,
pub node_b: u32,
pub weight: u32,
pub weight: i32,
pub source_id: usize,
pub target_id: usize,
}
pub type WeightedGraph = Vec<Edge>;
#[derive(Debug, Clone)]
pub struct Vertex {
pub id: usize,
pub edges: Vec<Edge>,
}
pub fn prims(graph: &WeightedGraph) -> usize {
println!("{:?}", graph);
42
}
pub type WeightedGraph = Vec<Vertex>;
pub fn prims(graph: &WeightedGraph) -> i32 {
let mut x: HashSet<usize> = HashSet::new();
let mut t = Vec::new();
x.insert(0);
while x.len() != graph.len() {
let mut min_edge = Edge {
weight: i32::MAX,
source_id: 0,
target_id: 0,
};
for node_id in &x {
for edge in &graph[*node_id].edges {
if edge.weight < min_edge.weight && !x.contains(&edge.target_id) {
min_edge = *edge;
}
}
}
x.insert(min_edge.target_id);
t.push(min_edge);
}
let mut result = 0;
for edge in &t {
result += edge.weight;
}
result
}

View File

@ -1,44 +1,49 @@
use std::collections::HashSet;
fn binary_search<T: std::cmp::PartialOrd>(min_i: usize, max_i: usize, xs: &Vec<T>, needle: T) -> usize {
if min_i >= max_i {
return max_i;
}
let half_i = min_i + (max_i - min_i) / 2;
fn binary_search<T: std::cmp::PartialOrd>(
min_i: usize,
max_i: usize,
xs: &Vec<T>,
needle: T,
) -> usize {
if min_i >= max_i {
return max_i;
}
let half_i = min_i + (max_i - min_i) / 2;
if xs[half_i] == needle {
return half_i;
}
if xs[half_i] == needle {
return half_i;
}
if needle < xs[half_i] {
binary_search(min_i, half_i - 1, &xs, needle)
} else {
binary_search(half_i + 1, max_i, xs, needle)
}
if needle < xs[half_i] {
binary_search(min_i, half_i - 1, &xs, needle)
} else {
binary_search(half_i + 1, max_i, xs, needle)
}
}
pub fn find_two_sums(xs: &mut Vec<i64>) -> usize {
let mut found: HashSet<i64> = HashSet::new();
const T_MIN: i64 = -10000;
const T_MAX: i64 = 10000;
xs.sort();
let mut found: HashSet<i64> = HashSet::new();
const T_MIN: i64 = -10000;
const T_MAX: i64 = 10000;
xs.sort();
for i in 0..xs.len() {
let a: i64 = xs[i];
let b_min = T_MIN - a;
let b_max = T_MAX - a;
let i_min = binary_search(i + 1, xs.len() - 1, &xs, b_min);
let i_max = binary_search(i + 1, xs.len() - 1, &xs, b_max);
for i in 0..xs.len() {
let a: i64 = xs[i];
let b_min = T_MIN - a;
let b_max = T_MAX - a;
let i_min = binary_search(i + 1, xs.len() - 1, &xs, b_min);
let i_max = binary_search(i + 1, xs.len() - 1, &xs, b_max);
for i in i_min..(i_max + 1) {
let b = xs[i];
let t = a + b;
if T_MIN <= t && t <= T_MAX {
found.insert(t);
}
}
}
found.len()
for i in i_min..(i_max + 1) {
let b = xs[i];
let t = a + b;
if T_MIN <= t && t <= T_MAX {
found.insert(t);
}
}
}
found.len()
}
// fn two_sum(t: i64, xs: &Vec<i64>, ys: &HashSet<i64>) -> bool {
@ -63,7 +68,7 @@ pub fn find_two_sums(xs: &mut Vec<i64>) -> usize {
// for t in -10000..10001 {
// if t % 10 == 0 {
// println!("{:?}", t);
// }
// }
// if two_sum(t, &xs_min, &xs_max_set) {
// r += 1
// }

View File

@ -1,9 +1,9 @@
use crate::jobs::{Job, Jobs};
use crate::prims::{Edge, Vertex, WeightedGraph};
use std::fs::File;
use std::io;
use std::io::{BufRead, BufReader, Error, ErrorKind};
use std::vec::Vec;
use crate::jobs::{Job, Jobs};
use crate::prims::{WeightedGraph, Edge};
#[derive(Debug, Clone)]
pub struct Graph {
@ -163,28 +163,44 @@ pub fn read_jobs(path: &str) -> Result<Jobs, io::Error> {
}
pub fn read_weighted_graph(path: &str) -> Result<WeightedGraph, io::Error> {
let g = Vec::new();
let mut g = Vec::new();
let file = File::open(path)?;
let br = BufReader::new(file);
let mut lines = br.lines();
let line = lines.next().unwrap().unwrap();
let mut nodes = line.split_whitespace();
let n_nodes: usize = nodes.next().unwrap().parse().unwrap();
let n_edges: usize = nodes.next().unwrap().parse().unwrap();
let mut fields = line.split_whitespace();
let n_nodes: usize = fields.next().unwrap().parse().unwrap();
// let n_edges: usize = fields.next().unwrap().parse().unwrap();
println!("{:?} {:?}", n_nodes, n_edges);
// lines.next();
// for line in lines {
// let line = line?;
// let mut nodes = line.split_whitespace();
// let weight = nodes.next().unwrap().parse().unwrap();
// let length = nodes.next().unwrap().parse().unwrap();
// let job = Job {
// weight: weight,
// length: length,
// };
// jobs.push(job);
// }
for i in 0..n_nodes {
let node = Vertex {
id: i,
edges: vec![],
};
g.push(node);
}
for line in lines {
let line = line?;
let mut nodes = line.split_whitespace();
let id_a: usize = nodes.next().unwrap().parse::<usize>().unwrap() - 1;
let id_b: usize = nodes.next().unwrap().parse::<usize>().unwrap() - 1;
let weight = nodes.next().unwrap().parse().unwrap();
let edge = Edge {
weight: weight,
source_id: id_a,
target_id: id_b,
};
g[id_a].edges.push(edge);
let edge = Edge {
weight: weight,
source_id: id_b,
target_id: id_a,
};
g[id_b].edges.push(edge);
}
Ok(g)
}