How to resolve the algorithm Sorting algorithms/Patience sort step by step in the Pascal programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Sorting algorithms/Patience sort step by step in the Pascal programming language

Table of Contents

Problem Statement

Sort an array of numbers (of any convenient size) into ascending order using   Patience sorting.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Sorting algorithms/Patience sort step by step in the Pascal programming language

Source code in the pascal programming language

PatienceSortTask (Output);

CONST MaxSortSize = 1024;       { A power of two. }
      MaxWinnersSize = (2 * MaxSortSize) - 1;

TYPE PilesArrayType = ARRAY [1 .. MaxSortSize] OF INTEGER;
     WinnersArrayType = ARRAY [1 .. MaxWinnersSize,
                               1 .. 2] OF INTEGER;

VAR ExampleNumbers : ARRAY [0 .. 35] OF INTEGER;
    SortedIndices : ARRAY [0 .. 25] OF INTEGER;
    i : INTEGER;

FUNCTION NextPowerOfTwo (n : INTEGER) : INTEGER;
  VAR Pow2 : INTEGER;
BEGIN
  { This need not be a fast implementation. }
  Pow2 := 1;
  WHILE Pow2 < n DO
    Pow2 := Pow2 + Pow2;
  NextPowerOfTwo := Pow2;
END;

PROCEDURE InitPilesArray (VAR Arr : PilesArrayType);
  VAR i : INTEGER;
BEGIN
  FOR i := 1 TO MaxSortSize DO
    Arr[i] := 0;
END;

PROCEDURE InitWinnersArray (VAR Arr : WinnersArrayType);
  VAR i : INTEGER;
BEGIN
  FOR i := 1 TO MaxWinnersSize DO
    BEGIN
      Arr[i, 1] := 0;
      Arr[i, 2] := 0;
    END;
END;

PROCEDURE IntegerPatienceSort (iFirst, iLast : INTEGER;
                               Arr : ARRAY OF INTEGER;
                               VAR Sorted : ARRAY OF INTEGER);
  VAR NumPiles : INTEGER;
      Piles, Links : PilesArrayType;
      Winners : WinnersArrayType;

  FUNCTION FindPile (q : INTEGER) : INTEGER;
    {
       Bottenbruch search for the leftmost pile whose top is greater
       than or equal to some element x. Return an index such that:

       * if x is greater than the top element at the far right, then
         the index returned will be num-piles.

       * otherwise, x is greater than every top element to the left of
         index, and less than or equal to the top elements at index
         and to the right of index.

       References:

       * H. Bottenbruch, "Structure and use of ALGOL 60", Journal of
         the ACM, Volume 9, Issue 2, April 1962, pp.161-221.
         https://doi.org/10.1145/321119.321120

         The general algorithm is described on pages 214 and 215.

       * https://en.wikipedia.org/w/index.php?title=Binary_search_algorithm&oldid=1062988272#Alternative_procedure
    }
    VAR i, j, k, Index : INTEGER;
  BEGIN
    IF NumPiles = 0 THEN
      Index := 1
    ELSE
      BEGIN
        j := 0;
        k := NumPiles - 1;
        WHILE j <> k DO
          BEGIN
            i := (j + k) DIV 2;
            IF Arr[Piles[j + 1] + iFirst - 1] < Arr[q + iFirst - 1] THEN
              j := i + 1
            ELSE
              k := i
          END;
        IF j = NumPiles - 1 THEN
          BEGIN
            IF Arr[Piles[j + 1] + iFirst - 1] < Arr[q + iFirst - 1] THEN
              { A new pile is needed. }
              j := j + 1
          END;
        Index := j + 1
      END;
    FindPile := Index
  END;

  PROCEDURE Deal;
    VAR i, q : INTEGER;
  BEGIN
    FOR q := 1 TO iLast - iFirst + 1 DO
      BEGIN
        i := FindPile (q);
        Links[q] := Piles[i];
        Piles[i] := q;
        IF i = NumPiles + 1 THEN
          NumPiles := i
      END
  END;

  PROCEDURE KWayMerge;
    {
       k-way merge by tournament tree.
    
       See Knuth, volume 3, and also
       https://en.wikipedia.org/w/index.php?title=K-way_merge_algorithm&oldid=1047851465#Tournament_Tree
    
       However, I store a winners tree instead of the recommended
       losers tree. If the tree were stored as linked nodes, it would
       probably be more efficient to store a losers tree. However, I
       am storing the tree as an array, and one can find an opponent
       quickly by simply toggling the least significant bit of a
       competitor's array index.
    }
    VAR TotalExternalNodes : INTEGER;
        TotalNodes : INTEGER;
        iSorted, i, Next : INTEGER;

    FUNCTION FindOpponent (i : INTEGER) : INTEGER;
      VAR Opponent : INTEGER;
    BEGIN
      IF ODD (i) THEN
        Opponent := i - 1
      ELSE
        Opponent := i + 1;
      FindOpponent := Opponent
    END;

    FUNCTION PlayGame (i : INTEGER) : INTEGER;
      VAR j, iWinner : INTEGER;
    BEGIN
      j := FindOpponent (i);
      IF Winners[i, 1] = 0 THEN
        iWinner := j
      ELSE IF Winners[j, 1] = 0 THEN
        iWinner := i
      ELSE IF (Arr[Winners[j, 1] + iFirst - 1]
               < Arr[Winners[i, 1] + iFirst - 1]) THEN
        iWinner := j
      ELSE
        iWinner := i;
      PlayGame := iWinner
    END;

    PROCEDURE ReplayGames (i : INTEGER);
      VAR j, iWinner : INTEGER;
    BEGIN
      j := i;
      WHILE j <> 1 DO
        BEGIN
          iWinner := PlayGame (j);
          j := j DIV 2;
          Winners[j, 1] := Winners[iWinner, 1];
          Winners[j, 2] := Winners[iWinner, 2];
        END
    END;

    PROCEDURE BuildTree;
      VAR iStart, i, iWinner : INTEGER;
    BEGIN
      FOR i := 1 TO TotalExternalNodes DO
        { Record which pile a winner will have come from. }
        Winners[TotalExternalNodes - 1 + i, 2] := i;

      FOR i := 1 TO NumPiles DO
        { The top of each pile becomes a starting competitor. }
        Winners[TotalExternalNodes + i - 1, 1] := Piles[i];

      FOR i := 1 TO NumPiles DO
        { Discard the top of each pile. }
        Piles[i] := Links[Piles[i]];

      iStart := TotalExternalNodes;
      WHILE iStart <> 1 DO
        BEGIN
          i := iStart;
          WHILE i <= (2 * iStart) - 1 DO
            BEGIN
              iWinner := PlayGame (i);
              Winners[i DIV 2, 1] := Winners[iWinner, 1];
              Winners[i DIV 2, 2] := Winners[iWinner, 2];
              i := i + 2
            END;
          iStart := iStart DIV 2
        END
    END;

  BEGIN
    TotalExternalNodes := NextPowerOfTwo (NumPiles);
    TotalNodes := (2 * TotalExternalNodes) - 1;
    BuildTree;
    iSorted := 0;
    WHILE Winners[1, 1] <> 0 DO
      BEGIN
        Sorted[iSorted] := Winners[1, 1] + iFirst - 1;
        iSorted := iSorted + 1;
        i := Winners[1, 2];
        Next := Piles[i];         { The next top of pile i. }
        IF Next <> 0 THEN
          Piles[i] := Links[Next]; { Drop that top. }
        i := (TotalNodes DIV 2) + i;
        Winners[i, 1] := Next;
        ReplayGames (i)
      END
  END;

