Sorting algorithms/Patience sort: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
 
(4 intermediate revisions by 3 users not shown)
Line 13:
{{trans|Kotlin}}
 
<langsyntaxhighlight lang="11l">F patience_sort(&arr)
I arr.len < 2 {R}
 
Line 48:
V sArr = [‘dog’, ‘cow’, ‘cat’, ‘ape’, ‘ant’, ‘man’, ‘pig’, ‘ass’, ‘gnu’]
patience_sort(&sArr)
print(sArr)</langsyntaxhighlight>
 
{{out}}
Line 59:
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
<lang AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program patienceSort64.s */
Line 422:
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
</lang>
 
=={{header|Ada}}==
Line 432:
 
 
<langsyntaxhighlight lang="ada">----------------------------------------------------------------------
 
with Ada.Text_IO;
Line 719:
end patience_sort_task;
 
----------------------------------------------------------------------</langsyntaxhighlight>
 
{{out}}
Line 727:
 
=={{header|AppleScript}}==
<langsyntaxhighlight lang="applescript">-- In-place patience sort.
on patienceSort(theList, l, r) -- Sort items l thru r of theList.
set listLen to (count theList)
Line 786:
set aList to {62, 86, 59, 65, 92, 85, 71, 71, 27, -52, 67, 59, 65, 80, 3, 65, 2, 46, 83, 72, 47, 5, 26, 18, 63}
sort(aList, 1, -1)
return aList</langsyntaxhighlight>
 
{{output}}
<langsyntaxhighlight lang="applescript">{-52, 2, 3, 5, 18, 26, 27, 46, 47, 59, 59, 62, 63, 65, 65, 65, 67, 71, 71, 72, 80, 83, 85, 86, 92}</langsyntaxhighlight>
 
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
<lang ARM Assembly>
/* ARM assembly Raspberry PI */
/* program patienceSort.s */
Line 1,121:
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
</lang>
 
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">patienceSort: function [arr][
result: new arr
 
if 2 > size result -> return result
 
piles: []
 
loop result 'elem ->
'piles ++ @[@[elem]]
 
loop 0..dec size result 'i [
minP: last piles\0
minPileIndex: 0
 
if 2 =< size piles ->
loop 1..dec size piles 'j [
if minP > last piles\[j] [
minP: last piles\[j]
minPileIndex: j
]
]
 
result\[i]: minP
piles\[minPileIndex]: slice piles\[minPileIndex] 0 dec dec size piles\[minPileIndex]
if zero? size piles\[minPileIndex] ->
piles: remove.index piles minPileIndex
]
return result
]
 
print patienceSort [3 1 2 8 5 7 9 4 6]</syntaxhighlight>
 
{{out}}
 
<pre>1 2 3 4 5 6 7 8 9</pre>
 
=={{header|ATS}}==
Line 1,131 ⟶ 1,168:
The sort routine returns an array of indices into the original array, which is left unmodified.
 
<langsyntaxhighlight lang="ats">(*------------------------------------------------------------------*)
 
#include "share/atspre_staload.hats"
Line 1,810 ⟶ 1,847:
end
 
(*------------------------------------------------------------------*)</langsyntaxhighlight>
 
{{out}}
<pre>$ patscc -O3 -DATS_MEMALLOC_LIBC patience_sort_task.dats && ./a.out
unsorted 22 15 98 82 22 4 58 70 80 38 49 48 46 54 93 8 54 2 72 84 86 76 53 37 90
sorted 2 4 8 15 22 22 37 38 46 48 49 53 54 54 58 70 72 76 80 82 84 86 90 93 98</pre>
 
===A patience sort for arrays of non-linear elements (second version)===
{{trans|Fortran}}
 
 
This version of the sort (which I derived from the first) has a more primitive "core" implementation, and a wrapper around that. The "core" requires that the user pass workspace to it (much as Fortran 77 procedures often do). The wrapper uses stack storage for the workspaces, if the sorted subarray is small; otherwise it uses malloc. One may be interested in contrasting the branch that uses stack storage with the branch that uses malloc.
 
<syntaxhighlight lang="ats">(* A version of the patience sort that uses arrays passed to it as its
workspace, and returns the results in an array passed to it.
 
This way, the arrays could be reused between calls, or easily put
on the stack if they are not too large, yet still allocated if they
are larger than that.
 
Notice that the work arrays both start *and finish* as
uninitialized storage. *)
 
(*------------------------------------------------------------------*)
 
#include "share/atspre_staload.hats"
 
(* ================================================================ *)
(* Interface declarations that really should be moved to a .sats *)
(* file. *)
 
stadef patience_sort_index (ifirst : int, len : int, i : int) =
len == 0 || (ifirst <= i && i < ifirst + len)
typedef patience_sort_index (ifirst : int, len : int, i : int) =
[patience_sort_index (ifirst, len, i)] size_t i
typedef patience_sort_index (ifirst : int, len : int) =
[i : int] patience_sort_index (ifirst, len, i)
 
stadef patience_sort_link (ifirst : int, len : int, i : int) =
0 <= i && i <= len
typedef patience_sort_link (ifirst : int, len : int, i : int) =
[patience_sort_link (ifirst, len, i)] size_t i
typedef patience_sort_link (ifirst : int, len : int) =
[i : int] patience_sort_link (ifirst, len, i)
 
(* patience_sort$lt : the order predicate for patience sort. *)
extern fn {a : t@ype}
patience_sort$lt (x : a, y : a) :<> bool
 
local
 
typedef index_t (ifirst : int, len : int) =
patience_sort_index (ifirst, len)
typedef link_t (ifirst : int, len : int) =
patience_sort_link (ifirst, len)
 
in
 
extern fn {a : t@ype}
patience_sort_given_workspaces
{ifirst, len : int | 0 <= ifirst}
{n : int | ifirst + len <= n}
{power : int | len <= power}
{n_piles : int | len <= n_piles}
{n_links : int | len <= n_links}
{n_winv : int | 2 * power <= n_winv}
{n_winl : int | 2 * power <= n_winl}
(pf_exp2 : [exponent : nat] EXP2 (exponent, power) |
arr : &RD(array (a, n)),
ifirst : size_t ifirst,
len : size_t len,
power : size_t power,
piles : &array (link_t (ifirst, len)?, n_piles) >> _,
links : &array (link_t (ifirst, len)?, n_links) >> _,
winvals : &array (link_t (ifirst, len)?, n_winv) >> _,
winlinks : &array (link_t (ifirst, len)?, n_winl) >> _,
sorted : &array (index_t (ifirst, len)?, len)
>> array (index_t (ifirst, len), len))
:<!wrt> void
 
