From 9c9ad12863f8c88faf549d2fa991d9b8feb32c65 Mon Sep 17 00:00:00 2001 From: GideonBature Date: Sat, 26 Apr 2025 05:04:36 +0100 Subject: [PATCH] Implement search insert position in cairo --- .../search_insert_position/.tool-versions | 1 + .../scripts/search_insert_position/Scarb.lock | 6 ++ .../scripts/search_insert_position/Scarb.toml | 11 +++ .../search_insert_position/src/lib.cairo | 1 + .../src/search_insert_position.cairo | 31 +++++++ .../tests/test_search_insert_position.cairo | 80 +++++++++++++++++++ 6 files changed, 130 insertions(+) create mode 100644 examples/cairo/scripts/search_insert_position/.tool-versions create mode 100644 examples/cairo/scripts/search_insert_position/Scarb.lock create mode 100644 examples/cairo/scripts/search_insert_position/Scarb.toml create mode 100644 examples/cairo/scripts/search_insert_position/src/lib.cairo create mode 100644 examples/cairo/scripts/search_insert_position/src/search_insert_position.cairo create mode 100644 examples/cairo/scripts/search_insert_position/tests/test_search_insert_position.cairo diff --git a/examples/cairo/scripts/search_insert_position/.tool-versions b/examples/cairo/scripts/search_insert_position/.tool-versions new file mode 100644 index 0000000..fb22047 --- /dev/null +++ b/examples/cairo/scripts/search_insert_position/.tool-versions @@ -0,0 +1 @@ +scarb 2.11.2 diff --git a/examples/cairo/scripts/search_insert_position/Scarb.lock b/examples/cairo/scripts/search_insert_position/Scarb.lock new file mode 100644 index 0000000..5beae69 --- /dev/null +++ b/examples/cairo/scripts/search_insert_position/Scarb.lock @@ -0,0 +1,6 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "search_insert_position" +version = "0.1.0" diff --git a/examples/cairo/scripts/search_insert_position/Scarb.toml b/examples/cairo/scripts/search_insert_position/Scarb.toml new file mode 100644 index 0000000..9970964 --- /dev/null +++ b/examples/cairo/scripts/search_insert_position/Scarb.toml @@ -0,0 +1,11 @@ +[package] +name = "search_insert_position" +version = "0.1.0" +edition = "2024_07" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] + +[dev-dependencies] +cairo_test = "2.11.2" diff --git a/examples/cairo/scripts/search_insert_position/src/lib.cairo b/examples/cairo/scripts/search_insert_position/src/lib.cairo new file mode 100644 index 0000000..f08a096 --- /dev/null +++ b/examples/cairo/scripts/search_insert_position/src/lib.cairo @@ -0,0 +1 @@ +pub mod search_insert_position; diff --git a/examples/cairo/scripts/search_insert_position/src/search_insert_position.cairo b/examples/cairo/scripts/search_insert_position/src/search_insert_position.cairo new file mode 100644 index 0000000..a5d39e2 --- /dev/null +++ b/examples/cairo/scripts/search_insert_position/src/search_insert_position.cairo @@ -0,0 +1,31 @@ +/// Finds the index of `target` in a sorted array `nums`. +/// If `target` is not present, returns the index where it would be inserted. +/// +/// # Arguments +/// +/// * `nums` - A sorted array of distinct integers +/// * `target` - The value to search for +/// +/// # Returns +/// +/// * The index of `target` in `nums` if found, or the index where it would be inserted +pub fn search_insert_pos(nums: @Array, target: u32) -> u32 { + if nums.len() == 0 { + return 0; // Empty array case + } + + let mut left: u32 = 0; + let mut right: u32 = nums.len(); + + // Binary search with a more efficient condition + while left != right { + let mid = left + (right - left) / 2; + + if *nums.at(mid) < target { + left = mid + 1; // Search in right half + } else { + right = mid; // Search in left half or target found + } + } + left +} diff --git a/examples/cairo/scripts/search_insert_position/tests/test_search_insert_position.cairo b/examples/cairo/scripts/search_insert_position/tests/test_search_insert_position.cairo new file mode 100644 index 0000000..382a7cc --- /dev/null +++ b/examples/cairo/scripts/search_insert_position/tests/test_search_insert_position.cairo @@ -0,0 +1,80 @@ +use search_insert_position::search_insert_position::search_insert_pos; + +#[test] +fn test_target_found() { + let nums = array![1, 3, 5, 6]; + let target = 5; + assert(search_insert_pos(@nums, target) == 2, 'Target 5 should be at index 2'); +} + +#[test] +fn test_target_not_found_middle() { + let nums = array![1, 3, 5, 6]; + let target = 2; + assert(search_insert_pos(@nums, target) == 1, 'Target 2 should insert at 1'); +} + +#[test] +fn test_target_smaller_than_all() { + let nums = array![1, 3, 5, 6]; + let target = 0; + assert(search_insert_pos(@nums, target) == 0, 'Target 0 should insert at 0'); +} + +#[test] +fn test_target_larger_than_all() { + let nums = array![1, 3, 5, 6]; + let target = 7; + assert(search_insert_pos(@nums, target) == 4, 'Target 7 should insert at 4'); +} + +#[test] +fn test_empty_array() { + let nums = array![]; + let target = 5; + assert(search_insert_pos(@nums, target) == 0, 'Empty array should return 0'); +} + +#[test] +fn test_single_element() { + let nums = array![1]; + let target = 2; + assert(search_insert_pos(@nums, target) == 1, 'Target 2 after single elem 1'); +} + +#[test] +fn test_single_element_found() { + let nums = array![5]; + let target = 5; + assert(search_insert_pos(@nums, target) == 0, 'Target 5 equals single elem'); +} + +#[test] +fn test_single_element_smaller() { + let nums = array![5]; + let target = 3; + assert(search_insert_pos(@nums, target) == 0, 'Target 3 before single elem 5'); +} + +#[test] +fn test_large_array() { + let nums = array![1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]; + let target = 10; + assert(search_insert_pos(@nums, target) == 5, 'Target 10 in large array'); +} + +#[test] +fn test_edge_case_MAX() { + // Testing with u32::max value + let nums = array![1, 3, 5, 7]; + let target = 4294967295_u32; // u32::MAX + assert(search_insert_pos(@nums, target) == 4, 'u32::MAX should insert at end'); +} + +#[test] +fn test_edge_case_MIN() { + // Testing with u32::min value + let nums = array![1, 3, 5, 7]; + let target = 0_u32; // u32::MIN + assert(search_insert_pos(@nums, target) == 0, 'u32::MIN should insert at start'); +}