Ruud H.G. van Tol on Thu, 29 Dec 2022 18:45:09 +0100 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Re: veccount |
On 2022-12-29 15:16, Karim Belabas wrote:
* Ruud H.G. van Tol [2022-12-29 13:04]:? binary(92) %3 = [1, 0, 1, 1, 1, 0, 0] How to effectively transform that to [1,1,3,2] (run-lengths), and next to 3 (the number of different run-length values)? [...] a condensed way from binary(92) to 3 would already help,Something like /* assume v is a non-empty vector */ rlev(v) = { my(x = v[1], c = 1, L = List()); for (i = 2, #v, if (v[i] == x, c++, listput(L,c); x = v[i]; c = 1)); listput(L,c); #Set(L); } ? rlev(binary(92)) %2 = 3 ? setrand(1); v = vector(10^6, i, random(2)); ? rlev(v) time = 894 ms. %4 = 20 One can save a log factor by using a counting sort to replace the list L and final #Set(L): /* assume v is a non-empty vector */ rlev2(v) = { my(x = v[1], c = 1, w = vector(#v)); for (i = 2, #v, if (v[i] == x, c++, w[c] = 1; x = v[i]; c = 1)); w[c] = 1; hammingweight(w); } ? rlev2(v) time = 437 ms. %5 = 20
That led me to write it as: rlev3(v) = { my( w= vector(#v), p= 1 ); for(i= 2, #v, if(v[i] != v[i-1], w[i - p]= 1; p= i)); w[#v + 1 - p]= 1; hammingweight(w); } -- Ruud