## Solution
[Link](https://gist.github.com/richardliang/b56d1d687b3cacdb3954e55303c610e5)
## Approach
At a high level, I broke the problem down into 3 parts
1. First find `num_match`
2. Then identify the correct indexes each tuple should be
3. Lastly, shift elements and create new array
### 1. Finding num_match
Circom doesn't have any control flows and each signal can only be assigned once. So, I used an intermediate signal `sum[101]` to store the running sum. The 0th index stores a 0 and adds a match to the sum when IsEqual returns 1. Return the last index which will return the final `num_match`
Example tuple of 4 elements
`[(3,5), (4,6), (8,7), (3,8)] -> [0,1,1,1,2]`
### 2. Identifying where the correct index each tuple should be
This was a simple step, simply multiply the return values of IsEqual and the running sum from i+i to 101 which gives you where the correct index where match should be plus one (so we need to subtract 1 from the index later on)
Example
`[1,0,0,1] * [1,1,1,2] -> [1,0,0,2]`
### 3. Shift elements
This was the trickiest part, since Circom doesn't allow you to index into arrays with signals. I can't just do the naive way e.g. `out[i] <== in[index_plus_one[i] - 1]` since the value of index_plus_one[i] isn't known at compile time
Instead, Circom needs O(n) to iterate across the set of all possible index values for a single element. For each element in the index_plus_1 array (row), we first check if the element matches the ith element (column). If there is a match, we return the second value of the `in` tuple and accumulate it over `j` and returning the last value of the running sum. We need to do this accumulation for all 100 elements
Conceptually, we're looping through `j` to find where the matched index is and placing it in a new array element `i`
To save constraints:
1. I only stored the second value of the matched. This is because we already know that the first `num_match` elements will be equal to `match`.
2. I subtracted each element in index_plus_one by 1. So the nonmatches become `-1` which ensures that it doesn't match any `i`th element
Example:
```
in: [(3,5), (4,6), (8,7), (3,8)]
0 1 2 3
-------
0 | 1 0 0 0
-1| 0 0 0 0
-1| 0 0 0 0
1 | 0 1 0 0
-------
1 1 0 0
[5 8 0 0]
```
To achieve the final solution of the filtered array, I populate `out` by checking if tuple_2 is matched, and outputting the `match` in the first element, and outputting the corresponding tuple_2 value in the second element.
This was a fun puzzle! Overall, made me appreciate lower level circuit writing a lot more, despite the limitations of Circom