How it works
Distribution sort using card game patience rules.
Implementation
function patienceSort(arr, stats) { const n = arr.length; let piles = []; for (let i = 0; i < n; i++) { let card = arr[i]; let left = 0, right = piles.length; while (left < right) { let mid = Math.floor((left + right) / 2); if (piles[mid][piles[mid].length - 1] > card) right = mid; else left = mid + 1; } if (left === piles.length) piles.push([card]); else piles[left].push(card); compare(i, i); } let outIdx = 0; while (piles.length > 0) { let minPile = 0; for (let i = 1; i < piles.length; i++) { if (piles[i][piles[i].length - 1] < piles[minPile][piles[minPile].length - 1]) { minPile = i; } } let val = piles[minPile].pop(); if (piles[minPile].length === 0) piles.splice(minPile, 1); arr[outIdx] = val; write(outIdx, val); markSorted(outIdx); outIdx++; } }
def patienceSort(arr, stats): piles = [] for i in range(n): card = arr[i] left = 0 right = len(piles) while (left < right): mid = ((left + right) // 2) if (piles[mid][(len(piles[mid]) - 1)] > card): right = mid else: left = (mid + 1) if (left == len(piles)): piles.append([card]) else: piles[left].append(card) compare(i, i) outIdx = 0 while (len(piles) > 0): minPile = 0 for i in range(1, len(piles)): if (piles[i][(len(piles[i]) - 1)] < piles[minPile][(len(piles[minPile]) - 1)]): minPile = i val = piles[minPile].pop() if (len(piles[minPile]) == 0): piles.pop(minPile) arr[outIdx] = val write(outIdx, val) markSorted(outIdx) outIdx += 1
#include <vector> #include <algorithm> void sort(std::vector<int>& arr, int n, int& comparisons, int& swaps) { std::vector<int> piles; for(int i=0; i<n; i++) { int card = arr[i]; int left = 0; int right = (int)piles.size(); while((left < right)) { int mid = ((left + right) / 2); if((piles[mid][(n - 1)] > card)) { right = mid; } else { left = (mid + 1); } } if((left == (int)piles.size())) { piles.push_back({card}); } else { piles[left].push_back(card); } compare(i, i); } int outIdx = 0; while(((int)piles.size() > 0)) { int minPile = 0; for(int i=1; i<(int)piles.size(); i++) { if((piles[i][(n - 1)] < piles[minPile][(n - 1)])) { minPile = i; } } int val = piles[minPile].back(); if((n == 0)) { piles.erase(piles.begin() + minPile); } arr[outIdx] = val; write(outIdx, val); markSorted(outIdx); outIdx++; } }
public void Sort(int[] arr, int n, dynamic stats) { var piles = new List<int>(); for(int i=0; i<n; i++) { int card = arr[i]; int left = 0; int right = piles.Count; while((left < right)) { int mid = ((left + right) / 2); if((piles[mid][(n - 1)] > card)) { right = mid; } else { left = (mid + 1); } } if((left == piles.Count)) { piles.Add(new int[] {card}); } else { piles[left][piles[left]_len++] = card; } compare(i, i); } int outIdx = 0; while((piles.Count > 0)) { int minPile = 0; for(int i=1; i<piles.Count; i++) { if((piles[i][(n - 1)] < piles[minPile][(n - 1)])) { minPile = i; } } int val = piles[minPile][--piles[minPile]_len]; if((n == 0)) { piles.RemoveAt(minPile); } arr[outIdx] = val; write(outIdx, val); markSorted(outIdx); outIdx++; } }
#include <stdio.h> #include <stdlib.h> void sort(int arr[], int n, int* comparisons, int* swaps) { int* piles = (int*)malloc(n * sizeof(int)); int piles_len = 0; for(int i=0; i<n; i++) { int card = arr[i]; int left = 0; int right = piles_len; while((left < right)) { int mid = ((left + right) / 2); if((piles[mid][(n - 1)] > card)) { right = mid; } else { left = (mid + 1); } } if((left == piles_len)) { piles[piles_len++] = {card}; } else { piles[left][piles[left]_len++] = card; } compare(i, i); } int outIdx = 0; while((piles_len > 0)) { int minPile = 0; for(int i=1; i<piles_len; i++) { if((piles[i][(n - 1)] < piles[minPile][(n - 1)])) { minPile = i; } } int val = piles[minPile][--piles[minPile]_len]; if((n == 0)) { piles_remove(minPile); } arr[outIdx] = val; write(outIdx, val); markSorted(outIdx); outIdx++; } }