extern fn {a : t@ype}
patience_sort_with_its_own_workspaces
{ifirst, len : int | 0 <= ifirst}
{n : int | ifirst + len <= n}
(arr : &RD(array (a, n)),
ifirst : size_t ifirst,
len : size_t len,
sorted : &array (index_t (ifirst, len)?, len)
>> array (index_t (ifirst, len), len))
:<!wrt> void
 
end
 
overload patience_sort with patience_sort_given_workspaces
overload patience_sort with patience_sort_with_its_own_workspaces
 
extern fn {tk : tkind}
next_power_of_two
{i : pos}
(i : g1uint (tk, i))
:<> [k : int | i <= k; k < 2 * i]
[n : nat]
@(EXP2 (n, k) | g1uint (tk, k))
 
(* ================================================================ *)
(* What follows is implementation and belongs in .dats files. *)
 
(*------------------------------------------------------------------*)
(*
 
In the following implementation of next_power_of_two:
 
* I implement it as a template for all types of kind g1uint. This
includes dependent forms of uint, usint, ulint, ullint, size_t,
and yet more types in the prelude; also whatever others one may
create.
 
* I prove the result is not less than the input.
 
* I prove the result is less than twice the input.
 
* I prove the result is a power of two. This last proof is
provided in the form of an EXP2 prop.
 
* I do NOT return what number two is raised to (though I easily
could have). I leave that number "existentially defined". In
other words, I prove only that some such non-negative number
exists.
 
*)
 
implement {tk}
next_power_of_two {i} (i) =
let
(* This is not the fastest implementation, although it does verify
its own correctness. *)
 
val one : g1uint (tk, 1) = g1u2u 1u
 
fun
loop {j : pos | j < i} .<i + i - j>.
(pf : [n : nat] EXP2 (n, j) |
j : g1uint (tk, j))
:<> [k : int | i <= k; k < 2 * i]
[n : nat]
@(EXP2 (n, k) | g1uint (tk, k)) =
let
val j2 = j + j
in
if i <= j2 then
@(EXP2ind pf | j2)
else
loop (EXP2ind pf | j2)
end
in
if i = one then
@(EXP2bas () | one)
else
loop (EXP2bas () | one)
end
 
(*------------------------------------------------------------------*)
 
extern praxi {a : vt@ype}
array_uninitize_without_doing_anything
{n : int}
(arr : &array (INV(a), n) >> array (a?, n),
asz : size_t n)
:<prf> void
 
(*------------------------------------------------------------------*)
 
stadef index_t (ifirst : int, len : int, i : int) =
patience_sort_index (ifirst, len, i)
typedef index_t (ifirst : int, len : int, i : int) =
patience_sort_index (ifirst, len, i)
typedef index_t (ifirst : int, len : int) =
patience_sort_index (ifirst, len)
 
stadef link_t (ifirst : int, len : int, i : int) =
patience_sort_link (ifirst, len, i)
typedef link_t (ifirst : int, len : int, i : int) =
patience_sort_link (ifirst, len, i)
typedef link_t (ifirst : int, len : int) =
patience_sort_link (ifirst, len)
 
fn {a : t@ype}
find_pile {ifirst, len : int}
{n : int | ifirst + len <= n}
{num_piles : nat | num_piles <= len}
{n_piles : int | len <= n_piles}
{q : pos | q <= len}
(ifirst : size_t ifirst,
arr : &RD(array (a, n)),
num_piles : size_t num_piles,
piles : &RD(array (link_t (ifirst, len), n_piles)),
q : size_t q)
:<> [i : pos | i <= num_piles + 1]
size_t i =
(*
Bottenbruch search for the leftmost pile whose top is greater than
or equal to the next value dealt by "deal".
 
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
*)
if num_piles = i2sz 0 then
i2sz 1
else
let
macdef lt = patience_sort$lt<a>
 
prval () = lemma_g1uint_param ifirst
prval () = prop_verify {0 <= ifirst} ()
 
fun
loop {j, k : nat | j <= k; k < num_piles}
.<k - j>.
(arr : &RD(array (a, n)),
piles : &array (link_t (ifirst, len), n_piles),
j : size_t j,
k : size_t k)
:<> [i : pos | i <= num_piles + 1]
size_t i =
if j = k then
begin
if succ j <> num_piles then
succ j
else
let
val piles_j = piles[j]
val () = $effmask_exn assertloc (piles_j <> g1u2u 0u)
 
val x1 = arr[pred q + ifirst]
and x2 = arr[pred piles_j + ifirst]
in
if x2 \lt x1 then
succ (succ j)
else
succ j
end
end
else
let
typedef index (i : int) = [0 <= i; i < n] size_t i
typedef index = [i : int] index i
 
stadef i = j + ((k - j) / 2)
val i : size_t i = j + ((k - j) / g1u2u 2u)
 
val piles_j = piles[j]
val () = $effmask_exn assertloc (piles_j <> g1u2u 0u)
 
val x1 = arr[pred q + ifirst]
and x2 = arr[pred piles_j + ifirst]
in
if x2 \lt x1 then
loop (arr, piles, i + 1, k)
else
loop (arr, piles, j, i)
end
in
loop (arr, piles, g1u2u 0u, pred num_piles)
end
 
fn {a : t@ype}
deal {ifirst, len : int}
{n : int | ifirst + len <= n}
(ifirst : size_t ifirst,
len : size_t len,
arr : &RD(array (a, n)),
piles : &array (link_t (ifirst, len)?, len)
>> array (link_t (ifirst, len), len),
links : &array (link_t (ifirst, len)?, len)
>> array (link_t (ifirst, len), len))
:<!wrt> [num_piles : int | num_piles <= len]
size_t num_piles =
let
prval () = lemma_g1uint_param ifirst
prval () = lemma_g1uint_param len
 
