Assuming I have an array N ← 0 0 0 1 1 1 0 0 1
, how can I apply the scan \
to achieve the array 0 0 0 1 2 3 0 0 1
?
+\N
gives me 0 0 0 1 2 3 3 3 4
which is not what I want.
+\¨⊆⍨N
gives me | 1 2 3 | 1 |
which is closer, but then I lose the positions.
Is there a way to carry the original values in the scan and multiply, or perhaps a better way?
How about m←{s-⌈\(s←+\⍵)×2>/0,⍵}
, seems about twice as fast?
cmpx 'h r' 'm r'
h r → 1.1E¯5 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
m r → 4.2E¯6 | -63% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
There are a couple of options here. Your original idea can be adapted easily using \.
Alternatively, for a short (but inefficient O(n^2)) solution, ⊥⍨¨,\
works.
For a more efficient but longer solution, I adapted https://aplcart.info/?q=cumulative%20sum#
There's probably something even better but I'm too bad to find it but it's left as an exercise to the reader ;)
f ← {⍵\∊+\¨⊆⍨⍵}
g ← ⊥⍨¨,\
h ← {+\⍵-a\¯2-/0,(a←1,2≠/⍵)/+\¯1↓0,⍵}
f 0 0 0 1 1 1 0 0 1
0 0 0 1 2 3 0 0 1
r ← ? 1e3 ⍴ 2 ⍝ random boolean array
(∧/2≡/f,⍥⊆g,⍥⊆h)r ⍝ they're all the same
1
]runtime -c 'f r' 'g r' 'h r'
f r → 3.6E¯5 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
g r → 7.7E¯5 | +111% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
h r → 7.3E¯6 | -80% ⎕⎕⎕⎕
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With