expand vex array from [A,B,C] to [A,A,A,B,B,C,C] ?

   72   2   2
User Avatar
Member
158 posts
Joined: Feb. 2016
Offline
I have an array and I need to expand it by a given amount, by reusing its values for the new indices, so that each new value is inserted next to its source value.
Like in the title, say I want to expand it by 4, then I should get 2 new A, 1 new B, 1 new C, and the expanded array will be:
[A,A,A, B,B, C,C]

My code kind of works 'till the delta newArray-oldArray is <= of the size of the old array. After that threshold, the insert() function would append out-of-bounds-Zeroes for the rest of the loop.

i[]@array = {1,2,3,4,5};
int count;

for(int i=0; i<10; i++)
{
    count = i % len(i[]@array);
    insert(i[]@array,  count+=i , i[]@array[count]);
    
}
// return: [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]

Any idea how to make it work?
Thanks a lot!
Edited by Andr - Feb. 13, 2019 11:07:07

Attachments:
Q_array_expand.hiplc (116.6 KB)

User Avatar
Member
402 posts
Joined: June 2014
Offline
Hi Andr,

This was fun There are simpler approaches using a temporary array, but makes a nice challenge trying to do it without (it's possible that it would end up faster too, but how big an array we'd need in order to notice… I'm not sure).

Have a gander and see what you think:
// need to expand the array size by a variable amount, so that its original elements are repeated evenly
// original array [A,B,C], expanded by 4 should return: [A,A,A,B,B,C,C]

i[]@array = {1,2,3,4,5};

int expand_count = chi("expand");
int input_len = len(i[]@array);
int output_len = input_len + expand_count;
// vex may well optimize this for us, but still a good habit to
// resize an array only once if we know the desired array size in advance
// rather than call append() or insert() inside a loop
resize(i[]@array, output_len);

for(int i=input_len; i>0; i--)
{
    // we want to write out the i-th input value to the highest 'unwritten'
    // output index until i doesn't fit in our unwritten range 
    int inner_loop = output_len/i;
    for(int j=0; j<inner_loop; j++)
    {
        // write the i-th input value to the end of the unwritten portion
        // of the output array
        i[]@array[output_len-1] = i[]@array[i-1];
        // reduce the size of the unwritten portion
        output_len--;
    }
}

I haven't had a change to properly untangle what was up with your original code, but my first guess is that you were getting bitten by the data dependencies between ‘count’ and 'i@array' inside the loop.

Cheers!
Henry Dean
User Avatar
Member
158 posts
Joined: Feb. 2016
Offline
Hello Henry, thanks a lot for reviewing my code and for the nice tips.
Your approach is clever, and very exotic to me: I've never used nested loops in that fashion, where the two loops are mutually dependent.
After spending some time on it I think I start to understand the logic.

thanks again
  • Quick Links