0

I am new to prolog language. I came across an interesting problem in prolog.

Generally, quicksort works well for large lists. But for smaller lists, insertion sort works better than quicksort. How can i write a sorting algorithm in Prolog that uses quicksort initially, but switches to insertion sort for sublists of 15 or fewer elements.

The hint is that we can count the number of elements during the partition operation. But i don't know how to form an algorithm for this problem. Can anyone please guide/help.

Thanks a lot in advance.

Justin Carrey
  • 3,563
  • 8
  • 32
  • 45
  • For more efficient ways, see http://stackoverflow.com/questions/8429479/sorting-a-list-in-prolog/8430692#8430692 – false Nov 11 '13 at 16:51

2 Answers2

1

You can make several clauses for the mysort rule that choose the algorithm based on the length of the list, like this:

mySort(In, Out) :-
    count(In, Cnt),
    Cnt < 15,
    insertionSort(In, Out).
mySort(In, Out) :-
    count(In, Cnt),
    Cnt >= 15,
    quickSort(In, Out).

quickSort(In, Out) :-
    partition(In, Left, Right),
    mySort(Left, SortedLeft),
    mySort(Right, SortedRight),
    mergeSorted(SortedLeft, SortedRight, Out).

The trick is that the quickSort/2 rule references sort, not quickSort, after partitioning the input. This means that as soon as the count drops below 15, insertionSort is going to be used to sort the smaller partitions.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Is `count/2` defined somewhere, or do you mean `length/2`? – lurker Nov 10 '13 at 02:33
  • @mbratch This is intended as a skeletal implementation, so `partition`, `mergeSorted`, and `count` are up to the OP to define (or to use an existing one, such as `length/2` for `count/2`). – Sergey Kalinichenko Nov 10 '13 at 02:37
  • the OP wanted `partition` also to count the length, to spare the unneeded extra traversal. – Will Ness Nov 10 '13 at 08:53
  • @WillNess This is only a skeleton of the algorithm - the OP is free to optimize this, passing around the counts. The key idea is in these three clauses. – Sergey Kalinichenko Nov 10 '13 at 10:10
  • sort/2 is a built-in predicate. You should not be able to redefine it. What Prolog did you use? It must be a very old version. – false Nov 11 '13 at 16:39
  • @false Thanks, I renamed this predicate to be consistent with the rest of the answer, where I am not using "real" names. The idea was to demonstrate the basic approach without writing any real code. I haven't been actively using Prolog since mid-nineties, so I had no idea it's not possible to redefine a built-in. Thanks! – Sergey Kalinichenko Nov 11 '13 at 16:46
1

partition puts each element either to one or the other sublist. so just maintain two more arguments which are counts for the sublists, starting as 0, and increment the corresponding counter when adding another element to its sublist:

part([]    ,[],[],0 ,0).
part([P|LS],L , R,CL,CR):- part(P,LS,L,[],R,[],0,CL,0,CR).

part(_,[]    ,LZ,LZ,RZ,RZ,CL,CL,CR,CR).
part(P,[X|LS],L ,LZ,R ,RZ,IL,CL,JR,CR):-
   X < P -> L=[X|T],I2 is IL+1, part(P,LS,T,LZ,R,RZ,I2,CL,JR,CR)
 ; .....
Will Ness
  • 70,110
  • 9
  • 98
  • 181