/* Quickselect (Rosetta code) in Picat. http://rosettacode.org/wiki/Quickselect_algorithm """ Use the quickselect algorithm on the vector [9, 8, 7, 6, 5, 0, 1, 2, 3, 4] To show the first, second, third, ... up to the tenth largest member of the vector, in order, here on this page. Note: Quicksort has a separate task. """ This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ % import v3_utils. % import util. % import cp. main => go. go ?=> L = [9,8,7,6,5,0,1,2,3,4], Len = L.len, println([select(L,1,Len,I) : I in 1..Len]), nl. go => true. select(List, Left, Right, K) = Select => if Left = Right then Select = List[Left] else PivotIndex = partition(List, Left, Right, random(Left,Right)), if K == PivotIndex then Select = List[K] elseif K < PivotIndex then Select = select(List, Left, PivotIndex-1, K) else Select = select(List, PivotIndex+1, Right, K) end end. partition(List, Left, Right, PivotIndex) = StoreIndex => PivotValue = List[PivotIndex], swap(List,PivotIndex,Right), StoreIndex = Left, foreach(I in Left..Right-1) if List[I] @< PivotValue then swap(List,StoreIndex,I), StoreIndex := StoreIndex+1 end end, swap(List,Right,StoreIndex). % Swap L[I] <=> L[J] swap(L,I,J) => T = L[I], L[I] := L[J], L[J] := T.