« first day (1045 days earlier)      last day (1593 days later) » 

12:08 AM
      cmpx '⊣\⍳1000' '⊣ LTRScan ⍳1000'
  ⊣\⍳1000         → 1.3E¯2 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  ⊣ LTRScan ⍳1000 → 6.6E¯4 | -95% ⎕⎕
      cmpx ',\⍳1000' ', LTRScan ⍳1000'
  ,\⍳1000         → 7.3E¯2 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  , LTRScan ⍳1000 → 7.5E¯4 | -99%
      (,\⍳1000) ≡ , LTRScan ⍳1000
1
Can I be sure that I implemented LTRScan properly?
 
12:52 AM
@Bubbler I'm fairly sure what I just came up with now is correct: {r⊣⍺⍺{r,←⊂⍵ ⍺⍺⍨⊃⌽r}¨1↓⍵⊣r←⊂⊃⍵} Does yours give the same result as mine for non-commutative functions?
 
@Adám Probably yes:
      arr←?1000/1000
      (|{r⊣⍺⍺{r,←⊂⍵ ⍺⍺⍨⊃⌽r}¨1↓⍵⊣r←⊂⊃⍵} arr) ≡ | LTRScan arr
1
But I'm wondering how I'd handle higher-rank arrays...
 
@Bubbler Use the rank operator.
 
@Bubbler I think it's significant that you faster than ,\. I expected that to be optimised...
 
@Bubbler Can we see your code? :-)
 
@Adám My version of LTRScan depends on SuffixScan, so it does have a few unnecessary ops. Anyway here it goes:
 SuffixScan←{
     ⍝ ⍺⍺ SuffixScan (A B C) → (A ⍺⍺ B ⍺⍺ C) (B ⍺⍺ C) C
     f←⍺⍺
     res←⊆⊢/⍵
     dummy←{tmp←⍺ f ⍵ ⋄ res,←⊆tmp ⋄ tmp}/⍵
     ⌽res
 }
 LTRScan←{
     ⍝ ⍺⍺ LTRScan A B C → A (A ⍺⍺ B) ((A ⍺⍺ B) ⍺⍺ C)
     ⌽⍺⍺⍨SuffixScan⌽⍵
 }
 
1:08 AM
@Bubbler ‽ That doesn't look right.
 
@Adám I wasn't actually sure. Then both should be I guess?
 
@Bubbler That'd be my first guess. Also, I don't understand what you're trying to do in dummy←{tmp←⍺ f ⍵ ⋄ res,←⊆tmp ⋄ tmp}/⍵
What's wrong with dummy←{res,←⊂⍺ f ⍵}/⍵?
 
@Adám That reminds me of the weirdness of modified assignment, but doesn't it break for e.g. f←,?
 
@Bubbler Why would the function matter?
 
@Adám Because the results don't agree:
      (,\⍳1000) ≡ , LTRScan2 ⍳1000
0
 
1:20 AM
@Bubbler Oh, hold on, then I think your operator isn't correct.
 
1:34 AM
@Adám dummy←{⊃res,←⊂⍺ f ⍵}/⍵ does work. I was worried about the fact that {...}/x y z was giving x f ⊂y f z instead of x f y f z.
 
@Bubbler Ah, now I get what you're doing. I'm tired. Btw, you can use res,∘⊂←
@Bubbler Another trick: You don't need to name f←⍺⍺ as you can simply pass ⍺⍺ on: dummy←⍺⍺{res,∘⊂←⍺ ⍺⍺ ⍵}/⍵
@Bubbler Why | here?
 
@Adám Just randomly picked an asymmetric function.
 
oh
@Bubbler So by inserting and simplifying and golfing, our solutions become quite similar:
{ r⊣⍺⍺{ r,←⊂⍵ ⍺⍺⍨⊃⌽r}¨1↓⍵⊣r←⊂⊃⍵}
{⌽r⊣⍺⍺{⊃r,←⊂⍺ ⍺⍺  ⍵ }/ ⌽⍵⊣r←⊂⊃⍵}
 
