Skip to content

Commit

Permalink
feat: dedup for arrays (#174)
Browse files Browse the repository at this point in the history
<!--- Please provide a general summary of your changes in the title
above -->

## Pull Request type

<!-- Please try to limit your pull request to one type; submit multiple
pull requests if needed. -->

Please check the type of change your PR introduces:

- [ ] Bugfix
- [x] Feature
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (no functional changes, no API changes)
- [ ] Build-related changes
- [ ] Documentation content changes
- [ ] Other (please describe):

## What is the current behavior?

<!-- Please describe the current behavior that you are modifying, or
link to a relevant issue. -->

Issue Number: N/A

## What is the new behavior?

<!-- Please describe the behavior or changes that are being added by
this PR. -->

-
-
-

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this does introduce a breaking change, please describe the
impact and migration path for existing applications below. -->

## Other information

<!-- Any other information that is important to this PR, such as
screenshots of how the component looks before and after the change. -->

---------

Co-authored-by: gaetbout <[email protected]>
Co-authored-by: Lucas @ StarkWare <[email protected]>
  • Loading branch information
3 people authored Sep 18, 2023
1 parent e863e5b commit fa3f7e7
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/data_structures/src/array_ext.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ trait ArrayTraitExt<T> {
fn index_of_max<impl TPartialEq: PartialEq<T>, impl TPartialOrd: PartialOrd<T>>(
self: @Array<T>
) -> Option<usize>;
fn dedup<impl TPartialEq: PartialEq<T>>(self: @Array<T>) -> Array<T>;
}

trait SpanTraitExt<T> {
Expand All @@ -43,6 +44,7 @@ trait SpanTraitExt<T> {
fn index_of_max<impl TPartialEq: PartialEq<T>, impl TPartialOrd: PartialOrd<T>>(
self: Span<T>
) -> Option<usize>;
fn dedup<impl TPartialEq: PartialEq<T>>(self: Span<T>) -> Array<T>;
}

impl ArrayImpl<T, impl TCopy: Copy<T>, impl TDrop: Drop<T>> of ArrayTraitExt<T> {
Expand Down Expand Up @@ -135,6 +137,10 @@ impl ArrayImpl<T, impl TCopy: Copy<T>, impl TDrop: Drop<T>> of ArrayTraitExt<T>
) -> Option<usize> {
self.span().index_of_max()
}

fn dedup<impl TPartialEq: PartialEq<T>>(mut self: @Array<T>) -> Array<T> {
self.span().dedup()
}
}

impl SpanImpl<T, impl TCopy: Copy<T>, impl TDrop: Drop<T>> of SpanTraitExt<T> {
Expand Down Expand Up @@ -354,4 +360,29 @@ impl SpanImpl<T, impl TCopy: Copy<T>, impl TDrop: Drop<T>> of SpanTraitExt<T> {
index += 1;
}
}

fn dedup<impl TPartialEq: PartialEq<T>>(mut self: Span<T>) -> Array<T> {
if self.len() == 0 {
return array![];
}

let mut last_value = self.pop_front().unwrap();
let mut ret = array![*last_value];

loop {
match self.pop_front() {
Option::Some(v) => {
if (last_value != v) {
last_value = v;
ret.append(*v);
};
},
Option::None => {
break;
}
};
};

ret
}
}
105 changes: 105 additions & 0 deletions src/data_structures/src/tests/array_ext_test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,111 @@ use array::{ArrayTrait, SpanTrait};

use alexandria_data_structures::array_ext::{ArrayTraitExt, SpanTraitExt};

// dedup

#[test]
#[available_gas(2000000)]
fn dedup_all_different() {
let mut destination = array![1, 2, 3, 4];
let new_arr = destination.dedup();
let len = new_arr.len();

assert(*new_arr[0] == 1, 'Should be 1');
assert(*new_arr[1] == 2, 'Should be 2');
assert(*new_arr[2] == 3, 'Should be 3');
assert(*new_arr[3] == 4, 'Should be 4');
assert(new_arr.len() == 4, 'Len should be 4');
}

#[test]
#[available_gas(2000000)]
fn dedup_one_match() {
let mut destination = array![1, 2, 2, 3, 4];
let new_arr = destination.dedup();
let len = new_arr.len();

assert(*new_arr[0] == 1, 'Should be 1');
assert(*new_arr[1] == 2, 'Should be 2');
assert(*new_arr[2] == 3, 'Should be 3');
assert(*new_arr[3] == 4, 'Should be 4');
assert(new_arr.len() == 4, 'Len should be 4');
}

#[test]
#[available_gas(2000000)]
fn dedup_two_matches() {
let mut destination = array![1, 2, 2, 3, 4, 4];
let new_arr = destination.dedup();
let len = new_arr.len();

assert(*new_arr[0] == 1, 'Should be 1');
assert(*new_arr[1] == 2, 'Should be 2');
assert(*new_arr[2] == 3, 'Should be 3');
assert(*new_arr[3] == 4, 'Should be 4');
assert(new_arr.len() == 4, 'Len should be 4');
}

#[test]
#[available_gas(2000000)]
fn dedup_one_match_more() {
let mut destination = array![1, 2, 2, 2, 3, 4, 4];
let new_arr = destination.dedup();
let len = new_arr.len();

assert(*new_arr[0] == 1, 'Should be 1');
assert(*new_arr[1] == 2, 'Should be 2');
assert(*new_arr[2] == 3, 'Should be 3');
assert(*new_arr[3] == 4, 'Should be 4');
assert(new_arr.len() == 4, 'Len should be 4');
}

#[test]
#[available_gas(2000000)]
fn dedup_all_same() {
let mut destination = array![2, 2, 2, 2];
let new_arr = destination.dedup();
let len = new_arr.len();

assert(*new_arr[0] == 2, 'Should be 2');
assert(new_arr.len() == 1, 'Len should be 1');
}

#[test]
#[available_gas(2000000)]
fn dedup_one_elem() {
let mut destination = array![2];
let new_arr = destination.dedup();
let len = new_arr.len();

assert(*new_arr[0] == 2, 'Should be 2');
assert(new_arr.len() == 1, 'Len should be 1');
}

#[test]
#[available_gas(2000000)]
fn dedup_no_elem() {
let mut destination = ArrayTrait::<felt252>::new();
let new_arr = destination.dedup();
let len = new_arr.len();
assert(new_arr.len() == 0, 'Len should be 0');
}

#[test]
#[available_gas(2000000)]
fn dedup_multiple_duplicates_same() {
let mut destination = array![1, 1, 3, 4, 3, 3, 3, 4, 2, 2];
let new_arr = destination.dedup();
let len = new_arr.len();

assert(new_arr.len() == 6, 'Len should be 6');
assert(*new_arr[0] == 1, 'Should be 1');
assert(*new_arr[1] == 3, 'Should be 3');
assert(*new_arr[2] == 4, 'Should be 4');
assert(*new_arr[3] == 3, 'Should be 3');
assert(*new_arr[4] == 4, 'Should be 4');
assert(*new_arr[5] == 2, 'Should be 2');
}

// append_all

#[test]
Expand Down

0 comments on commit fa3f7e7

Please sign in to comment.