Is there a better/nicer way?

APL-related discussions - a stream of APL consciousness.
Not sure where to start a discussion ? Here's the place to be
Forum rules
This forum is for discussing APL-related issues. If you think that the subject is off-topic, then the Chat forum is probably a better place for your thoughts !

Is there a better/nicer way?

Postby Veli-Matti on Fri Mar 26, 2021 12:48 pm

Sirs (and ladies, hopefully!),

I came across to a problem, in which I needed to create vector of vectors from the original vector rotating two successive items along the original, like
      rot 'ABCDEFGH'
BACDEFGH ACBDEFGH ABDCEFGH ABCEDFGH ABCDFEGH ABCDEGFH ABCDEFHG

After solving the problem with a rude code I was thinking if there would be a sneakier way to do the same (and of course being able to give the rotating window width as an argument would be a nice touch, too):
      3 rot 'ABCDEFGH'
CBADEFGH ADCBEFGH ABEDCFGH ABCFEDGH ABCDGFEH ABCDEHGF

My solution for the original problem is
      rot←{
2>l←≢⍵:⊂⍵
i←l{(⍳⍵-1),(⍵+1 0),(⍵+1)↓⍳⍺}¨⍳l-1
i⊃¨¨⊂⊂⍵
}

Any new ideas?

-Veli-Matti (feeling like an old dog now)
Veli-Matti
 
Posts: 65
Joined: Sat Nov 28, 2009 3:12 pm

Re: Is there a better/nicer way?

Postby Brian|Dyalog on Fri Mar 26, 2021 3:04 pm

Hi Veli-Matti!

What an interesting problem! It would have made a good candidate problem for a future APL Problem Solving competition. :-) This is just a quick hack; I'm not sure that it's "sneakier", but it seems to work...

      rot←{⍺←2 ⋄ ⍺>≢⍵:⊂⍵ ⋄(⊂⊂⍵)⌷⍨¨¨⍺{(⍺,/⍵){(⌽⍺)@⍺⊢⍵}¨⊂⍵}⍳≢⍵}
⍪2 3 4 rot¨⊂8↑⎕A
┌────────────────────────────────────────────────────────────────┐
│┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐│
││BACDEFGH│ACBDEFGH│ABDCEFGH│ABCEDFGH│ABCDFEGH│ABCDEGFH│ABCDEFHG││
│└────────┴────────┴────────┴────────┴────────┴────────┴────────┘│
├────────────────────────────────────────────────────────────────┤
│┌────────┬────────┬────────┬────────┬────────┬────────┐ │
││CBADEFGH│ADCBEFGH│ABEDCFGH│ABCFEDGH│ABCDGFEH│ABCDEHGF│ │
│└────────┴────────┴────────┴────────┴────────┴────────┘ │
├────────────────────────────────────────────────────────────────┤
│┌────────┬────────┬────────┬────────┬────────┐ │
││DCBAEFGH│AEDCBFGH│ABFEDCGH│ABCGFEDH│ABCDHGFE│ │
│└────────┴────────┴────────┴────────┴────────┘ │
└────────────────────────────────────────────────────────────────┘


Thanks for an interesting Friday diversion!

/Brian
User avatar
Brian|Dyalog
 
Posts: 108
Joined: Thu Nov 26, 2009 4:02 pm
Location: West Henrietta, NY

Re: Is there a better/nicer way?

Postby Veli-Matti on Fri Mar 26, 2021 4:30 pm

So there is no some new-squggle based obvious solution around...

Had to test a little bit:


rot_wm←{⍺←2 ⋄ ⎕IO←0 ⋄ ⍺>l←≢⍵:⊂⍵ ⋄ (⍺{(⍳⍵),(⍵+⌽⍳⍺),(⍵+⍺)↓⍳l}¨⍳l-⍺-1)⊃¨¨⊂⊂⍵}
rot_bm←{⍺←2 ⋄ ⍺>≢⍵:⊂⍵ ⋄(⊂⊂⍵)⌷⍨¨¨⍺{(⍺,/⍵){(⌽⍺)@⍺⊢⍵}¨⊂⍵}⍳≢⍵}
]runtime -c 'rot_wm 123⍴⎕A' 'rot_bb 123⍴⎕A'

rot_wm 123⍴⎕A → 2.1E¯4 | 0% ⎕⎕⎕⎕
rot_bb 123⍴⎕A → 1.9E¯3 | +847% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕

:)
-wm
Veli-Matti
 
Posts: 65
Joined: Sat Nov 28, 2009 3:12 pm

Re: Is there a better/nicer way?

Postby Brian|Dyalog on Fri Mar 26, 2021 6:40 pm

Ah! I didn't know you were looking for performance as well. :) The @ in my first solution slows things down quite a bit. Someone more clever than me might find a new-squiggle solution, but here's another try...

How about:
      rot_bb2←{⍺←2 ⋄ ⍺>≢⍵:⊂⍵ ⋄ (⊂¨⍺{⍵∘{a←⍺ ⋄ a⊣a[⍵]←⌽⍵}¨⍺,/⍵}⍳≢⍵)⌷¨⊂⍵}
]runtime -c 'rot_bb2 123⍴⎕A' 'rot_wm 123⍴⎕A'
rot_bb2 123⍴⎕A → 1.2E¯4 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
rot_wm 123⍴⎕A → 1.5E¯4 | +18% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
User avatar
Brian|Dyalog
 
Posts: 108
Joined: Thu Nov 26, 2009 4:02 pm
Location: West Henrietta, NY

Re: Is there a better/nicer way?

Postby Veli-Matti on Fri Mar 26, 2021 7:03 pm

