From d845ce64a4eef2e1205d88603e708377e697845d Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Mon, 16 Nov 2020 21:12:09 -0500 Subject: [PATCH] Implement merge sort that counts inversions --- src/main.rs | 71 +++++++++++++++-------------------------------- src/merge_sort.rs | 48 ++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 48 deletions(-) create mode 100644 src/merge_sort.rs diff --git a/src/main.rs b/src/main.rs index 17baac0..d521d24 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,57 +1,32 @@ -use std::clone::Clone; -use std::cmp::PartialOrd; -use std::marker::Copy; +mod merge_sort; +use crate::merge_sort::merge_sort_inversions; +use std::fs::File; +use std::io; +use std::io::{BufRead, BufReader, Error, ErrorKind}; use std::vec::Vec; -fn merge(a: Vec, b: Vec) -> Vec { - let mut r = vec![]; - let mut i = 0; - let mut j = 0; - - while i < a.len() && j < b.len() { - if a[i] < b[j] { - r.push(a[i]); - i += 1; - } else { - r.push(b[j]); - j += 1; - } +fn read_to_vector(path: &str) -> Result, io::Error> { + let file = File::open(path)?; + let br = BufReader::new(file); + let mut v = Vec::new(); + for line in br.lines() { + let line = line?; + let n = line + .trim() + .parse() + .map_err(|e| Error::new(ErrorKind::InvalidData, e))?; + v.push(n); } - - while i < a.len() { - r.push(a[i]); - i += 1; - } - - while j < b.len() { - r.push(b[j]); - j += 1; - } - - return r; + Ok(v) } -fn merge_sort(v: Vec) -> Vec { - if v.len() <= 1 { - return v; - } - let i = v.len() / 2; - let a = merge_sort((&v[..i]).to_vec()); - let b = merge_sort((&v[i..]).to_vec()); - let r = merge(a, b); - return r; -} - -fn mult_bin(a: i64, b: i64) -> i64 { - return a * b; +fn c1a2() { + let vec = read_to_vector("data/week_2_assignment_2.txt").unwrap(); + let (_sorted, inversions) = merge_sort_inversions(vec); + // println!("{:?}", sorted.len()); + println!("course 1 assignment 2: {:?}", inversions); } fn main() { - println!("Hello, world!"); - let l = vec![4, 2, 1, 3]; - let l = merge_sort(l); - println!("{:?}", l); - - let r = mult_bin(42, 21); - println!("{:?}", r); + c1a2(); } diff --git a/src/merge_sort.rs b/src/merge_sort.rs new file mode 100644 index 0000000..0adb3a9 --- /dev/null +++ b/src/merge_sort.rs @@ -0,0 +1,48 @@ +use std::clone::Clone; +use std::cmp::PartialOrd; + +fn merge_count_inversions( + a: Vec, + b: Vec, +) -> (Vec, usize) { + let mut r = vec![]; + let mut i = 0; + let mut j = 0; + let mut inversions = 0; + + while i < a.len() && j < b.len() { + if a[i] < b[j] { + r.push(a[i]); + i += 1; + } else { + r.push(b[j]); + j += 1; + inversions += a.len() - i; + } + } + + while i < a.len() { + r.push(a[i]); + i += 1; + } + + while j < b.len() { + r.push(b[j]); + j += 1; + } + + return (r, inversions); +} + +pub fn merge_sort_inversions( + v: Vec, +) -> (Vec, usize) { + if v.len() <= 1 { + return (v, 0); + } + let i = v.len() / 2; + let (a, n) = merge_sort_inversions((&v[..i]).to_vec()); + let (b, m) = merge_sort_inversions((&v[i..]).to_vec()); + let (r, p) = merge_count_inversions(a, b); + return (r, n + m + p); +}