Skip to content

Latest commit

 

History

History

a_random_permutation

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

A Random Permutation

The other day I needed to pick a random order for my team to present our work in. Usually one of us just makes up an order but this time I decided to do it programmatically.

With my team on the call, I fired up an APL REPL and entered an expression like:

      'alice' 'bob' 'yazeed' 'zach'[4?4]
┌─────┬────┬──────┬───┐
│alicezachyazeedbob│
└─────┴────┴──────┴───┘

So with 5 characters, [4?4], I had the business end of an expression to select a random permutation. But in that expression I have to manually count the number of people on my team (4) and type it two times. Let's see if we can eliminate that so I can add people and have the expression handle it.

      {[?]} 'alice' 'bob' 'yazeed' 'zach'
┌────┬──────┬─────┬───┐
│zachyazeedalicebob│
└────┴──────┴─────┴───┘

So with 9 characters I had a function to handle a group of any size.

If some NASA Apollo program contributors join my team I can handle them:

      {[?]} 'alice' 'bob' 'yazeed' 'zach' 'margaret' 'fred' 'jim' 'jack'
┌────┬──────┬───┬───┬────┬────┬─────┬────────┐
│zachyazeedbobjimjackfredalicemargaret│
└────┴──────┴───┴───┴────┴────┴─────┴────────┘

But that expression explicitly references the parameter (⍵) two times. There is another way to do this that does not involve explicitly referencing the parameters: tacit style

      (?) 'alice' 'bob' 'yazeed' 'zach'
┌──────┬───┬────┬─────┐
│yazeedbobzachalice│
└──────┴───┴────┴─────┘

Notice that that expression does not reference its parameters explicitly (⍵ and ⍺ do not occur in the expression). It is only 8 characters (if you don't count the parens which are only there because I put the argument (the vector of character vectors) next to it.)

I don't expect that many other languages can express this in 8 characters or less (especially without a library)!

I've only been using APL recreationally (contributing to April) for about a year but I was able to arrive at the first two expressions quickly. The tacit style took me at least 10 minutes and I had help from The APLcart. (I didn't make my team watch me try to write this tacit style expression; I did it after work.)

I knew I wanted a permutation of a vector of character vectors so I searched "permutation" in APLcart and I found the following (which is the basis of the tacit expression I wrote):

Iv⌷⍨∘⊂⍨Y              Permute: Reorder major cells of Y according tot permutation vector Iv

APLcart tells you that Iv is an integer vector and Y is any array. I won't describe the 10 minutes in detail but I'll list the things I needed to remember/review/discover in addition to the language primitives:

Function Trains. Specifically the monadic fork.

Dyalog APL's expression tree. I actually don't know what they call it but if you type a tacit expression in the REPL it prints a cute tree representation depicting how the functions and operators get glued together to form a derived function.

      ⌷⍨∘⊂⍨ 
     ⍨
   ┌─┘
   ∘  
  ┌┴┐ 
  ⍨ ⊂ 
┌─┘   
⌷     

If APL looks interesting to you I can recommend the Dyalog APL Tutor to get more comfortable with the language. If you want to see a famous use of APL you can watch Conway's Game Of Life in APL.

Ok, have fun making random orders to present your team's work in. :)