Interesting.
 
Uh, I think there's a typo there somewhere.
Here we go:
{r⊣⍺⍺⍨{ r,←⊂⍵ ⍺⍺⊃⌽r}¨1↓⍵⊣r←⊂⊃⍵}
{r⊣⍺⍺⍨{⊃r,←⊂⍺ ⍺⍺ ⍵ }/ ⌽⍵⊣r←⊂⊃⍵}
@H.PWiz It is in 18.0
@Bubbler 18.0 timings:
      A←{r⊣⍺⍺⍨{ r,←⊂⍵ ⍺⍺⊃⌽r}¨1↓⍵⊣r←⊂⊃⍵}
      B←{r⊣⍺⍺⍨{⊃r,←⊂⍺ ⍺⍺ ⍵ }/ ⌽⍵⊣r←⊂⊃⍵}

      arr←?1000/1000
      cmpx '|A arr' '|B arr'
  |A arr → 5.2E¯4 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  |B arr → 6.8E¯4 | +29% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕

      cmpx '-A⍳1000' '-B⍳1000'
  -A⍳1000 → 3.9E¯4 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  -B⍳1000 → 6.0E¯4 | +52% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕

      cmpx ',\⍳1000' ',A⍳1000' ',B⍳1000'
  ,\⍳1000 → 8.1E¯5 |    0% ⎕⎕⎕⎕
  ,A⍳1000 → 6.5E¯4 | +699% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
 
1:56 AM
Nice, so while we can't beat internally optimized ones, we can do much better for non-optimized ones.
(And yours is slightly faster)
Is ⊃⌽x special-cased btw?
 
(And yours is slightly shorter)
@Bubbler Yes.
 
That probably explains the difference.
 
Cool.
For higher-rank arrays, simply LTRScan⍤1 works like `\`, I guess?
And for f⍀ x, I could do ⍉f LTRScan⍤1 ⍉x (though might be slow)
 
 
6 hours later…
8:02 AM
Random fact about scan: `+\` is optimized only for scalar elements, not nested ones
      nested←1⍴¨⍳1000
      cmpx '∊+\nested' '+\∊nested'
  ∊+\nested → 1.8E¯2 |    0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  +\∊nested → 7.8E¯6 | -100%
(Btw I can't figure out how to type backslash in inline code...)
 
@Bubbler "``+\``"
 
+\
I guess I'm dumb.
 
9:15 AM
@Bubbler Nah, chat markdown is a bit strange. There are phrases that simply cannot be written as code.
@Bubbler Not just +\, even +/ isn't. There's not really any way to optimise it as each element is a pointer, so there's a whole lot of memory jumping going on there.
 
 
8 hours later…
5:44 PM
a cool random graph, courtesy of floating point numbers & optimization:
https://tio.run/##7dg/SgNBFMfxfk7x62JIkfUEEryCFwj2NoJNSGMRSMiIFmKt1fYqgo2Q3ORdZB2NtSQhbN7Mfh8DO7sDw@cNO392L8dXN@PrptFv2N3j@YXN7quwuR@l@uRkMFx/2Pylnyo2f55Y/BxYfJ8O@6v67LT6CYtvtrhND1Olmq5qi6@p4a8Tmz30Usc9W35ZrFPjcpEa10@jkJ5StiwMFoPFYO1U9E@ETmSZdaraLkiP9Bwmlktq2iVCATm4SkT7RciPfDy2BNm9GjRoX2jlMwmlLLBSDlB5Z0qOiZJfntziBA0aEyGHReSQwg7vExC78iay1HBeaYsmYMdRHY4ldyhBatVTHkiOOALThqQAioAAyQXCFM5kyXe2HfrjcJziWA4JEiSWSfY1jiH8JADD5w4/T4AUBREMGC0ZQOyJEISSCZtL03wD
 

« first day (1045 days earlier)      last day (1593 days later) »