typedef link_t (i : int) = link_t (ifirst, len, i)
typedef link_t = link_t (ifirst, len)
 
val zero : size_t 0 = g1u2u 0u
val one : size_t 1 = g1u2u 1u
val link_nil : link_t 0 = g1u2u 0u
 
fun
loop {q : pos | q <= len + 1}
{m : nat | m <= len}
.<len + 1 - q>.
(arr : &RD(array (a, n)),
q : size_t q,
piles : &array (link_t, len) >> _,
links : &array (link_t, len) >> _,
m : size_t m)
:<!wrt> [num_piles : nat | num_piles <= len]
size_t num_piles =
if q = succ (len) then
m
else
let
val i = find_pile {ifirst, len} (ifirst, arr, m, piles, q)
 
(* We have no proof the number of elements will not exceed
storage. However, we know it will not, because the number
of piles cannot exceed the size of the input. Let us get
a "proof" by runtime check. *)
val () = $effmask_exn assertloc (i <= len)
in
links[pred q] := piles[pred i];
piles[pred i] := q;
if i = succ m then
loop {q + 1} (arr, succ q, piles, links, succ m)
else
loop {q + 1} (arr, succ q, piles, links, m)
end
in
array_initize_elt<link_t> (piles, len, link_nil);
array_initize_elt<link_t> (links, len, link_nil);
loop (arr, one, piles, links, zero)
end
 
fn {a : t@ype}
k_way_merge {ifirst, len : int}
{n : int | ifirst + len <= n}
{num_piles : pos | num_piles <= len}
{power : int | len <= power}
(pf_exp2 : [exponent : nat] EXP2 (exponent, power) |
arr : &RD(array (a, n)),
ifirst : size_t ifirst,
len : size_t len,
num_piles : size_t num_piles,
power : size_t power,
piles : &array (link_t (ifirst, len), len) >> _,
links : &RD(array (link_t (ifirst, len), len)),
winvals : &array (link_t (ifirst, len)?, 2 * power)
>> _,
winlinks : &array (link_t (ifirst, len)?, 2 * power)
>> _,
sorted : &array (index_t (ifirst, len)?, len)
>> array (index_t (ifirst, len), len))
:<!wrt> void =
(*
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.
*)
let
prval () = lemma_g1uint_param ifirst
prval () = lemma_g1uint_param len
 
typedef link_t (i : int) = link_t (ifirst, len, i)
typedef link_t = link_t (ifirst, len)
 
val link_nil : link_t 0 = g1u2u 0u
 
typedef index_t (i : int) = index_t (ifirst, len, i)
typedef index_t = index_t (ifirst, len)
 
val [total_external_nodes : int]
@(_ | total_external_nodes) = next_power_of_two num_piles
prval () = prop_verify {num_piles <= total_external_nodes} ()
 
stadef total_nodes = (2 * total_external_nodes) - 1
val total_nodes : size_t total_nodes =
pred (g1u2u 2u * total_external_nodes)
 
(* We will ignore index 0 of the winners tree arrays. *)
stadef winners_size = total_nodes + 1
val winners_size : size_t winners_size = succ total_nodes
 
(* An exercise for the reader is to write a proof that
winners_size <= 2 * power, so one can get rid of the
runtime assertion here: *)
val () = $effmask_exn assertloc (winners_size <= 2 * power)
 
prval @(winvals_left, winvals_right) =
array_v_split {link_t?} {..} {2 * power} {winners_size}
(view@ winvals)
prval () = view@ winvals := winvals_left
 
prval @(winlinks_left, winlinks_right) =
array_v_split {link_t?} {..} {2 * power} {winners_size}
(view@ winlinks)
prval () = view@ winlinks := winlinks_left
 
val () = array_initize_elt<link_t> (winvals, winners_size,
link_nil)
val () = array_initize_elt<link_t> (winlinks, winners_size,
link_nil)
 
 
(* - - - - - - - - - - - - - - - - - - - - - - - - - - *)
(* Record which pile a winner will have come from. *)
 
fun
init_pile_links
{i : nat | i <= num_piles}
.<num_piles - i>.
(winlinks : &array (link_t, winners_size),
i : size_t i)
:<!wrt> void =
if i <> num_piles then
begin
winlinks[total_external_nodes + i] := succ i;
init_pile_links (winlinks, succ i)
end
 
val () = init_pile_links (winlinks, g1u2u 0u)
 
(* - - - - - - - - - - - - - - - - - - - - - - - - - - *)
(* The top of each pile becomes a starting competitor. *)
 
fun
init_competitors
{i : nat | i <= num_piles}
.<num_piles - i>.
(winvals : &array (link_t, winners_size),
piles : &array (link_t, len),
i : size_t i)
:<!wrt> void =
if i <> num_piles then
begin
winvals[total_external_nodes + i] := piles[i];
init_competitors (winvals, piles, succ i)
end
val () = init_competitors (winvals, piles, g1u2u 0u)
 
(* - - - - - - - - - - - - - - - - - - - - - - - - - - *)
(* Discard the top of each pile. *)
 
fun
discard_tops {i : nat | i <= num_piles}
.<num_piles - i>.
(piles : &array (link_t, len),
links : &array (link_t, len),
i : size_t i)
:<!wrt> void =
if i <> num_piles then
let
val link = piles[i]
 
(* None of the piles should have been empty. *)
val () = $effmask_exn assertloc (link <> g1u2u 0u)
in
piles[i] := links[pred link];
discard_tops (piles, links, succ i)
end
 
val () = discard_tops (piles, links, g1u2u 0u)
 
(* - - - - - - - - - - - - - - - - - - - - - - - - - - *)
(* How to play a game. *)
fn
play_game {i : int | 2 <= i; i <= total_nodes}
(arr : &RD(array (a, n)),
winvals : &array (link_t, winners_size),
i : size_t i)
:<> [iwinner : pos | iwinner <= total_nodes]
size_t iwinner =
let
macdef lt = patience_sort$lt<a>
 