BEGIN
  NumPiles := 0;
  InitPilesArray (Piles);
  InitPilesArray (Links);
  InitWinnersArray (Winners);

  IF MaxSortSize < iLast - iFirst + 1 THEN
    BEGIN
      Write ('This subarray is too large for the program.');
      WriteLn;
      HALT
    END
  ELSE
    BEGIN
      Deal;
      KWayMerge
    END
END;

BEGIN
  ExampleNumbers[10] := 22;
  ExampleNumbers[11] := 15;
  ExampleNumbers[12] := 98;
  ExampleNumbers[13] := 82;
  ExampleNumbers[14] := 22;
  ExampleNumbers[15] := 4;
  ExampleNumbers[16] := 58;
  ExampleNumbers[17] := 70;
  ExampleNumbers[18] := 80;
  ExampleNumbers[19] := 38;
  ExampleNumbers[20] := 49;
  ExampleNumbers[21] := 48;
  ExampleNumbers[22] := 46;
  ExampleNumbers[23] := 54;
  ExampleNumbers[24] := 93;
  ExampleNumbers[25] := 8;
  ExampleNumbers[26] := 54;
  ExampleNumbers[27] := 2;
  ExampleNumbers[28] := 72;
  ExampleNumbers[29] := 84;
  ExampleNumbers[30] := 86;
  ExampleNumbers[31] := 76;
  ExampleNumbers[32] := 53;
  ExampleNumbers[33] := 37;
  ExampleNumbers[34] := 90;

  IntegerPatienceSort (10, 34, ExampleNumbers, SortedIndices);

  Write ('unsorted  ');
  FOR i := 10 TO 34 DO
    BEGIN
      Write (' ');
      Write (ExampleNumbers[i])
    END;
  WriteLn;
  Write ('sorted    ');
  FOR i := 0 TO 24 DO
    BEGIN
      Write (' ');
      Write (ExampleNumbers[SortedIndices[i]]);
    END;
  WriteLn
END.


  

You may also check:How to resolve the algorithm Elementary cellular automaton step by step in the Prolog programming language
You may also check:How to resolve the algorithm Quad-power prime seeds step by step in the Java programming language
You may also check:How to resolve the algorithm Read a specific line from a file step by step in the AutoHotkey programming language
You may also check:How to resolve the algorithm Test a function step by step in the Insitux programming language
You may also check:How to resolve the algorithm Classes step by step in the Crystal programming language