0

I found this quicksort implementation on a website:

q:{$[2>distinct x;x;raze q each x where each not scan x < rand x]};

I don't understand this part:

raze q each x where each not scan x < rand x

Can someone explain it to me step by step?

Donald_W
  • 1,773
  • 21
  • 35
user3914448
  • 469
  • 1
  • 11
  • 22
  • @Rahul 's answer explains it well....but are you just trying to understand it out of curiosity or were you planning to actually use it?? You should definitely not use this, it will never be quicker than the built-in 'asc' function – terrylynch Feb 23 '15 at 13:55
  • Thanks, just to understand, to learn q – user3914448 Feb 23 '15 at 23:57

1 Answers1

4

Lets do it step by step . I assume you have basic understanding of Quick Sort algo. Also, there is one correction in code you mentioned which I have corrected in step 5.

Example list:

                q)x: 1 0 5 4 3
  1. Take a random element from list which will act as pivot.

       q)  rand x
    

    Suppose it gives us '4' from list.

  2. Split list 'x' in 2 lists. One contains elements lesser that '4' and other greater(or equal) to '4'.

    2.a) First compare all elements with pivot (4 in our case)

                  q)   (x<rand x)   /  11001b  : output is boolean list 
    

    2.b) Using above boolean list we can get all elements from 'x' lesser than '4'. Here is the way:

         q) x where  11001b  / ( 1  0 3) : output
    

    So we require other expression to get all elements greater(or equal) than pivot '4'. There are many ways to do it but lets see the one used in code:

          q)not scan (x<rand x)   / (11001b;00110b) : output
    

So it gives the list which has 2 lists. First is result of (x < rand x) which is used to get elements lesser than pivot '4' and other is negation of this list which is done by 'not' and it is used to get all elements greater(or equal) that pivot '4'.

2.c) So now we can generate 2 lists using sample code from (2.b)

       q) x where each (not scan (x<rand x)) / ((1 0 3);(5 4)): output list which has 2 lists
  1. Now apply same function to each list to sort each of them i.e. recursive call on each list of list ((1 0 3);(5 4))

        q) q each x where each (not scan (x<rand x))
    
    1. After all calculations , apply 'raze' to flatten all lists that are returned from each recursive call to output one single list.

    2. End condition for recursive call is: when input list has only 1 distinct element just return it.

         q) 2>count distinct x
      

      Note: There is one correction. 'count' was missing in original code.

Rahul
  • 3,914
  • 1
  • 14
  • 25