commit 0dee5398929c1bc2852d0cb2e9ba53e649b83298
parent 13d0eac9f15815774bad57244e2d93e3cac54718
Author: ling0x <ling0x@users.noreply.github.com>
Date: Sun, 12 Apr 2026 03:03:13 +0100
tests
Diffstat:
4 files changed, 115 insertions(+), 66 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
@@ -5,6 +5,6 @@ edition = "2024"
[dependencies]
tracing = "*"
+tracing-subscriber = "*"
[dev-dependencies]
-tracing-subscriber = "*"
diff --git a/src/hash_table/two_sum.rs b/src/hash_table/two_sum.rs
@@ -1,3 +1,5 @@
+use std::collections::HashSet;
+
use tracing::info;
// 101ms, 2.37MB
@@ -38,12 +40,14 @@ pub fn two_sum_2(nums: Vec<i32>, target: i32) -> Vec<i32> {
}
// 86ms, 2.28MB
+// if I replace rposition with position it becomes 56ms, which means that
+// position is faster than rposition
pub fn two_sum_3(nums: Vec<i32>, target: i32) -> Vec<i32> {
for (i, x) in nums.iter().enumerate() {
let idx = nums
.iter()
.enumerate()
- .position(|(i2, y)| i2 != i && *y == target - x);
+ .rposition(|(i2, y)| i2 != i && *y == target - x);
if let Some(idx) = idx {
return Vec::from([i as i32, idx as i32]);
}
@@ -51,92 +55,105 @@ pub fn two_sum_3(nums: Vec<i32>, target: i32) -> Vec<i32> {
Vec::new()
}
-pub fn two_sums_3(nums: Vec<i32>, target: i32) -> Vec<i32> {
- let mut seen = Vec::<String>::new();
+// 27ms 2.22MB
+pub fn two_sum_4(nums: Vec<i32>, target: i32) -> Vec<i32> {
+ for (i, x) in nums.iter().enumerate() {
+ let i2 = nums.iter().position(|y| y == &(target - x));
+ if i2.is_some_and(|z| z != i) {
+ return vec![i as i32, i2.unwrap() as i32];
+ }
+ }
+ Vec::new()
+}
- for (i, x) in nums.iter().enumerate() {}
+pub fn two_sum_5(nums: Vec<i32>, target: i32) -> Vec<i32> {
todo!()
}
#[cfg(test)]
mod tests {
- use tracing::info;
-
- use crate::hash_table::two_sum::{two_sum_1, two_sum_2, two_sum_3};
- use crate::test_utils::benchmark::{init_benchmark_tracing, run_with_metrics};
+ use crate::hash_table::two_sum::{two_sum_1, two_sum_2, two_sum_3, two_sum_4};
+ use crate::test_utils::benchmark::{init_benchmark_tracing, run_and_assert_vec_any_order};
- fn assert_indices_any_order(mut actual: Vec<i32>, mut expected: Vec<i32>) {
- actual.sort_unstable();
- expected.sort_unstable();
- assert_eq!(actual, expected);
+ #[derive(Clone)]
+ struct TwoSumCase {
+ name: &'static str,
+ nums: Vec<i32>,
+ target: i32,
+ expected: Vec<i32>,
}
- #[test]
- // #[ignore]
- fn two_sum_1_test_1() {
- init_benchmark_tracing();
- let (result, _) = run_with_metrics("two_sum_1_test_1", || two_sum_1(vec![2, 7, 11, 15], 9));
- assert_indices_any_order(result, vec![0, 1]);
- }
- #[test]
- // #[ignore]
- fn two_sum_1_test_2() {
- init_benchmark_tracing();
- let (result, _) = run_with_metrics("two_sum_1_test_2", || two_sum_1(vec![3, 2, 3], 6));
- assert_indices_any_order(result, vec![0, 2]);
- }
- #[test]
- // #[ignore]
- fn two_sum_1_test_3() {
- init_benchmark_tracing();
- let (result, _) = run_with_metrics("two_sum_1_test_3", || two_sum_1(vec![3, 2, 4], 6));
- assert_indices_any_order(result, vec![1, 2]);
+ fn full_cases() -> Vec<TwoSumCase> {
+ vec![
+ TwoSumCase {
+ name: "case_1",
+ nums: vec![2, 7, 11, 15],
+ target: 9,
+ expected: vec![0, 1],
+ },
+ TwoSumCase {
+ name: "case_2",
+ nums: vec![3, 2, 3],
+ target: 6,
+ expected: vec![0, 2],
+ },
+ TwoSumCase {
+ name: "case_3",
+ nums: vec![3, 2, 4],
+ target: 6,
+ expected: vec![1, 2],
+ },
+ TwoSumCase {
+ name: "case_4",
+ nums: vec![-3, 4, 3, 90],
+ target: 0,
+ expected: vec![0, 2],
+ },
+ ]
}
- #[test]
- // #[ignore]
- fn two_sum_2_test_1() {
+ fn run_solver_cases(
+ solver_name: &str,
+ solver: fn(Vec<i32>, i32) -> Vec<i32>,
+ cases: Vec<TwoSumCase>,
+ ) {
init_benchmark_tracing();
- let (result, _) = run_with_metrics("two_sum_2_test_1", || two_sum_2(vec![2, 7, 11, 15], 9));
- assert_indices_any_order(result, vec![0, 1]);
+ for case in cases {
+ run_and_assert_vec_any_order(
+ &format!("{solver_name}_{}", case.name),
+ case.expected,
+ || solver(case.nums, case.target),
+ );
+ }
}
+
#[test]
- // #[ignore]
- fn two_sum_2_test_2() {
- init_benchmark_tracing();
- let (result, _) = run_with_metrics("two_sum_2_test_2", || two_sum_2(vec![3, 2, 3], 6));
- assert_indices_any_order(result, vec![0, 2]);
+ #[ignore]
+ fn two_sum_1_cases() {
+ run_solver_cases("two_sum_1", two_sum_1, full_cases());
}
+
#[test]
- // #[ignore]
- fn two_sum_2_test_3() {
- init_benchmark_tracing();
- let (result, _) = run_with_metrics("two_sum_2_test_3", || two_sum_2(vec![3, 2, 4], 6));
- assert_indices_any_order(result, vec![1, 2]);
+ #[ignore]
+ fn two_sum_2_cases() {
+ run_solver_cases("two_sum_2", two_sum_2, full_cases());
}
#[test]
- // #[ignore]
- fn two_sum_3_test_1() {
- init_benchmark_tracing();
- let (result, _) = run_with_metrics("two_sum_3_test_1", || two_sum_3(vec![2, 7, 11, 15], 9));
- info!("{result:?}");
- assert_indices_any_order(result, vec![0, 1]);
+ #[ignore]
+ fn two_sum_3_cases() {
+ run_solver_cases("two_sum_3", two_sum_3, full_cases());
}
+
#[test]
- // #[ignore]
- fn two_sum_3_test_2() {
- init_benchmark_tracing();
- let (result, _) = run_with_metrics("two_sum_3_test_2", || two_sum_3(vec![3, 2, 3], 6));
- info!("{result:?}");
- assert_indices_any_order(result, vec![0, 2]);
+ #[ignore]
+ fn two_sum_4_cases() {
+ run_solver_cases("two_sum_4", two_sum_4, full_cases());
}
+
#[test]
// #[ignore]
- fn two_sum_3_test_3() {
- init_benchmark_tracing();
- let (result, _) = run_with_metrics("two_sum_3_test_3", || two_sum_3(vec![3, 2, 4], 6));
- info!("{result:?}");
- assert_indices_any_order(result, vec![1, 2]);
+ fn two_sum_5_cases() {
+ run_solver_cases("two_sum_5", two_sum_5, full_cases());
}
}
diff --git a/src/main.rs b/src/main.rs
@@ -1,3 +1,15 @@
+use leetcode::hash_table::two_sum::two_sum_5;
+use tracing::info;
+use tracing_subscriber::fmt;
+
fn main() {
- println!("Cargo test all the leetcode cases");
+ fmt().with_target(false).compact().init();
+ info!("-----------------------");
+ two_sum_5(vec![2, 7, 11, 15], 9);
+ info!("-----------------------");
+ two_sum_5(vec![3, 2, 3], 6);
+ info!("-----------------------");
+ two_sum_5(vec![3, 2, 4], 6);
+ info!("-----------------------");
+ two_sum_5(vec![-3, 4, 3, 90], 0);
}
diff --git a/src/test_utils/benchmark.rs b/src/test_utils/benchmark.rs
@@ -1,4 +1,5 @@
use std::alloc::{GlobalAlloc, Layout, System};
+use std::fmt::Debug;
use std::sync::Once;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::{Duration, Instant};
@@ -97,3 +98,22 @@ where
(output, result)
}
+
+pub fn assert_vec_any_order<T>(mut actual: Vec<T>, mut expected: Vec<T>)
+where
+ T: Ord + Debug,
+{
+ actual.sort_unstable();
+ expected.sort_unstable();
+ assert_eq!(actual, expected);
+}
+
+pub fn run_and_assert_vec_any_order<T, F>(label: &str, expected: Vec<T>, test: F) -> BenchmarkResult
+where
+ T: Ord + Debug,
+ F: FnOnce() -> Vec<T>,
+{
+ let (actual, metrics) = run_with_metrics(label, test);
+ assert_vec_any_order(actual, expected);
+ metrics
+}