-
Notifications
You must be signed in to change notification settings - Fork 382
feat: add array range and reverse functions #7159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,74 @@ use crate::runtime::is_unconstrained; | |||||||||||||||||||||||||||||||||||||||||||||||
| mod check_shuffle; | ||||||||||||||||||||||||||||||||||||||||||||||||
| mod quicksort; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| /// Creates a new array by applying a function to each index. | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// This is a utility function to create arrays with custom initialization. | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// Example: | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// ```noir | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// fn main() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// let arr = std::array::from_fn(5, |i| i * 2); | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// assert(arr == [0, 2, 4, 6, 8]); | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// } | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// ``` | ||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn from_fn<T>(size: u32, f: fn(u32) -> T) -> [T] { | ||||||||||||||||||||||||||||||||||||||||||||||||
| let mut result = []; | ||||||||||||||||||||||||||||||||||||||||||||||||
| for i in 0..size { | ||||||||||||||||||||||||||||||||||||||||||||||||
| result.push(f(i)); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| result | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| /// Creates a new array containing numbers from 0 to N-1. | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// This is a utility function to create arrays from ranges. | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// Example: | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// ```noir | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// fn main() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// let arr = std::array::range(5); | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// assert(arr == [0, 1, 2, 3, 4]); | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// } | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// ``` | ||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn range(size: u32) -> [u32] { | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above: it returns a slice with a dynamic length. Should be removed in favour of renaming |
||||||||||||||||||||||||||||||||||||||||||||||||
| from_fn(size, |i| i) | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| /// Creates a new fixed-size array by applying a function to each index. | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// This is a utility function to create arrays with custom initialization. | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// The size parameter can be less than N to partially fill the array. | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// Example: | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// ```noir | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// fn main() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// let arr: [Field; 5] = std::array::from_fn_fixed(5, |i| i as Field); | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// assert(arr == [0, 1, 2, 3, 4]); | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// } | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// ``` | ||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn from_fn_fixed<T, let N: u32>(size: u32, f: fn(u32) -> T) -> [T; N] { | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert(size <= N, "Size cannot exceed array capacity N"); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| let mut result = [crate::mem::zeroed(); N]; | ||||||||||||||||||||||||||||||||||||||||||||||||
| for i in 0..size { | ||||||||||||||||||||||||||||||||||||||||||||||||
| result[i] = f(i); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+46
to
+57
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
It's simpler this way, I don't think the partial fill was a good suggestion on my part, sorry. |
||||||||||||||||||||||||||||||||||||||||||||||||
| result | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| /// Creates a new fixed-size array containing numbers from 0 to size-1. | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// This is a utility function to create arrays from ranges. | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// The size parameter can be less than N to partially fill the array. | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// Example: | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// ```noir | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// fn main() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// let arr: [u32; 5] = std::array::range_fixed(5); | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// assert(arr == [0, 1, 2, 3, 4]); | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// } | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// ``` | ||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn range_fixed<let N: u32>(size: u32) -> [u32; N] { | ||||||||||||||||||||||||||||||||||||||||||||||||
| from_fn_fixed(size, |i| i) | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+63
to
+74
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| impl<T, let N: u32> [T; N] { | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// Returns the length of this array. | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -136,6 +204,28 @@ impl<T, let N: u32> [T; N] { | |||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| ret | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| /// Returns a new array with elements in reverse order. | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// The original array remains untouched. | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// Example: | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// ```noir | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// fn main() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// let arr = [1, 2, 3]; | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// let reversed = arr.reverse(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// assert(reversed == [3, 2, 1]); | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// } | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// ``` | ||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn reverse(self) -> Self { | ||||||||||||||||||||||||||||||||||||||||||||||||
| let mut result = self; | ||||||||||||||||||||||||||||||||||||||||||||||||
| let len = self.len(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| for i in 0..(len / 2) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| let temp = result[i]; | ||||||||||||||||||||||||||||||||||||||||||||||||
| result[i] = result[len - 1 - i]; | ||||||||||||||||||||||||||||||||||||||||||||||||
| result[len - 1 - i] = temp; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| result | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| impl<T, let N: u32> [T; N] | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -157,7 +247,7 @@ where | |||||||||||||||||||||||||||||||||||||||||||||||
| /// } | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// ``` | ||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn sort(self) -> Self { | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.sort_via(|a, b| a <= b) | ||||||||||||||||||||||||||||||||||||||||||||||||
| self.sort_via(|a: T, b: T| a <= b) | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -184,10 +274,11 @@ where | |||||||||||||||||||||||||||||||||||||||||||||||
| /// } | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// ``` | ||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn sort_via<Env>(self, ordering: fn[Env](T, T) -> bool) -> Self { | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// Safety: `sorted` array is checked to be: | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// a. a permutation of `input`'s elements | ||||||||||||||||||||||||||||||||||||||||||||||||
| /// b. satisfying the predicate `ordering` | ||||||||||||||||||||||||||||||||||||||||||||||||
| unsafe { | ||||||||||||||||||||||||||||||||||||||||||||||||
| /*@safety: `sorted` array is checked to be: | ||||||||||||||||||||||||||||||||||||||||||||||||
| a. a permutation of `input`'s elements | ||||||||||||||||||||||||||||||||||||||||||||||||
| b. satisfying the predicate `ordering` | ||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||
| let sorted = quicksort::quicksort(self, ordering); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if !is_unconstrained() { | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -232,4 +323,63 @@ mod test { | |||||||||||||||||||||||||||||||||||||||||||||||
| fn map_empty() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq([].map(|x| x + 1), []); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||||||||||||||||||||
| fn test_range() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| let arr = range(5); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(arr, [0_u32, 1_u32, 2_u32, 3_u32, 4_u32]); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| let empty = range(0); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(empty, []); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||||||||||||||||||||
| fn test_from_fn() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| let arr = from_fn(5, |i| i * 2); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(arr, [0_u32, 2_u32, 4_u32, 6_u32, 8_u32]); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| let field_arr = from_fn(3, |i| i as Field); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(field_arr, [0_Field, 1_Field, 2_Field]); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||||||||||||||||||||
| fn test_range_fixed() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| let arr: [u32; 5] = range_fixed(5); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(arr, [0_u32, 1_u32, 2_u32, 3_u32, 4_u32]); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // Partial filling test | ||||||||||||||||||||||||||||||||||||||||||||||||
| let arr2: [u32; 5] = range_fixed(3); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(arr2[0], 0_u32); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(arr2[1], 1_u32); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(arr2[2], 2_u32); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||||||||||||||||||||
| fn test_from_fn_fixed() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| let arr: [u32; 5] = from_fn_fixed(5, |i| i * 2); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(arr, [0_u32, 2_u32, 4_u32, 6_u32, 8_u32]); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // Test with Field type | ||||||||||||||||||||||||||||||||||||||||||||||||
| let field_arr: [Field; 3] = from_fn_fixed(3, |i| i as Field); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(field_arr, [0_Field, 1_Field, 2_Field]); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // Partial filling test | ||||||||||||||||||||||||||||||||||||||||||||||||
| let arr2: [u32; 5] = from_fn_fixed(3, |i| i * 3); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(arr2[0], 0_u32); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(arr2[1], 3_u32); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(arr2[2], 6_u32); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||||||||||||||||||||
| fn test_reverse() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| let arr = [1, 2, 3, 4, 5]; | ||||||||||||||||||||||||||||||||||||||||||||||||
| let reversed = arr.reverse(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(reversed, [5, 4, 3, 2, 1]); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| let empty: [Field; 0] = []; | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(empty.reverse(), []); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| let single = [1]; | ||||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq(single.reverse(), [1]); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function does not return an array, they return a slice. I suggest we remove it, and rename the
from_fn_fixedtofrom_fninstead.