fn
find_opponent {i : int | 2 <= i; i <= total_nodes}
(i : size_t i)
:<> [j : int | 2 <= j; j <= total_nodes]
size_t j =
let
(* The prelude contains bitwise operations only for
non-dependent unsigned integer. We will not bother to
add them ourselves, but instead go back and forth
between dependent and non-dependent. *)
val i0 = g0ofg1 i
val j0 = g0uint_lxor<size_kind> (i0, g0u2u 1u)
val j = g1ofg0 j0
 
(* We have no proof the opponent is in the proper
range. Create a "proof" by runtime checks. *)
val () = $effmask_exn assertloc (g1u2u 2u <= j)
val () = $effmask_exn assertloc (j <= total_nodes)
in
j
end
 
val j = find_opponent i
val winner_i = winvals[i]
and winner_j = winvals[j]
in
if winner_i = link_nil then
j
else if winner_j = link_nil then
i
else
let
val i1 = pred winner_i + ifirst
and i2 = pred winner_j + ifirst
prval () = lemma_g1uint_param i1
prval () = lemma_g1uint_param i2
in
if arr[i2] \lt arr[i1] then j else i
end
end
 
(* - - - - - - - - - - - - - - - - - - - - - - - - - - *)
 
fun
build_tree {istart : pos | istart <= total_external_nodes}
.<istart>.
(arr : &RD(array (a, n)),
winvals : &array (link_t, winners_size),
winlinks : &array (link_t, winners_size),
istart : size_t istart)
:<!wrt> void =
if istart <> 1 then
let
fun
play_initial_games
{i : int | istart <= i; i <= (2 * istart) + 1}
.<(2 * istart) + 1 - i>.
(arr : &RD(array (a, n)),
winvals : &array (link_t, winners_size),
winlinks : &array (link_t, winners_size),
i : size_t i)
:<!wrt> void =
if i <= pred (istart + istart) then
let
val iwinner = play_game (arr, winvals, i)
and i2 = i / g1u2u 2u
in
winvals[i2] := winvals[iwinner];
winlinks[i2] := winlinks[iwinner];
play_initial_games (arr, winvals, winlinks,
succ (succ i))
end
in
play_initial_games (arr, winvals, winlinks, istart);
build_tree (arr, winvals, winlinks, istart / g1u2u 2u)
end
 
val () = build_tree (arr, winvals, winlinks, total_external_nodes)
 
(* - - - - - - - - - - - - - - - - - - - - - - - - - - *)
 
fun
replay_games {i : pos | i <= total_nodes}
.<i>.
(arr : &RD(array (a, n)),
winvals : &array (link_t, winners_size),
winlinks : &array (link_t, winners_size),
i : size_t i)
:<!wrt> void =
if i <> g1u2u 1u then
let
val iwinner = play_game (arr, winvals, i)
and i2 = i / g1u2u 2u
in
winvals[i2] := winvals[iwinner];
winlinks[i2] := winlinks[iwinner];
replay_games (arr, winvals, winlinks, i2)
end
 
fun
merge {isorted : nat | isorted <= len}
{p_sorted : addr}
.<len - isorted>.
(pf_sorted : !array_v (index_t?, p_sorted,
len - isorted)
>> array_v (index_t, p_sorted,
len - isorted) |
arr : &RD(array (a, n)),
piles : &array (link_t, len),
links : &array (link_t, len),
winvals : &array (link_t, winners_size),
winlinks : &array (link_t, winners_size),
p_sorted : ptr p_sorted,
isorted : size_t isorted)
:<!wrt> void =
(* This function not only fills in the "sorted" array, but
transforms it from "uninitialized" to "initialized". *)
if isorted <> len then
let
prval @(pf_elem, pf_rest) = array_v_uncons pf_sorted
val winner = winvals[1]
val () = $effmask_exn assertloc (winner <> link_nil)
val () = !p_sorted := pred winner + ifirst
 
