« first day (2543 days earlier)      last day (104 days later) » 

1:00 PM
Welcome to APL Quest, 2023-2! Today's quest is Put It In Reverse:
> Write a function that:
• takes a scalar or vector left argument
• takes a scalar or vector right argument
• returns a Boolean result that is the same shape as the right argument where 1's mark the ends of occurrences of the left argument in the right argument
 
⍷ _U_ ⌽
(1∘-∘≢⊣)⌽⍷
 
Hehe. For the uninitiated, _U_←{⍺←{⍵ ⋄ ⍺⍺} ⋄ ⍵⍵⍣¯1⊢(⍵⍵ ⍺)⍺⍺(⍵⍵ ⍵)}
Btw, you don't need the first there.
 
I had ⌽⍤⍷⍥⌽, which is pretty much just Under in disguise
 
You don't need
 
oh, right
 
1:02 PM
At the actual competition, someone submitted this little gem: {1-≢⍺}⌽⍷ which is the same algorithm as @Richard's second one, but hybrid explicit-tacit — and shorter for it.
Anyone wants to speculate on the relative performance of these two ways?
 
under is slowest probably
rotate is perhaps faster than mirroring twice
 
I just realized I've never thought about what under does in the dyadic case
 
It is like Over.
So, I defined:
      _U_←{⍺←{⍵ ⋄ ⍺⍺} ⋄ ⍵⍵⍣¯1⊢(⍵⍵ ⍺)⍺⍺(⍵⍵ ⍵)}
      'cmpx'⎕CY'dfns'
      Under←⍷_U_⌽
      Minus←{1-≢⍺}⌽⍷
      Over←⌽⍷⍥⌽
      h←?1e6⍴10
      n←⍳5
      +/n⍷h
14
And then measured:
      cmpx'n Under h' 'n Minus h' 'n Over h'
  n Under h → 1.4E¯3 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  n Minus h → 1.3E¯3 | -12% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  n Over h  → 1.5E¯3 |  +2% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
 
Depends a lot on the size of the vector. Large vector mirroring might be faster , a lot of smal vectors shifting is faster ?
 
@Richard It isn't twice, but three times.
No, the important thing is the amount of data being change, as it all has to be rewritten no matter if we are reversing or rotating.
Assuming the left argument is small, its impact is negligible.
 
1:08 PM
ah, ok
 
But the huge right argument is likely to be 8, 16, 32, or even 64 times as much data as the equally large result.
Why?
 
bits versus characters
 
vs ints, but yes
 
Well, h was numbers here, but yes 1-byte numbers. Had they been bigger than 127 (I limited them to ≤ 10) then they would have been 2 bytes each.
In fact, they could even be 128 bits each, if they were complex or decimal floats.
 
are complex decimal floats 256 bits, or do complex numbers always use float64's?
 
1:14 PM
For now, complex are always two float64s jammed together.
In general, people that need complex, don't need (that) much precision.
I've been experimenting a bit with larger arguments of larger types, but the performance result tends to be about the same. Once, I got:
      (h n)×←0J1
      cmpx'n Under h' 'n Minus h' 'n Over h'
  n Under h → 1.6E¯1 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  n Minus h → 1.3E¯1 | -23% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  n Over h  → 1.5E¯1 |  -8% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
 
Why should the result be 0 with e.g. ,1 on the left and 1 on the right?
 
But I have my doubts about its validity. Under and Over should be completely equivalent, since the data processing drowns out the overhead.
@rabbitgrowth Because ,1 doesn't appear anywhere in 1.
Vectors contain scalars, but scalars do not contain vectors.
 
I see, that makes sense
      1⍷1
1
      1⍷,1
1
      (,1)⍷1
0
      (,1)⍷,1
1
 
If you want homework, go investigate if empty arrays appear in other (empty) arrays. What if the types don't match? Can you infer a rule for how works?
 
:)
wow, just tried, how nice
 
1:24 PM
lol, I spent a lot of time discussing this with Roger Hui.
 
'⎕←(2 2 ⍴ 2) ⍷ 3 3 ⍴ 2'
 
The bot is long gone, but you can install this.
 
Wouldn't you be unable to tell if thinks an empty array appears in another empty array, since the result is also an empty array?
 
how many possibllities to fit a small cube in large one :)
+/,(2 2 2 ⍴ 2) ⍷ (3 3 3 ⍴ 2)
 
@rabbitgrowth Correct.
Anyway, have a look at ⍷ follies if this subject interests you.
You have a week until 2023-3: Caesar Salad!
 
1:29 PM
oh, I remember this one, I had a nice solution but turned it quite ugly because I was forcing myself to make it tacit
 
next week!
 
@Adám That looks interesting, will give it a read. Thanks!
 
 
3 hours later…
5:00 PM
I'm looking at Project Euler #8 with `k` but looking at it in general from an array language point of view and also in general

https://projecteuler.net/problem=8

I was wondering: is there an approach for solving that makes sense that is not the naive approach with a sliding window and doing all the products?
A few thoughts I had on it:

* every product that has a 0 in it goes to 0 so the calculation does not have to happen, and there are a lot of 13-item windows with at least one 0 in them
* if i split the string of numbers on all zeroes I get a bunch of strings that I can work on in parallel
* then there also is an approach of intead of a sliding window and doing all products to take 13, do the product, then move 1 further, divide by the digit that is no longer in the considered digits and multiply again by the new digit
 
5:54 PM
Another thought to avoid sliding windows is maybe reshape into matrix of shape n 13 and then dropping or rotating data so rows become the windows.
Shifting by multiply divide might be ok, but division is typically considered slow. Know there's a string ?search algorithm that follows similar idea to produce the hash though can't remember details
 
@Silas that's a great point @ reshaping, I still need to learn thinking like that, ty
 
One thing is you can check the sum instead of the product
then it is just adding and subtraction instead of doing division
for all a, b, c, d : Nat. a ≥ c AND b ≥ d IMPLIES a × b ≥ c × d
 
6:21 PM
Welp that doesn't work.
 
 
3 hours later…
9:01 PM
@tosh There's a way to decompose any associative windowed operation into scans that take linear time, known as the van Herk/Gil-Werman algorithm in image processing. This article does something like it for min or max in q, but it overlaps the scans in a way that prevents it from working for other functions.
I did a tutorial that focuses on it in Singeli (jump to "Here, I wrote up a little prototype!"), and there's a version on bqncrate too.
 
9:45 PM
@Marshall ty for the pointer
 

« first day (2543 days earlier)      last day (104 days later) »