## 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?

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?

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

Brian|Dyalog

Posts: 108
Joined: Thu Nov 26, 2009 4:02 pm
Location: West Henrietta, NY

### Re: Is there a better/nicer way?

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?

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...

`      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% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕`

Brian|Dyalog

Posts: 108
Joined: Thu Nov 26, 2009 4:02 pm
Location: West Henrietta, NY

### Re: Is there a better/nicer way?

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?

`      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`

Phil Last

Posts: 571
Joined: Thu Jun 18, 2009 6:29 pm

### Re: Is there a better/nicer way?

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?

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?

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.

Morten|Dyalog

Posts: 401
Joined: Tue Sep 09, 2008 3:52 pm

### Re: Is there a better/nicer way?

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% ⎕⎕⎕⎕⎕⎕⎕⎕⎕                             `

Morten|Dyalog

Posts: 401
Joined: Tue Sep 09, 2008 3:52 pm

Next