(* Move to the next element in the winner's pile. *)
val ilink = winlinks[1]
val () = $effmask_exn assertloc (ilink <> link_nil)
val inext = piles[pred ilink]
val () = (if inext <> link_nil then
piles[pred ilink] := links[pred inext])
 
(* Replay games, with the new element as a competitor. *)
val i = (total_nodes / g1u2u 2u) + ilink
val () = $effmask_exn assertloc (i <= total_nodes)
val () = winvals[i] := inext
val () = replay_games (arr, winvals, winlinks, i)
 
val () = merge (pf_rest |
arr, piles, links, winvals, winlinks,
ptr_succ<index_t> p_sorted, succ isorted)
prval () = pf_sorted := array_v_cons (pf_elem, pf_rest)
in
end
else
let
prval () = pf_sorted :=
array_v_unnil_nil{index_t?, index_t} pf_sorted
in
end
 
val () = merge (view@ sorted |
arr, piles, links, winvals, winlinks,
addr@ sorted, i2sz 0)
 
prval () =
array_uninitize_without_doing_anything<link_t>
(winvals, winners_size)
prval () =
array_uninitize_without_doing_anything<link_t>
(winlinks, winners_size)
prval () = view@ winvals :=
array_v_unsplit (view@ winvals, winvals_right)
prval () = view@ winlinks :=
array_v_unsplit (view@ winlinks, winlinks_right)
in
end
 
implement {a}
patience_sort_given_workspaces
{ifirst, len} {n} {power}
{n_piles} {n_links} {n_winv} {n_winl}
(pf_exp2 | arr, ifirst, len, power,
piles, links, winvals, winlinks,
sorted) =
let
prval () = lemma_g1uint_param ifirst
prval () = lemma_g1uint_param len
 
typedef index_t = index_t (ifirst, len)
typedef link_t = link_t (ifirst, len)
in
if len = i2sz 0 then
let
prval () = view@ sorted :=
array_v_unnil_nil{index_t?, index_t} (view@ sorted)
in
end
else
let
prval @(piles_left, piles_right) =
array_v_split {link_t?} {..} {n_piles} {len} (view@ piles)
prval () = view@ piles := piles_left
 
prval @(links_left, links_right) =
array_v_split {link_t?} {..} {n_links} {len} (view@ links)
prval () = view@ links := links_left
 
prval @(winvals_left, winvals_right) =
array_v_split {link_t?} {..} {n_winv} {2 * power}
(view@ winvals)
prval () = view@ winvals := winvals_left
 
prval @(winlinks_left, winlinks_right) =
array_v_split {link_t?} {..} {n_winl} {2 * power}
(view@ winlinks)
prval () = view@ winlinks := winlinks_left
 
val num_piles =
deal {ifirst, len} {n} (ifirst, len, arr, piles, links)
prval () = lemma_g1uint_param num_piles
val () = $effmask_exn assertloc (num_piles <> i2sz 0)
 
val () =
k_way_merge {ifirst, len} {n} {..} {power}
(pf_exp2 | arr, ifirst, len, num_piles, power,
piles, links, winvals, winlinks,
sorted)
 
prval () =
array_uninitize_without_doing_anything<link_t>
(piles, len)
prval () =
array_uninitize_without_doing_anything<link_t>
(links, len)
 
prval () = view@ piles :=
array_v_unsplit (view@ piles, piles_right)
prval () = view@ links :=
array_v_unsplit (view@ links, links_right)
prval () = view@ winvals :=
array_v_unsplit (view@ winvals, winvals_right)
prval () = view@ winlinks :=
array_v_unsplit (view@ winlinks, winlinks_right)
in
end
end
 
(* ================================================================ *)
(* An interface that provides the workspaces. If the subarray to *)
(* be sorted is small enough, stack storage will be used. *)
 
#define LEN_THRESHOLD 128
#define WINNERS_SIZE 256
 
prval () = prop_verify {WINNERS_SIZE == 2 * LEN_THRESHOLD} ()
 
local
prval pf_exp2 = EXP2bas () (* 1*)
prval pf_exp2 = EXP2ind pf_exp2 (* 2 *)
prval pf_exp2 = EXP2ind pf_exp2 (* 4 *)
prval pf_exp2 = EXP2ind pf_exp2 (* 8 *)
prval pf_exp2 = EXP2ind pf_exp2 (* 16 *)
prval pf_exp2 = EXP2ind pf_exp2 (* 32 *)
prval pf_exp2 = EXP2ind pf_exp2 (* 64 *)
prval pf_exp2 = EXP2ind pf_exp2 (* 128 *)
in
prval pf_exp2_for_stack_storage = pf_exp2
end
 
implement {a}
patience_sort_with_its_own_workspaces
{ifirst, len} {n} (arr, ifirst, len, sorted) =
let
prval () = lemma_g1uint_param ifirst
prval () = lemma_g1uint_param len
 
typedef link_t = link_t (ifirst, len)
 
fn
sort {ifirst, len : int | 0 <= ifirst}
{n : int | ifirst + len <= n}
{power : int | len <= power}
{n_piles : int | len <= n_piles}
{n_links : int | len <= n_links}
{n_winv : int | 2 * power <= n_winv}
{n_winl : int | 2 * power <= n_winl}
(pf_exp2 : [exponent : nat] EXP2 (exponent, power) |
arr : &RD(array (a, n)),
ifirst : size_t ifirst,
len : size_t len,
power : size_t power,
piles : &array (link_t (ifirst, len)?, n_piles) >> _,
links : &array (link_t (ifirst, len)?, n_links) >> _,
winvals : &array (link_t (ifirst, len)?, n_winv) >> _,
winlinks : &array (link_t (ifirst, len)?, n_winl) >> _,
sorted : &array (index_t (ifirst, len)?, len)
>> array (index_t (ifirst, len), len))
:<!wrt> void =
patience_sort_given_workspaces<a>
{ifirst, len} {n} {power}
{n_piles} {n_links} {n_winv} {n_winl}
(pf_exp2 | arr, ifirst, len, power, piles, links,
winvals, winlinks, sorted)
in
if len <= i2sz LEN_THRESHOLD then
let
var piles : array (link_t?, LEN_THRESHOLD)
var links : array (link_t?, LEN_THRESHOLD)
var winvals : array (link_t?, WINNERS_SIZE)
var winlinks : array (link_t?, WINNERS_SIZE)
in
sort (pf_exp2_for_stack_storage |
arr, ifirst, len, i2sz LEN_THRESHOLD,
piles, links, winvals, winlinks, sorted)
end
else
let
val @(pf_piles, pfgc_piles | p_piles) =
array_ptr_alloc<link_t> len
val @(pf_links, pfgc_links | p_links) =
array_ptr_alloc<link_t> len
 
val @(pf_exp2 | power) = next_power_of_two<size_kind> len
 
val @(pf_winvals, pfgc_winvals | p_winvals) =
array_ptr_alloc<link_t> (power + power)
val @(pf_winlinks, pfgc_winlinks | p_winlinks) =
array_ptr_alloc<link_t> (power + power)
 
macdef piles = !p_piles
macdef links = !p_links
macdef winvals = !p_winvals
macdef winlinks = !p_winlinks
in
sort (pf_exp2 |
arr, ifirst, len, power, piles, links,
winvals, winlinks, sorted);
array_ptr_free (pf_piles, pfgc_piles | p_piles);
array_ptr_free (pf_links, pfgc_links | p_links);
array_ptr_free (pf_winvals, pfgc_winvals | p_winvals);
array_ptr_free (pf_winlinks, pfgc_winlinks | p_winlinks)
end
end
 
(* ================================================================ *)
(* A demonstration program. *)
 
fn {a : t@ype}
find_length {n : int}
(lst : list (a, n))
:<> [m : int | m == n] size_t m =
let
prval () = lemma_list_param lst
in
g1i2u (length lst)
end
 
implement
main0 () =
let
implement
patience_sort$lt<int> (x, y) =
x < y
 
val example_list =
$list (22, 15, 98, 82, 22, 4, 58, 70, 80, 38, 49, 48, 46, 54,
93, 8, 54, 2, 72, 84, 86, 76, 53, 37, 90)
 
val ifirst = i2sz 10
val [len : int] len = find_length example_list
 
#define ARRSZ 100
val () = assertloc (i2sz 10 + len <= ARRSZ)
 
var arr : array (int, ARRSZ)
val () = array_initize_elt<int> (arr, i2sz ARRSZ, 0)
 
prval @(pf_left, pf_right) =
array_v_split {int} {..} {ARRSZ} {10} (view@ arr)
prval @(pf_middle, pf_right) =
array_v_split {int} {..} {90} {len} pf_right
 
val p = ptr_add<int> (addr@ arr, 10)
val () = array_copy_from_list<int> (!p, example_list)
 
prval pf_right = array_v_unsplit (pf_middle, pf_right)
prval () = view@ arr := array_v_unsplit (pf_left, pf_right)
 
typedef index_t = patience_sort_index (10, len)
 
var sorted : array (index_t, ARRSZ)
val () = array_initize_elt<index_t> (sorted, i2sz ARRSZ,
g1u2u 10u)
prval @(sorted_left, sorted_right) =
array_v_split {index_t} {..} {ARRSZ} {len} (view@ sorted)
prval () = view@ sorted := sorted_left
 
val () = patience_sort<int> (arr, i2sz 10, len, sorted)
 
prval () = view@ sorted :=
array_v_unsplit (view@ sorted, sorted_right)
 
var i : [i : nat | i <= len] size_t i
in
print! ("unsorted ");
for (i := i2sz 0; i <> len; i := succ i)
print! (" ", arr[i2sz 10 + i]);
println! ();
 
print! ("sorted ");
for (i := i2sz 0; i <> len; i := succ i)
print! (" ", arr[sorted[i]]);
println! ()
end
 
(*------------------------------------------------------------------*)</syntaxhighlight>
 
{{out}}
<pre>$ patscc -O3 -DATS_MEMALLOC_LIBC patience_sort_task_provided_storage.dats && ./a.out
unsorted 22 15 98 82 22 4 58 70 80 38 49 48 46 54 93 8 54 2 72 84 86 76 53 37 90
sorted 2 4 8 15 22 22 37 38 46 48 49 53 54 54 58 70 72 76 80 82 84 86 90 93 98</pre>
Line 1,823 ⟶ 2,748:
The mergesort proves the result has the same length as the original, but this patience sort does not.
 
<langsyntaxhighlight lang="ats">//--------------------------------------------------------------------
//
// A patience sort for 32-bit signed integers.
Line 2,194 ⟶ 3,119:
end
 
(*------------------------------------------------------------------*)</langsyntaxhighlight>
 
{{out}}
Line 2,202 ⟶ 3,127:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">PatienceSort(A){
P:=0, Pile:=[], Result:=[]
for k, v in A
Line 2,261 ⟶ 3,186:
}
return Result
}</langsyntaxhighlight>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">Test := [[4, 65, 2, -31, 0, 99, 83, 782, 1]
,["n", "o", "n", "z", "e", "r", "o", "s", "u", "m"]
,["dog", "cow", "cat", "ape", "ant", "man", "pig", "ass", "gnu"]]
Line 2,273 ⟶ 3,198:
MsgBox % "[" Trim(output, ", ") "]"
}
return</langsyntaxhighlight>
{{out}}
<pre>Pile1 = [-31, 2, 4]
Line 2,296 ⟶ 3,221:
=={{header|C}}==
Takes integers as input, prints out usage on incorrect invocation
<syntaxhighlight lang="c">
<lang C>
#include<stdlib.h>
#include<stdio.h>
Line 2,362 ⟶ 3,287:
return 0;
}
</syntaxhighlight>
</lang>
Invocation and output :
<pre>
Line 2,370 ⟶ 3,295:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <vector>
#include <stack>
Line 2,433 ⟶ 3,358:
std::cout << std::endl;
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>-31, 0, 1, 2, 4, 65, 83, 99, 782, </pre>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">
(defn patience-insert
"Inserts a value into the sequence where each element is a stack.
Line 2,504 ⟶ 3,429:
;; Sort the test sequence and print it
(println (patience-sort [4 65 2 -31 0 99 83 782 1]))
</syntaxhighlight>
</lang>
{{out}}
<pre>[-31 0 1 2 4 65 83 99 782]</pre>
Line 2,510 ⟶ 3,435:
=={{header|D}}==
{{trans|Python}}
<langsyntaxhighlight lang="d">import std.stdio, std.array, std.range, std.algorithm;
 
void patienceSort(T)(T[] items) /*pure nothrow @safe*/
Line 2,538 ⟶ 3,463:
assert(data.isSorted);
data.writeln;
}</langsyntaxhighlight>
{{out}}
<pre>[-31, 0, 1, 2, 4, 65, 83, 99, 782]</pre>
 
