Challenge#1 – Partial sort

One of my colleagues recently introduced me to Project Euler. Project Euler is a great way for you to solve mathematical problems using your preferred language and then compare your solution with others. However, I noticed that most of the problems there were not practical for q. Many were designed to use loops which are frowned up on in q. This is why I am going to start posting challenges here that are q/kdb+ related.

Our first challenge is about partial sort.

A developer asked on q/kdb+ google groups page about how to partially sort a list. Let’s say I have a list:

53 66 59 30 85 89 23 60 6 52 39

I want to get:

30 53 59 66 85 89 23 60 6 52 39

Note that it found the middle number (89) and then sorted the list up to that point.

Post your solutions in the comments section.

UPDATE:

Solutions I have received:

You can place the order online to get it drop at your home; do place purchase cheap viagra the order online today itself. Even though, it is obvious that, the probability of experiencing powerlessness rises with time, this is mainly owing to the increased sensitivity, you condoms can actually buy cipla viagra robertrobb.com help decrease that efficiently. It can http://robertrobb.com/?iid=4269 generico levitra on line be a major trouble prevalent in most with the men. Kamagra have proved effective to treat men’s free sample of levitra erectile dysfunction.
Bill - {(asc i _ x),(i:neg (count x) div 2)#x}

Showvik - {asc[x [til p]],(p:floor(count x)%2)_x}

Rolf - {{asc[x],y}. 2 0N#x}

David - raze(asc;::)@'2 0N#list

Performance:

q)a:1000001?100
q)\ts {(asc i _ x),(i:neg (count x) div 2)#x}a
49 8389232j
q)\ts {asc[x [til p]],(p:floor(count x)%2)_x}a
45 8389232j
q)\ts {{asc[x],y}. 2 0N#x}a
29 10486448j
q)\ts raze(asc;::)@'2 0N#a
29 8389232j

David and Rolf’s solutions both take 29mS to execute. Let’s use a different sized list.

q)a:100000001?100
q)\ts {{asc[x],y}. 2 0N#x}a
2809 1342178160j
q)\ts raze(asc;::)@'2 0N#a
2258 1073742448j

Looks like David’s solution is faster and uses less memory. That’s because Rolf’s solution creates a new list whereas David just uses the same list throughout.

Join the Conversation

4 Comments

  1. My first solution appeared to be working, but only because the middle element (89) was also the highest in the first half of the list. I modified my solution to ensure that the middle digit was actually being included in the sort and also ensures that lists of even length were accommodated.

    {(asc (i)_x),(i:neg (size:count x) div 2)#x}[53 66 59 30 85 89 23 60 6 52 39]

    1. Nice solution, Bill! You can get rid of size assignment because you are only using it once. Also, the parenthesis around i are unnecessary.

      q){(asc i _ x),(i:neg (count x) div 2)#x}[53 66 59 30 85 89 23 60 6 52 39]
      30 53 59 66 85 89 23 60 6 52 39

  2. q){asc[x [til p]],(p:floor(count x)%2)_x}53 66 59 30 85 89 23 60 6 52 39 100 12 14 15
    q)23 30 53 59 66 85 89 60 6 52 39 100 12 14 15j

    1. Thanks Showvik! I have updated the post with more solutions and comparison.

Leave a comment

Your email address will not be published. Required fields are marked *