Ouch - when looking at the performance, the long solutions seem to be always available.
So there's no 'clever' solution around? (till Adám or Roger get interested - Key or Stencil perhaps..)

I'm sure that this will tease you a little, though:

rot_wm2←{⍺←2 ⋄ ⍺>≢⍵:⊂⍵ ⋄ ⎕IO←0 ⋄ n←⍳(1-⍺)+≢⍵ ⋄ (n↑¨⊂⍵),¨((-⍺),/⍵),¨(-⌽n)↑¨⊂⍵}
]runtime -c 'rot_wm2 123⍴⎕A' 'rot_bb2 123⍴⎕A' 'rot_wm 123⍴⎕A'

rot_wm2 123⍴⎕A → 8.0E¯5 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
rot_bb2 123⍴⎕A → 2.0E¯4 | +146% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
rot_wm 123⍴⎕A → 1.9E¯4 | +140% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕


-wm ;)
Veli-Matti
 
Posts: 65
Joined: Sat Nov 28, 2009 3:12 pm

Re: Is there a better/nicer way?

Postby Phil Last on Fri Mar 26, 2021 7:06 pm

      rot_pl←{⍵∘{(⌽⍵)@(⍺⍳⍵)⊢⍺}¨⍺,/⍵}
2 rot_pl 8⍴⎕a
BACDEFGH ACBDEFGH ABDCEFGH ABCEDFGH ABCDFEGH ABCDEGFH ABCDEFHG
3 rot_pl 8⍴⎕a
CBADEFGH ADCBEFGH ABEDCFGH ABCFEDGH ABCDGFEH ABCDEHGF
4 rot_pl 8⍴⎕a
DCBAEFGH AEDCBFGH ABFEDCGH ABCGFEDH ABCDHGFE
User avatar
Phil Last
 
Posts: 571
Joined: Thu Jun 18, 2009 6:29 pm

Re: Is there a better/nicer way?

Postby Veli-Matti on Fri Mar 26, 2021 8:49 pm

I _should_ have included Phil in the APLists to be waited for :)
This far the shortest solution! - except that the result is not always correct:


2 rot_wm2 5⍴'ABCD'
BACDA ACBDA ABDCA ABCAD
2 rot_pl 5⍴'ABCD'
BACDA ACBDA ABDCA DBCAA

-wm
Veli-Matti
 
Posts: 65
Joined: Sat Nov 28, 2009 3:12 pm

Re: Is there a better/nicer way?

Postby Veli-Matti on Sat Mar 27, 2021 8:04 am

Using an old APL1 approach without peppering makes the code even quicker.

rot_wm3←{⍺←2 ⋄ ⍺>≢⍵:⊂⍵ ⋄ ↓(-r)⌽⍺{⍵[;⌽⍳⍺],0 ⍺↓⍵}r⌽(≢r←¯1+⍳(≢⍵)-⍺-1)(≢⍵)⍴⍵}
]runtime -c "rot_bb2 333⍴⎕A" "rot_wm2 333⍴⎕A" "rot_wm3 333⍴⎕A"

rot_bb2 333⍴⎕A → 6.1E¯4 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
rot_wm2 333⍴⎕A → 2.2E¯4 | -64% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
rot_wm3 333⍴⎕A → 9.4E¯5 | -85% ⎕⎕⎕⎕⎕⎕


-wm
Veli-Matti
 
Posts: 65
Joined: Sat Nov 28, 2009 3:12 pm

Re: Is there a better/nicer way?

Postby Morten|Dyalog on Sat Mar 27, 2021 8:45 am

So, I was expecting this to be be faster, but it isn't. I think I can claim "different", though:

Code: Select all
    rot_mk←{n←≢⍵ ⋄ ↓⍵[+\(1+n-⍺)n⍴1(⍺-1)1(n-⍺)/⍺ ¯1 ⍺ 1]}

    cmpx '3 rot_wm3 txt' '3 rot_mk txt'
  3 rot_wm3 txt → 1.3E¯4 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                   
  3 rot_mk txt  → 2.5E¯4 | +95% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕


Seriously, a good place to post this kind of puzzle now is on the APL Orchard, it is full of young and enthusiastic golfers.
User avatar
Morten|Dyalog
 
Posts: 401
Joined: Tue Sep 09, 2008 3:52 pm

Re: Is there a better/nicer way?

Postby Morten|Dyalog on Sun Mar 28, 2021 8:43 am

OK, "golfed for speed" in my dreams last night. "Flat" APL rocks!

Code: Select all
rot_mk2←{                                                           
     ⎕IO ⎕ML←0 1                                                     
     rows←1+⍺-⍨cols←≢⍵         ⍝ result shape                         
     ⍺>cols:0⍴⊂⍵               ⍝ not enough data: exit                     
     r←(n←rows×cols)⍴⍵         ⍝ fill the result with ⍵                             
     i←((1+cols)×⍳rows)∘.+⍳⍺   ⍝ indices of windows that need rotating
     r[i]←r[⌽i]                ⍝ do the flip                         
     (n⍴cols↑1)⊂r              ⍝ partition result                     
 }                                                                   
      cmpx '3 rot_wm3 txt' '3 rot_mk txt'   '3 rot_mk2 txt'
  3 rot_wm3 txt → 1.4E¯4 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                 
  3 rot_mk txt  → 2.6E¯4 | +85% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  3 rot_mk2 txt → 5.5E¯5 | -61% ⎕⎕⎕⎕⎕⎕⎕⎕⎕                             

User avatar
Morten|Dyalog
 
Posts: 401
Joined: Tue Sep 09, 2008 3:52 pm

Next

Return to APL Chat

Who is online

Users browsing this forum: No registered users and 1 guest