=={{header|Elixir}}==
<langsyntaxhighlight lang="elixir">defmodule Sort do
def patience_sort(list) do
piles = deal_pile(list, [])
Line 2,577 ⟶ 3,502:
end
 
IO.inspect Sort.patience_sort [4, 65, 2, -31, 0, 99, 83, 782, 1]</langsyntaxhighlight>
 
{{out}}
Line 2,598 ⟶ 3,523:
 
 
<langsyntaxhighlight lang="fortran">module rosetta_code_patience_sort
implicit none
private
Line 2,893 ⟶ 3,818:
end function less
 
end program patience_sort_task</langsyntaxhighlight>
 
{{out}}
Line 2,902 ⟶ 3,827:
=={{header|Go}}==
This version is written for int slices, but can be easily modified to sort other types.
<langsyntaxhighlight lang="go">package main
 
import (
Line 2,960 ⟶ 3,885:
patience_sort(a)
fmt.Println(a)
}</langsyntaxhighlight>
{{out}}
<pre>[-31 0 1 2 4 65 83 99 782]</pre>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Control.Monad.ST
import Control.Monad
import Data.Array.ST
Line 3,012 ⟶ 3,937:
 
main :: IO ()
main = print $ patienceSort [4, 65, 2, -31, 0, 99, 83, 782, 1]</langsyntaxhighlight>
{{out}}
<pre>[-31,0,1,2,4,65,83,99,782]</pre>
Line 3,020 ⟶ 3,945:
 
 
<langsyntaxhighlight lang="icon">#---------------------------------------------------------------------
#
# Patience sorting.
Line 3,254 ⟶ 4,179:
end
 
#---------------------------------------------------------------------</langsyntaxhighlight>
 
