Data update
This commit is contained in:
parent
72eb4943cb
commit
4d5544505c
2347 changed files with 62432 additions and 16731 deletions
|
|
@ -0,0 +1,29 @@
|
|||
proc patience_sort &nums[] .
|
||||
for num in nums[]
|
||||
for p to len piles[][]
|
||||
if num >= piles[p][len piles[p][]]
|
||||
piles[p][] &= num
|
||||
break 1
|
||||
.
|
||||
.
|
||||
if p > len piles[][] : piles[][] &= [ num ]
|
||||
.
|
||||
for i to len nums[]
|
||||
dest = 1
|
||||
for p = 2 to len piles[][]
|
||||
if piles[p][1] < piles[dest][1] : dest = p
|
||||
.
|
||||
nums[i] = piles[dest][1]
|
||||
for j = 2 to len piles[dest][]
|
||||
piles[dest][j - 1] = piles[dest][j]
|
||||
.
|
||||
len piles[dest][] -1
|
||||
if len piles[dest][] = 0
|
||||
swap piles[dest][] piles[$][]
|
||||
len piles[][] -1
|
||||
.
|
||||
.
|
||||
.
|
||||
nums[] = [ 10 6 -30 9 18 1 -20 ]
|
||||
patience_sort nums[]
|
||||
print nums[]
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
// We define a custom Pile struct instead of using Stack
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
struct Pile<T: Ord> {
|
||||
values: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T: Ord> Pile<T> {
|
||||
fn new(value: T) -> Self {
|
||||
let mut values = Vec::new();
|
||||
values.push(value);
|
||||
Pile { values }
|
||||
}
|
||||
|
||||
fn push(&mut self, value: T) {
|
||||
self.values.push(value);
|
||||
}
|
||||
|
||||
fn pop(&mut self) -> Option<T> {
|
||||
self.values.pop()
|
||||
}
|
||||
|
||||
fn top(&self) -> Option<&T> {
|
||||
self.values.last()
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
self.values.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
// For binary heap ordering (min-heap)
|
||||
impl<T: Ord> Ord for Pile<T> {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
// Reverse the ordering for min-heap
|
||||
other.top().cmp(&self.top())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Ord> PartialOrd for Pile<T> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
fn patience_sort<T: Ord + Clone>(slice: &mut [T]) {
|
||||
let mut piles: Vec<Pile<T>> = Vec::new();
|
||||
|
||||
// Sort into piles
|
||||
for item in slice.iter().cloned() {
|
||||
// Find the pile to insert into
|
||||
let idx = match piles.binary_search_by(|pile| {
|
||||
if let Some(top) = pile.top() {
|
||||
top.cmp(&item)
|
||||
} else {
|
||||
Ordering::Greater // Should not happen
|
||||
}
|
||||
}) {
|
||||
Ok(idx) => idx, // Found a pile with the same top value
|
||||
Err(idx) => idx, // Position where we should insert new pile
|
||||
};
|
||||
|
||||
if idx < piles.len() {
|
||||
piles[idx].push(item);
|
||||
} else {
|
||||
piles.push(Pile::new(item));
|
||||
}
|
||||
}
|
||||
|
||||
// Convert to BinaryHeap for efficient merging
|
||||
let mut heap = BinaryHeap::from(piles);
|
||||
|
||||
// Merge piles
|
||||
for item_slot in slice.iter_mut() {
|
||||
if let Some(mut smallest_pile) = heap.pop() {
|
||||
if let Some(top) = smallest_pile.pop() {
|
||||
*item_slot = top;
|
||||
|
||||
if !smallest_pile.is_empty() {
|
||||
heap.push(smallest_pile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert!(heap.is_empty());
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut a = [4, 65, 2, -31, 0, 99, 83, 782, 1];
|
||||
patience_sort(&mut a);
|
||||
println!("{:?}", a);
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const ArrayList = std.ArrayList;
|
||||
const PriorityQueue = std.PriorityQueue;
|
||||
|
||||
// Pile structure to represent a stack of items
|
||||
fn Pile(comptime T: type) type {
|
||||
return struct {
|
||||
values: ArrayList(T),
|
||||
|
||||
const Self = @This();
|
||||
|
||||
fn init(allocator: Allocator) Self {
|
||||
return Self{
|
||||
.values = ArrayList(T).init(allocator),
|
||||
};
|
||||
}
|
||||
|
||||
fn deinit(self: *Self) void {
|
||||
self.values.deinit();
|
||||
}
|
||||
|
||||
fn push(self: *Self, value: T) !void {
|
||||
try self.values.append(value);
|
||||
}
|
||||
|
||||
fn pop(self: *Self) ?T {
|
||||
if (self.values.items.len == 0) return null;
|
||||
return self.values.pop();
|
||||
}
|
||||
|
||||
fn top(self: *const Self) ?T {
|
||||
if (self.values.items.len == 0) return null;
|
||||
return self.values.items[self.values.items.len - 1];
|
||||
}
|
||||
|
||||
fn isEmpty(self: *const Self) bool {
|
||||
return self.values.items.len == 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Compare function for priority queue (min-heap)
|
||||
fn pileGreaterThan(comptime T: type) type {
|
||||
return struct {
|
||||
pub fn compare(context: void, a: *const Pile(T), b: *const Pile(T)) std.math.Order {
|
||||
_ = context;
|
||||
const a_top = a.top() orelse return .lt;
|
||||
const b_top = b.top() orelse return .gt;
|
||||
return if (a_top > b_top) .lt else if (a_top < b_top) .gt else .eq;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Patience sort implementation
|
||||
fn patienceSort(comptime T: type, allocator: Allocator, slice: []T) !void {
|
||||
const PileT = Pile(T);
|
||||
var piles = ArrayList(*PileT).init(allocator);
|
||||
defer {
|
||||
// Clean up all piles regardless of how we exit the function
|
||||
for (piles.items) |pile| {
|
||||
pile.deinit();
|
||||
allocator.destroy(pile);
|
||||
}
|
||||
piles.deinit();
|
||||
}
|
||||
|
||||
// Sort into piles
|
||||
for (slice) |item| {
|
||||
// Try to find an existing pile to add to
|
||||
var added = false;
|
||||
for (piles.items) |pile| {
|
||||
if (pile.top()) |top| {
|
||||
if (top > item) {
|
||||
try pile.push(item);
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no suitable pile found, create a new one
|
||||
if (!added) {
|
||||
var new_pile = try allocator.create(PileT);
|
||||
errdefer allocator.destroy(new_pile);
|
||||
|
||||
new_pile.* = PileT.init(allocator);
|
||||
errdefer new_pile.deinit();
|
||||
|
||||
try new_pile.push(item);
|
||||
try piles.append(new_pile);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a priority queue for efficient merging
|
||||
var queue = PriorityQueue(*PileT, void, pileGreaterThan(T).compare).init(allocator, {});
|
||||
defer queue.deinit();
|
||||
|
||||
// Add all piles to the priority queue
|
||||
for (piles.items) |pile| {
|
||||
try queue.add(pile);
|
||||
}
|
||||
|
||||
// Merge piles back into the original slice
|
||||
var i: usize = 0;
|
||||
while (queue.count() > 0) {
|
||||
const smallest_pile = queue.remove();
|
||||
if (smallest_pile.pop()) |value| {
|
||||
slice[i] = value;
|
||||
i += 1;
|
||||
|
||||
if (!smallest_pile.isEmpty()) {
|
||||
try queue.add(smallest_pile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std.debug.assert(i == slice.len);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var a = [_]i32{ 4, 65, 2, -31, 0, 99, 83, 782, 1 };
|
||||
try patienceSort(i32, allocator, &a);
|
||||
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
try stdout.print("Sorted array: ", .{});
|
||||
for (a, 0..) |value, i| {
|
||||
try stdout.print("{}", .{value});
|
||||
if (i < a.len - 1) {
|
||||
try stdout.print(", ", .{});
|
||||
}
|
||||
}
|
||||
try stdout.print("\n", .{});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue