From 510694f2e219254a149bb78d8f5f52a7344e014c Mon Sep 17 00:00:00 2001 From: Rowan Torbitzky-Lane Date: Mon, 14 Apr 2025 00:19:56 -0500 Subject: [PATCH] These need to be on main --- src/instructions/mod.rs | 30 ++++ src/instructions/vector.rs | 329 ++++++++++++++++++++++++++++++++++++- 2 files changed, 357 insertions(+), 2 deletions(-) diff --git a/src/instructions/mod.rs b/src/instructions/mod.rs index 321789f..342296c 100644 --- a/src/instructions/mod.rs +++ b/src/instructions/mod.rs @@ -364,14 +364,19 @@ pub fn string_instructions() -> Vec { string_rest, string_but_last, string_drop, + string_drop_last, string_length, string_reverse, string_push_all, string_make_empty, string_is_empty, string_contains, + string_contains_vector_non_contiguous, + string_contains_vector_contiguous, string_index_of, + string_index_of_vector, string_occurrences_of, + string_occurrences_of_vector, string_set_nth, string_replace, // common.rs @@ -418,14 +423,19 @@ pub fn vector_int_instructions() -> Vec { vector_int_rest, vector_int_but_last, vector_int_drop, + vector_int_drop_last, vector_int_length, vector_int_reverse, vector_int_push_all, vector_int_make_empty, vector_int_is_empty, vector_int_contains, + vector_int_contains_vector_non_contiguous, + vector_int_contains_vector_contiguous, vector_int_index_of, + vector_int_index_of_vector, vector_int_occurrences_of, + vector_int_occurrences_of_vector, vector_int_set_nth, vector_int_replace, // common.rs @@ -451,14 +461,19 @@ pub fn vector_float_instructions() -> Vec { vector_float_rest, vector_float_but_last, vector_float_drop, + vector_float_drop_last, vector_float_length, vector_float_reverse, vector_float_push_all, vector_float_make_empty, vector_float_is_empty, vector_float_contains, + vector_float_contains_vector_non_contiguous, + vector_float_contains_vector_contiguous, vector_float_index_of, + vector_float_index_of_vector, vector_float_occurrences_of, + vector_float_occurrences_of_vector, vector_float_set_nth, vector_float_replace, // common.rs @@ -484,13 +499,18 @@ pub fn vector_string_instructions() -> Vec { vector_string_rest, vector_string_but_last, vector_string_drop, + vector_string_drop_last, vector_string_length, vector_string_reverse, vector_string_make_empty, vector_string_is_empty, vector_string_contains, + vector_string_contains_vector_non_contiguous, + vector_string_contains_vector_contiguous, vector_string_index_of, + vector_string_index_of_vector, vector_string_occurrences_of, + vector_string_occurrences_of_vector, vector_string_set_nth, vector_string_replace, // common.rs @@ -516,14 +536,19 @@ pub fn vector_boolean_instructions() -> Vec { vector_boolean_rest, vector_boolean_but_last, vector_boolean_drop, + vector_boolean_drop_last, vector_boolean_length, vector_boolean_reverse, vector_boolean_push_all, vector_boolean_make_empty, vector_boolean_is_empty, vector_boolean_contains, + vector_boolean_contains_vector_non_contiguous, + vector_boolean_contains_vector_contiguous, vector_boolean_index_of, + vector_boolean_index_of_vector, vector_boolean_occurrences_of, + vector_boolean_occurrences_of_vector, vector_boolean_set_nth, vector_boolean_replace, // common.rs @@ -549,14 +574,19 @@ pub fn vector_char_instructions() -> Vec { vector_char_rest, vector_char_but_last, vector_char_drop, + vector_char_drop_last, vector_char_length, vector_char_reverse, vector_char_push_all, vector_char_make_empty, vector_char_is_empty, vector_char_contains, + vector_char_contains_vector_non_contiguous, + vector_char_contains_vector_contiguous, vector_char_index_of, + vector_char_index_of_vector, vector_char_occurrences_of, + vector_char_occurrences_of_vector, vector_char_set_nth, vector_char_replace, // common.rs diff --git a/src/instructions/vector.rs b/src/instructions/vector.rs index c2ebc4a..a076245 100644 --- a/src/instructions/vector.rs +++ b/src/instructions/vector.rs @@ -1,5 +1,7 @@ use crate::push::state::PushState; use rust_decimal::Decimal; +use std::collections::HashSet; +use std::hash::Hash; /// Generates an index between 0 and length. Takes abs(num) and then mods it by length. fn bounded_idx(num: i128, length: usize) -> usize { @@ -589,6 +591,70 @@ make_instruction_aux!( make_instruction_aux!(vector_char, vector_char, _drop, Vec, 1, int, 1, i128); make_instruction_aux!(string, string, _drop, Vec, 1, int, 1, i128); +pub fn _drop_last(vals: Vec>, auxs: Vec) -> Option> +where + T: Clone, +{ + let mut ret_vec = vals[0].clone(); + let rvlen = ret_vec.len(); //Ret_Vec Len + if ret_vec.is_empty() { + return None; + } + ret_vec.drain((rvlen - (auxs[0].abs().min(rvlen as i128) as usize))..rvlen); + Some(ret_vec) +} +make_instruction_aux!( + vector_int, + vector_int, + _drop_last, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_float, + vector_float, + _drop_last, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_string, + vector_string, + _drop_last, + Vec>, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_boolean, + vector_boolean, + _drop_last, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!( + vector_char, + vector_char, + _drop_last, + Vec, + 1, + int, + 1, + i128 +); +make_instruction_aux!(string, string, _drop_last, Vec, 1, int, 1, i128); + /// Takes the length of a vector. pub fn _length(vals: Vec>) -> Option { Some(vals[0].len() as i128) @@ -694,6 +760,104 @@ make_instruction_aux!( make_instruction_aux!(vector_char, boolean, _contains, Vec, 1, char, 1, char); make_instruction_aux!(string, boolean, _contains, Vec, 1, char, 1, char); +/// Checks if a vector contains another vector in no order. True if does, false otherwise +pub fn _contains_vector_non_contiguous(vals: Vec>) -> Option +where + T: Eq + Hash, +{ + let hashset: HashSet<&T> = vals[1].iter().collect(); + Some(vals[0].iter().all(|x| hashset.contains(x))) +} +make_instruction_clone!( + vector_int, + boolean, + _contains_vector_non_contiguous, + Vec, + 2 +); +make_instruction_clone!( + vector_float, + boolean, + _contains_vector_non_contiguous, + Vec, + 2 +); +make_instruction_clone!( + vector_string, + boolean, + _contains_vector_non_contiguous, + Vec>, + 2 +); +make_instruction_clone!( + vector_boolean, + boolean, + _contains_vector_non_contiguous, + Vec, + 2 +); +make_instruction_clone!( + vector_char, + boolean, + _contains_vector_non_contiguous, + Vec, + 2 +); +make_instruction_clone!( + string, + boolean, + _contains_vector_non_contiguous, + Vec, + 2 +); + +/// Checks if a vector contains another contiguous vector. True if does, false otherwise +pub fn _contains_vector_contiguous(vals: Vec>) -> Option +where + T: Eq, +{ + if vals[0].is_empty() { + return Some(true); // would argue the empty set is in everything + } + Some(vals[1].windows(vals[0].len()).any(|x| x == vals[0])) +} +make_instruction_clone!( + vector_int, + boolean, + _contains_vector_contiguous, + Vec, + 2 +); +make_instruction_clone!( + vector_float, + boolean, + _contains_vector_contiguous, + Vec, + 2 +); +make_instruction_clone!( + vector_string, + boolean, + _contains_vector_contiguous, + Vec>, + 2 +); +make_instruction_clone!( + vector_boolean, + boolean, + _contains_vector_contiguous, + Vec, + 2 +); +make_instruction_clone!( + vector_char, + boolean, + _contains_vector_contiguous, + Vec, + 2 +); +make_instruction_clone!(string, boolean, _contains_vector_contiguous, Vec, 2); + /// Returns the index of a primitive in a vector, pushes result to int stack pub fn _index_of(vals: Vec>, auxs: Vec) -> Option where @@ -740,17 +904,36 @@ make_instruction_aux!( make_instruction_aux!(vector_char, int, _index_of, Vec, 1, char, 1, char); make_instruction_aux!(string, int, _index_of, Vec, 1, char, 1, char); +/// Finds the index of the start of one vector in another. Searches in contiguous space. +pub fn _index_of_vector(vals: Vec>) -> Option +where + T: Eq, +{ + if vals[0].is_empty() { + return Some(0); + } + if let Some(val) = vals[1].windows(vals[0].len()).position(|x| x == vals[0]) { + return Some(val as i128); + } + Some(-1) +} +make_instruction_clone!(vector_int, int, _index_of_vector, Vec, 2); +make_instruction_clone!(vector_float, int, _index_of_vector, Vec, 2); +make_instruction_clone!(vector_string, int, _index_of_vector, Vec>, 2); +make_instruction_clone!(vector_boolean, int, _index_of_vector, Vec, 2); +make_instruction_clone!(vector_char, int, _index_of_vector, Vec, 2); +make_instruction_clone!(string, int, _index_of_vector, Vec, 2); + /// Counts the amount of a primitive in a vector pub fn _occurrences_of(vals: Vec>, auxs: Vec) -> Option where T: Clone + Eq, { - let temp_aux = &auxs[0]; Some( vals[0] .clone() .into_iter() - .filter(|r| r == temp_aux) + .filter(|r| r == &auxs[0]) .count() as i128, ) } @@ -797,6 +980,41 @@ make_instruction_aux!( ); make_instruction_aux!(string, int, _occurrences_of, Vec, 1, char, 1, char); +pub fn _occurrences_of_vector(vals: Vec>) -> Option +where + T: Eq + Hash, +{ + if vals[0].is_empty() { + return Some(0); + } + Some( + vals[1] + .windows(vals[0].len()) + .filter(|x| x == &vals[0]) + .count() as i128, + ) +} +make_instruction_clone!(vector_int, int, _occurrences_of_vector, Vec, 2); +make_instruction_clone!(vector_float, int, _occurrences_of_vector, Vec, 2); +make_instruction_clone!( + vector_string, + int, + _occurrences_of_vector, + Vec>, + 2 +); +make_instruction_clone!(vector_boolean, int, _occurrences_of_vector, Vec, 2); +make_instruction_clone!(vector_char, int, _occurrences_of_vector, Vec, 2); +make_instruction_clone!(string, int, _occurrences_of_vector, Vec, 2); + +/// Pushes the values inside a vector to a primitive stack. +pub fn _parse_to_prim(vals: Vec>) -> Option> +where + T: Clone, +{ + Some(vals[0].clone()) +} + /// Sets the nth index in a vector. N from the int stack. pub fn _set_nth(vals: Vec>, aux0: Vec, aux1: Vec) -> Option> where @@ -1267,6 +1485,32 @@ mod tests { assert_eq!(vec![empty_vec], test_state.vector_int); } + #[test] + fn vector_drop_last_test() { + let mut test_state = EMPTY_STATE; + let empty_vec: Vec = vec![]; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5]]; + test_state.int = vec![2]; + vector_int_drop_last(&mut test_state); + assert_eq!(vec![vec![0, 1, 2, 3]], test_state.vector_int); + + test_state.vector_int = vec![vec![0]]; + test_state.int = vec![2]; + vector_int_drop_last(&mut test_state); + assert_eq!(vec![empty_vec.clone()], test_state.vector_int); + + test_state.vector_int = vec![vec![1, 2, 3, 4]]; + test_state.int = vec![4]; + vector_int_drop_last(&mut test_state); + assert_eq!(vec![empty_vec.clone()], test_state.vector_int); + + test_state.vector_int = vec![empty_vec.clone()]; + test_state.int = vec![30]; + vector_int_drop_last(&mut test_state); + assert_eq!(vec![empty_vec], test_state.vector_int); + } + #[test] fn vector_length_test() { let mut test_state = EMPTY_STATE; @@ -1345,6 +1589,49 @@ mod tests { assert_eq!(vec![false], test_state.boolean); } + #[test] + fn contains_vector_non_contiguous_test() { + let mut test_state = EMPTY_STATE; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 6, 7, 8], vec![0, 2, 3, 4, 5, 1]]; + vector_int_contains_vector_non_contiguous(&mut test_state); + assert_eq!(vec![true], test_state.boolean); + test_state.boolean.clear(); + + test_state.vector_int = vec![vec![], vec![]]; + vector_int_contains_vector_non_contiguous(&mut test_state); + assert_eq!(vec![true], test_state.boolean); + test_state.boolean.clear(); + + test_state.vector_int = vec![vec![1, 2, 3], vec![0, 1, 2, 3, 4, 5]]; + vector_int_contains_vector_non_contiguous(&mut test_state); + assert_eq!(vec![false], test_state.boolean); + } + + #[test] + fn contains_vector_contiguous() { + let mut test_state = EMPTY_STATE; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 6, 7, 8], vec![0, 1, 2, 3, 4, 5]]; + vector_int_contains_vector_contiguous(&mut test_state); + assert_eq!(vec![true], test_state.boolean); + test_state.boolean.clear(); + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 6, 7, 8], vec![0, 2, 3, 4, 5, 1]]; + vector_int_contains_vector_contiguous(&mut test_state); + assert_eq!(vec![false], test_state.boolean); + test_state.boolean.clear(); + + test_state.vector_int = vec![vec![], vec![]]; + vector_int_contains_vector_contiguous(&mut test_state); + assert_eq!(vec![true], test_state.boolean); + test_state.boolean.clear(); + + test_state.vector_int = vec![vec![1, 2, 3], vec![0, 1, 2, 3, 4, 5]]; + vector_int_contains_vector_contiguous(&mut test_state); + assert_eq!(vec![false], test_state.boolean); + } + #[test] fn index_of_test() { let mut test_state = EMPTY_STATE; @@ -1365,6 +1652,25 @@ mod tests { assert_eq!(vec![-1], test_state.int); } + #[test] + fn index_of_vector_test() { + let mut test_state = EMPTY_STATE; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5], vec![1, 2, 3]]; + vector_int_index_of_vector(&mut test_state); + assert_eq!(vec![1], test_state.int); + test_state.int.clear(); + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5], vec![10]]; + vector_int_index_of_vector(&mut test_state); + assert_eq!(vec![-1], test_state.int); + test_state.int.clear(); + + test_state.vector_int = vec![vec![], vec![]]; + vector_int_index_of_vector(&mut test_state); + assert_eq!(vec![0], test_state.int); + } + #[test] fn occurrences_of_test() { let mut test_state = EMPTY_STATE; @@ -1385,6 +1691,25 @@ mod tests { assert_eq!(vec![0], test_state.int); } + #[test] + fn occurrences_of_vector_test() { + let mut test_state = EMPTY_STATE; + + test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 1, 2], vec![1, 2]]; + vector_int_occurrences_of_vector(&mut test_state); + assert_eq!(vec![2], test_state.int); + test_state.int.clear(); + + test_state.vector_int = vec![vec![1], vec![1, 2, 3, 2, 2, 5], vec![2, 2]]; + vector_int_occurrences_of_vector(&mut test_state); + assert_eq!(vec![1], test_state.int); + test_state.int.clear(); + + test_state.vector_int = vec![vec![], vec![]]; + vector_int_occurrences_of_vector(&mut test_state); + assert_eq!(vec![0], test_state.int); + } + #[test] fn set_nth_test() { let mut test_state = EMPTY_STATE; -- 2.47.2