{{out}}
Line 3,263 ⟶ 4,188:
=={{header|J}}==
The data structure for append and transfer are as x argument a list with [[wp:CAR_and_CDR|cdr]] as the stacks and [[wp:CAR_and_CDR|car]] as the data to sort or growing sorted list; and the y argument being the index of pile to operate on. New piles are created by using the new value, accomplished by selecting the entire x argument as a result. Filtering removes empty stacks during unpiling.
<syntaxhighlight lang="j">
<lang J>
Until =: 2 :'u^:(0=v)^:_'
Filter =: (#~`)(`:6)
Line 3,290 ⟶ 4,215:
unpile_demo =: >@:{.@:((0<#S:0)Filter@:(transfer Show smallest)Until(1=#))@:(a:&,)
patience_sort_demo =: unpile_demo@:pile_demo
</syntaxhighlight>
</lang>
 
<pre>
Line 3,401 ⟶ 4,326:
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.util.*;
 
public class PatienceSort {
Line 3,438 ⟶ 4,363:
System.out.println(Arrays.toString(a));
}
}</langsyntaxhighlight>
{{out}}
<pre>[-31, 0, 1, 2, 4, 65, 83, 99, 782]</pre>
 
=={{header|Javascript}}==
<langsyntaxhighlight Javascriptlang="javascript">const patienceSort = (nums) => {
const piles = []
 
Line 3,476 ⟶ 4,401:
}
console.log(patienceSort([10,6,-30,9,18,1,-20]));
</syntaxhighlight>
</lang>
{{out}}
<pre>[-30, -20, 1, 6, 9, 10, 18]</pre>
Line 3,484 ⟶ 4,409:
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
<langsyntaxhighlight lang="jq">def patienceSort:
length as $size
| if $size < 2 then .
Line 3,519 ⟶ 4,444:
["n", "o", "n", "z", "e", "r", "o", "s", "u", "m"],
["dog", "cow", "cat", "ape", "ant", "man", "pig", "ass", "gnu"]
| patienceSort</langsyntaxhighlight>
{{out}}
<pre>
Line 3,528 ⟶ 4,453:
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">function patiencesort(list::Vector{T}) where T
piles = Vector{Vector{T}}()
for n in list
Line 3,556 ⟶ 4,481:
println(patiencesort(rand(collect(1:1000), 12)))
</langsyntaxhighlight>{{out}}
<pre>
[186, 243, 255, 257, 427, 486, 513, 613, 657, 734, 866, 907]
Line 3,562 ⟶ 4,487:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.2
 
fun <T : Comparable<T>> patienceSort(arr: Array<T>) {
Line 3,603 ⟶ 4,528:
patienceSort(sArr)
println(sArr.contentToString())
}</langsyntaxhighlight>
 
{{out}}
Line 3,620 ⟶ 4,545:
 
 
<langsyntaxhighlight lang="mercury">:- module patience_sort_task.
 
:- interface.
Line 3,983 ⟶ 4,908:
%%% mode: mercury
%%% prolog-indent-width: 2
%%% end:</langsyntaxhighlight>
 
{{out}}
Line 4,000 ⟶ 4,925:
Unlike the Ada upon which it is based, this implementation of patience sort is specific to arrays of integers, rather than generic.
 
<langsyntaxhighlight lang="modula2">MODULE PatienceSortTask;
 
FROM STextIO IMPORT WriteString;
Line 4,279 ⟶ 5,204:
END;
WriteLn;
END PatienceSortTask.</langsyntaxhighlight>
 
{{out}}
Line 4,287 ⟶ 5,212:
 
=={{header|Nim}}==
<langsyntaxhighlight Nimlang="nim">import std/decls
 
func patienceSort[T](a: var openArray[T]) =
Line 4,327 ⟶ 5,252:
var sArray = ["dog", "cow", "cat", "ape", "ant", "man", "pig", "ass", "gnu"]
sArray.patienceSort()
echo sArray</langsyntaxhighlight>
 
{{out}}
Line 4,335 ⟶ 5,260:
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">module PatienceSortFn (Ord : Set.OrderedType) : sig
val patience_sort : Ord.t list -> Ord.t list
end = struct
Line 4,385 ⟶ 5,310:
let patience_sort n =
merge_piles (sort_into_piles n)
end</langsyntaxhighlight>
Usage:
<pre># module IntPatienceSort = PatienceSortFn
Line 4,400 ⟶ 5,325:
{{works with|Free Pascal Compiler|3.2.2}}
 
<langsyntaxhighlight Pascallang="pascal">PatienceSortTask (Output);
 
CONST MaxSortSize = 1024; { A power of two. }
Line 4,677 ⟶ 5,602:
END;
WriteLn
END.</langsyntaxhighlight>
 
{{out}}
Line 4,692 ⟶ 5,617:
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight Perllang="perl">sub patience_sort {
my @s = [shift];
for my $card (@_) {
Line 4,712 ⟶ 5,637:
 
print join ' ', patience_sort qw(4 3 6 2 -1 13 12 9);
</syntaxhighlight>
</lang>
{{out}}
<pre>-1 2 3 4 6 9 12 13</pre>
 
=={{header|Phix}}==
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Line 4,756 ⟶ 5,681:
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">patience_sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]),{</span><span style="color: #004600;">pp_IntCh</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 4,766 ⟶ 5,691:
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php"><?php
class PilesHeap extends SplMinHeap {
public function compare($pile1, $pile2) {
Line 4,808 ⟶ 5,733:
patience_sort($a);
print_r($a);
?></langsyntaxhighlight>
{{out}}
<pre>Array
Line 4,824 ⟶ 5,749:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de leftmost (Lst N H)
(let L 1
(while (<= L H)
Line 4,857 ⟶ 5,782:
(patience (4 65 2 -31 0 99 83 782 1)) )
(bye)</langsyntaxhighlight>
 
=={{header|Prolog}}==
<langsyntaxhighlight lang="prolog">patience_sort(UnSorted,Sorted) :-
make_piles(UnSorted,[],Piled),
merge_piles(Piled,[],Sorted).
Line 4,888 ⟶ 5,813:
merge_pile([N|T1],[P|T2],[N|R]) :-
N < P,
merge_pile(T1,[P|T2],R).</langsyntaxhighlight>
{{out}}
<pre>
Line 4,897 ⟶ 5,822:
=={{header|Python}}==
{{works with|Python|2.7+ and 3.2+}} (for <tt>functools.total_ordering</tt>)
<langsyntaxhighlight lang="python">from functools import total_ordering
from bisect import bisect_left
from heapq import merge
Line 4,923 ⟶ 5,848:
a = [4, 65, 2, -31, 0, 99, 83, 782, 1]
patience_sort(a)
print a</langsyntaxhighlight>
{{out}}
<pre>[-31, 0, 1, 2, 4, 65, 83, 99, 782]</pre>
Line 4,931 ⟶ 5,856:
uses <code>bsearchwith</code> from [[Binary search#Quackery]] and <code>merge</code> from [[Merge sort#Quackery]].
 
<langsyntaxhighlight Quackerylang="quackery"> [ dip [ 0 over size rot ]
nested bsearchwith
[ -1 peek
Line 4,960 ⟶ 5,885:
' [ 0 1 2 3 4 5 6 7 8 9 ]
shuffle dup echo cr
patience-sort echo</langsyntaxhighlight>
 
{{out}}
Line 4,969 ⟶ 5,894:
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">#lang racket/base
(require racket/match racket/list)
 
Line 5,000 ⟶ 5,925:
[((cons ush ust) least) (scan ush (cons least seens) ust)]))])))
 
(patience-sort (shuffle (for/list ((_ 10)) (random 7))) <)</langsyntaxhighlight>
{{out}}
<pre>'(1 1 2 2 2 3 4 4 4 5)</pre>
Line 5,007 ⟶ 5,932:
(formerly Perl 6)
{{works with|rakudo|2015-10-22}}
<syntaxhighlight lang="raku" perl6line>multi patience(*@deck) {
my @stacks;
for @deck -> $card {
Line 5,023 ⟶ 5,948:
}
 
say ~patience ^10 . pick(*);</langsyntaxhighlight>
{{out}}
<pre>0 1 2 3 4 5 6 7 8 9</pre>
Line 5,031 ⟶ 5,956:
 
Duplicates are also sorted correctly.
<langsyntaxhighlight lang="rexx">/*REXX program sorts a list of things (or items) using the patience sort algorithm. */
parse arg xxx; say ' input: ' xxx /*obtain a list of things from the C.L.*/
n= words(xxx); #= 0; !.= 1 /*N: # of things; #: number of piles*/
Line 5,055 ⟶ 5,980:
end /*k*/ /* [↑] each iteration finds a low item*/
/* [↓] string $ has a leading blank.*/
say 'output: ' strip($) /*stick a fork in it, we're all done. */</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the input of: &nbsp; <tt> 4 65 2 -31 0 99 83 782 7.88 1e1 1 </tt>}}
<pre>
Line 5,068 ⟶ 5,993:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">class Array
def patience_sort
piles = []
Line 5,091 ⟶ 6,016:
 
a = [4, 65, 2, -31, 0, 99, 83, 782, 1]
p a.patience_sort</langsyntaxhighlight>
 
{{out}}
Line 5,100 ⟶ 6,025:
{{libheader|Scala Time complexity O(n log n)}}
{{works with|Scala|2.13}}
<langsyntaxhighlight Scalalang="scala">import scala.collection.mutable
 
object PatienceSort extends App {
Line 5,136 ⟶ 6,061:
 
println(sort(List(4, 65, 2, -31, 0, 99, 83, 782, 1)))
}</langsyntaxhighlight>
 
=={{header|Scheme}}==
Line 5,147 ⟶ 6,072:
 
 
<langsyntaxhighlight lang="scheme">(define-library (rosetta-code k-way-merge)
 
(export k-way-merge)
Line 5,380 ⟶ 6,305:
(newline)
 
;;--------------------------------------------------------------------</langsyntaxhighlight>
 
{{out}}
Line 5,388 ⟶ 6,313:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func patience(deck) {
var stacks = [];
deck.each { |card|
Line 5,410 ⟶ 6,335:
 
var a = [4, 65, 2, -31, 0, 99, 83, 782, 1]
say patience(a)</langsyntaxhighlight>
{{out}}
<pre>
Line 5,418 ⟶ 6,343:
=={{header|Standard ML}}==
{{works with|SML/NJ}}
<langsyntaxhighlight lang="sml">structure PilePriority = struct
type priority = int
fun compare (x, y) = Int.compare (y, x) (* we want min-heap *)
Line 5,472 ⟶ 6,397:
 
fun patience_sort n =
merge_piles (sort_into_piles n)</langsyntaxhighlight>
Usage:
<pre>- patience_sort [4, 65, 2, ~31, 0, 99, 83, 782, 1];
Line 5,480 ⟶ 6,405:
{{works with|Tcl|8.6}}
This uses the <code>-bisect</code> option to <code>lsearch</code> in order to do an efficient binary search (in combination with <code>-index end</code>, which means that the search is indexed by the end of the sublist).
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
proc patienceSort {items} {
Line 5,513 ⟶ 6,438:
}
return $result
}</langsyntaxhighlight>
Demonstrating:
<langsyntaxhighlight lang="tcl">puts [patienceSort {4 65 2 -31 0 99 83 782 1}]</langsyntaxhighlight>
{{out}}
<pre>-31 0 1 2 4 65 83 99 782</pre>
Line 5,522 ⟶ 6,447:
{{trans|Kotlin}}
{{libheader|Wren-sort}}
<langsyntaxhighlight ecmascriptlang="wren">import "./sort" for Cmp
 
var patienceSort = Fn.new { |a|
Line 5,566 ⟶ 6,491:
var sa = ["dog", "cow", "cat", "ape", "ant", "man", "pig", "ass", "gnu"]
patienceSort.call(sa)
System.print(sa)</langsyntaxhighlight>
 
{{out}}
Line 5,576 ⟶ 6,501:
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn patienceSort(ns){
piles:=L();
foreach n in (ns){ newPile:=True; // create list of sorted lists
Line 5,592 ⟶ 6,517:
}
r.close();
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">T(T(3,2,6,4,3,5,1),
T(4,65,2,-31,0,99,83,782,1),
T(0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15),
"foobar")
.pump(Console.println,patienceSort);</langsyntaxhighlight>
{{out}}
<pre>
9,485

edits