Try to improve the performance of the two-sum assignment

This commit is contained in:
2020-12-23 15:19:49 -05:00
parent 77828d0eb9
commit 8bbb196819
7 changed files with 87 additions and 25 deletions

1
.gitignore vendored
View File

@@ -16,3 +16,4 @@ algos.sublime-workspace
# Data for the exercises. Some files are big so don't check them in. # Data for the exercises. Some files are big so don't check them in.
data/c2a4.txt data/c2a4.txt
data/c2a4.back.txt

View File

@@ -7,4 +7,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
rand = "0.7.3" rand = "0.7.3"
[profile.release]
opt-level = 3

BIN
misc/prims_mst_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

BIN
misc/prims_mst_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 KiB

BIN
misc/prims_mst_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 KiB

View File

@@ -16,6 +16,7 @@ use crate::quick_sort::quick_sort;
use crate::ssc::ssc; use crate::ssc::ssc;
use crate::two_sum::find_two_sums; use crate::two_sum::find_two_sums;
#[allow(dead_code)] #[allow(dead_code)]
fn c1a2() { fn c1a2() {
let vec = util::read_to_vector("data/c1a2.txt").unwrap(); let vec = util::read_to_vector("data/c1a2.txt").unwrap();
@@ -78,9 +79,10 @@ fn c2a3() {
#[allow(dead_code)] #[allow(dead_code)]
fn c2a4() { fn c2a4() {
let v = util::read_to_vector("data/c2a4.txt").unwrap(); let mut v = util::read_to_vector("data/c2a4.txt").unwrap();
let r = find_two_sums(v); let r = find_two_sums(&mut v);
println!("c2a4={:?}", r); println!("c2a4={:?}", r);
// c2a4=427
} }
#[allow(dead_code)] #[allow(dead_code)]
@@ -95,6 +97,6 @@ fn main() {
// c2a1(); // c2a1();
// c2a2(); // c2a2();
// c2a3(); // c2a3();
// c2a4(); c2a4();
c3a1(); // c3a1();
} }

View File

@@ -1,32 +1,88 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::iter::FromIterator; // use std::iter::FromIterator;
fn two_sum(t: i64, xs: &Vec<i64>, ys: &HashSet<i64>) -> bool { // fn two_sum(t: i64, xs: &Vec<i64>, ys: &HashSet<i64>) -> bool {
for &x in xs { // for &x in xs {
let y = t - x; // let y = t - x;
if x != y && ys.contains(&y) { // if x != y && ys.contains(&y) {
return true; // return true;
// }
// }
// false
// }
fn binary_search(min_i: usize, xs: &Vec<i64>, needle: i64) -> usize {
let mut width = xs.len() - min_i;
let mut i = min_i + width / 2;
if xs[i] == needle {
return i;
}
while width > 1 {
width = width / 2;
if xs[i] < needle {
i = i + width;
} else if xs[i] > needle {
i = i - width;
} else {
return i;
} }
} }
false
0
} }
pub fn find_two_sums(xs: Vec<i64>) -> usize { // fn add_two_sums_for_limits(i: usize, xs: &Vec<i64>) -> () {
// let t_min = -10000;
// let t_max = 10000;
// let a: i64 = xs[i];
// let b_min = t_min - a;
// let b_max = t_max - a;
// println!("{:?} {:?}", b_min, b_max);
let mut xs_min: Vec<i64> = xs.to_vec(); // }
xs_min.retain(|&i| i < 0);
let mut xs_max: Vec<i64> = xs.to_vec(); pub fn find_two_sums(xs: &mut Vec<i64>) -> usize {
xs_max.retain(|&i| i >= 0); let found: HashSet<i64> = HashSet::new();
let xs_max_set: HashSet<i64> = HashSet::from_iter(xs_max); const T_MIN: i64 = -3;
const T_MAX: i64 = 3;
let mut r: usize = 0; xs.sort();
for t in -10000..10001 { for i in 0..1 {
if two_sum(t, &xs_min, &xs_max_set) { // add_two_sums_for_limits(i, &xs);
r += 1 let a: i64 = xs[i];
} let b_min = T_MIN - a;
let b_max = T_MAX - a;
println!("a={} b_min={} b_max={}", a, b_min, b_max);
let i_min = binary_search(i, &xs, b_min);
let i_max = binary_search(i, &xs, b_max);
println!("{:?} {:?}", i_min, i_max);
} }
r found.len()
} }
// pub fn find_two_sums(xs: Vec<i64>) -> usize {
// let mut xs_min: Vec<i64> = xs.to_vec();
// xs_min.retain(|&i| i < 0);
// let mut xs_max: Vec<i64> = xs.to_vec();
// xs_max.retain(|&i| i >= 0);
// let xs_max_set: HashSet<i64> = HashSet::from_iter(xs_max);
// let mut r: usize = 0;
// for t in -10000..10001 {
// if t % 10 == 0 {
// println!("{:?}", t);
// }
// if two_sum(t, &xs_min, &xs_max_set) {
// r += 1
// }
// }
// r
// }