Data update
This commit is contained in:
parent
72eb4943cb
commit
4d5544505c
2347 changed files with 62432 additions and 16731 deletions
|
|
@ -1,4 +1,4 @@
|
|||
proc merge . a[] b[] .
|
||||
proc merge &a[] &b[] .
|
||||
a = 1 ; b = 1
|
||||
while a <= len a[] and b <= len b[]
|
||||
if a[a] < b[b]
|
||||
|
|
@ -19,7 +19,7 @@ proc merge . a[] b[] .
|
|||
.
|
||||
swap a[] r[]
|
||||
.
|
||||
proc strand . a[] s[] .
|
||||
proc strand &a[] &s[] .
|
||||
s[] = [ a[1] ]
|
||||
for i = 2 to len a[]
|
||||
if a[i] > s[$]
|
||||
|
|
@ -30,7 +30,7 @@ proc strand . a[] s[] .
|
|||
.
|
||||
swap a[] an[]
|
||||
.
|
||||
proc strandsort . a[] .
|
||||
proc strandsort &a[] .
|
||||
strand a[] out[]
|
||||
while len a[] > 0
|
||||
strand a[] b[]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
Sub strandSort(bs() As Long)
|
||||
Dim As Long subList()
|
||||
Dim As Long results()
|
||||
Dim As Long i, j, k
|
||||
Dim As Long lb = LBound(bs), ub = UBound(bs)
|
||||
|
||||
' Initialize results array with zero elements
|
||||
ReDim results(-1)
|
||||
|
||||
While ub >= lb
|
||||
ReDim subList(0)
|
||||
subList(0) = bs(lb)
|
||||
|
||||
' Remove the first element
|
||||
For i = lb To ub - 1
|
||||
bs(i) = bs(i + 1)
|
||||
Next
|
||||
ReDim Preserve bs(ub - 1)
|
||||
ub -= 1
|
||||
|
||||
' Extract sorted subsequence
|
||||
For i = lb To ub
|
||||
If bs(i) >= subList(UBound(subList)) Then
|
||||
ReDim Preserve subList(UBound(subList) + 1)
|
||||
subList(UBound(subList)) = bs(i)
|
||||
|
||||
' Remove the element
|
||||
For j = i To ub - 1
|
||||
bs(j) = bs(j + 1)
|
||||
Next
|
||||
ReDim Preserve bs(ub - 1)
|
||||
ub -= 1
|
||||
i -= 1
|
||||
End If
|
||||
Next
|
||||
|
||||
' Merge lists - but only if results has elements
|
||||
If UBound(results) >= 0 Then
|
||||
ReDim As Long merged(UBound(results) + UBound(subList) + 1)
|
||||
i = 0
|
||||
j = 0
|
||||
k = 0
|
||||
|
||||
While i <= UBound(results) And j <= UBound(subList)
|
||||
If results(i) < subList(j) Then
|
||||
merged(k) = results(i)
|
||||
i += 1
|
||||
Else
|
||||
merged(k) = subList(j)
|
||||
j += 1
|
||||
End If
|
||||
k += 1
|
||||
Wend
|
||||
|
||||
While i <= UBound(results)
|
||||
merged(k) = results(i)
|
||||
i += 1
|
||||
k += 1
|
||||
Wend
|
||||
|
||||
While j <= UBound(subList)
|
||||
merged(k) = subList(j)
|
||||
j += 1
|
||||
k += 1
|
||||
Wend
|
||||
|
||||
ReDim results(UBound(merged))
|
||||
For i = 0 To UBound(merged)
|
||||
results(i) = merged(i)
|
||||
Next
|
||||
Else
|
||||
' If results is empty, just copy subList to results
|
||||
ReDim results(UBound(subList))
|
||||
For i = 0 To UBound(subList)
|
||||
results(i) = subList(i)
|
||||
Next
|
||||
End If
|
||||
Wend
|
||||
|
||||
' Copy results back to bs
|
||||
ReDim bs(UBound(results))
|
||||
For i = 0 To UBound(results)
|
||||
bs(i) = results(i)
|
||||
Next
|
||||
End Sub
|
||||
|
||||
'--- Main Program ---
|
||||
Dim As Long i
|
||||
Dim As Long array(14) = {-5,-3, 0,-7, 5, 2, 3, 6,-6,-1, 1,-2, 4, 7,-4}
|
||||
Dim As Long a = LBound(array), b = UBound(array)
|
||||
|
||||
Print "unsort ";
|
||||
For i = a To b : Print Using "####"; array(i); : Next i
|
||||
|
||||
strandSort(array()) ' sort the array
|
||||
|
||||
Print !"\n sort ";
|
||||
For i = a To b : Print Using "####"; array(i); : Next i
|
||||
|
||||
Sleep
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
module Strand_sort{
|
||||
function strand_sort(aa as array) {
|
||||
function mergelist(sa, sb) {
|
||||
flush ' empty current stack
|
||||
variant v, g
|
||||
integer L=3
|
||||
while len(sa) and len(sb)
|
||||
if L=1 else stack sa {read v}
|
||||
if L=2 else stack sb {read g}
|
||||
if v<g then
|
||||
data v: L=2
|
||||
else
|
||||
data g:L=1
|
||||
end if
|
||||
end while
|
||||
' dump stacks to current stack
|
||||
If L=1 then data v
|
||||
if L=2 then data g
|
||||
data !sa, !sb
|
||||
' return the current stack as-is
|
||||
=[]
|
||||
}
|
||||
function strand(&a) {
|
||||
flush
|
||||
variant v, g
|
||||
if len(a)<1 then =a:exit
|
||||
stack a {read v }: data v
|
||||
i=1
|
||||
L=0
|
||||
while i <= len(a)
|
||||
if i<>L then
|
||||
stack a {
|
||||
shift i ' get i_th item as top
|
||||
over ' copy one
|
||||
read g ' read in a variant
|
||||
shiftback i ' send back to i
|
||||
}
|
||||
L=i
|
||||
end if
|
||||
if g > v then
|
||||
stack a {
|
||||
shift i
|
||||
drop
|
||||
}
|
||||
data g
|
||||
v = g
|
||||
else
|
||||
i++
|
||||
end if
|
||||
end while
|
||||
=[]
|
||||
}
|
||||
|
||||
a=stack(aa)
|
||||
out = strand(&a)
|
||||
while len(a)
|
||||
out = mergelist(out, strand(&a))
|
||||
end while
|
||||
=array(out)
|
||||
}
|
||||
m = (1, 6, 3, 2, 1, 7, 5, 3)
|
||||
Print m
|
||||
Print strand_sort(m)
|
||||
m = ("aa", "cc", "bb", "a1")
|
||||
Print m
|
||||
Print strand_sort(m)
|
||||
}
|
||||
Strand_sort
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
use std::fmt;
|
||||
|
||||
struct Link {
|
||||
value: i32,
|
||||
next: Option<Box<Link>>,
|
||||
}
|
||||
|
||||
impl Link {
|
||||
fn new(value: i32, next: Option<Box<Link>>) -> Self {
|
||||
Link { value, next }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Link {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[{}", self.value)?;
|
||||
|
||||
let mut current = &self.next;
|
||||
while let Some(link) = current {
|
||||
write!(f, " {}", link.value)?;
|
||||
current = &link.next;
|
||||
}
|
||||
|
||||
write!(f, "]")
|
||||
}
|
||||
}
|
||||
|
||||
fn link_ints(s: &[i32]) -> Option<Box<Link>> {
|
||||
if s.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(Box::new(Link::new(s[0], link_ints(&s[1..]))))
|
||||
}
|
||||
}
|
||||
|
||||
fn strand_sort(mut a: Option<Box<Link>>) -> Option<Box<Link>> {
|
||||
let mut result: Option<Box<Link>> = None;
|
||||
|
||||
while let Some(mut head) = a {
|
||||
// Take the first element for our sublist
|
||||
a = head.next.take();
|
||||
|
||||
// Build sublist
|
||||
let mut sublist = Some(head);
|
||||
let mut sublist_tail = sublist.as_mut().unwrap();
|
||||
|
||||
// Process the remaining elements in the original list
|
||||
let mut current = a;
|
||||
a = None;
|
||||
|
||||
// Start building a new 'a' list
|
||||
let mut new_a = None;
|
||||
let mut new_a_tail_ptr: *mut Option<Box<Link>> = &mut new_a;
|
||||
|
||||
while let Some(mut node) = current {
|
||||
current = node.next.take();
|
||||
|
||||
if node.value > sublist_tail.value {
|
||||
// Append to sublist
|
||||
sublist_tail.next = Some(node);
|
||||
sublist_tail = sublist_tail.next.as_mut().unwrap();
|
||||
} else {
|
||||
// Add to the new 'a' list
|
||||
unsafe {
|
||||
*new_a_tail_ptr = Some(node);
|
||||
new_a_tail_ptr = &mut (*new_a_tail_ptr).as_mut().unwrap().next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a = new_a;
|
||||
|
||||
// If result is empty, set it to the sublist
|
||||
if result.is_none() {
|
||||
result = sublist;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Merge sublist with result
|
||||
result = merge(result, sublist);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn merge(list1: Option<Box<Link>>, list2: Option<Box<Link>>) -> Option<Box<Link>> {
|
||||
match (list1, list2) {
|
||||
(None, list2) => list2,
|
||||
(list1, None) => list1,
|
||||
(Some(mut head1), Some(mut head2)) => {
|
||||
// Start with the smaller value
|
||||
let mut result;
|
||||
let mut current;
|
||||
|
||||
if head1.value <= head2.value {
|
||||
result = Some(head1);
|
||||
current = result.as_mut().unwrap();
|
||||
match current.next.take() {
|
||||
Some(next) => head1 = next,
|
||||
None => {
|
||||
current.next = Some(head2);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = Some(head2);
|
||||
current = result.as_mut().unwrap();
|
||||
match current.next.take() {
|
||||
Some(next) => head2 = next,
|
||||
None => {
|
||||
current.next = Some(head1);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge the rest
|
||||
loop {
|
||||
if head1.value <= head2.value {
|
||||
current.next = Some(head1);
|
||||
current = current.next.as_mut().unwrap();
|
||||
match current.next.take() {
|
||||
Some(next) => head1 = next,
|
||||
None => {
|
||||
current.next = Some(head2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
current.next = Some(head2);
|
||||
current = current.next.as_mut().unwrap();
|
||||
match current.next.take() {
|
||||
Some(next) => head2 = next,
|
||||
None => {
|
||||
current.next = Some(head1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = link_ints(&[170, 45, 75, -90, -802, 24, 2, 66]);
|
||||
println!("before: {}", a.as_ref().map_or("None".to_string(), |link| link.to_string()));
|
||||
|
||||
let b = strand_sort(a);
|
||||
println!("after: {}", b.as_ref().map_or("None".to_string(), |link| link.to_string()));
|
||||
}
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
const std = @import("std");
|
||||
|
||||
const Link = struct {
|
||||
value: i32,
|
||||
next: ?*Link,
|
||||
|
||||
fn new(allocator: std.mem.Allocator, value: i32, next: ?*Link) !*Link {
|
||||
const link = try allocator.create(Link);
|
||||
link.* = .{ .value = value, .next = next };
|
||||
return link;
|
||||
}
|
||||
|
||||
pub fn format(
|
||||
self: *const Link,
|
||||
comptime fmt: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) !void {
|
||||
_ = fmt;
|
||||
_ = options;
|
||||
|
||||
try writer.print("[{}", .{self.value});
|
||||
|
||||
var current = self.next;
|
||||
while (current) |link| {
|
||||
try writer.print(" {}", .{link.value});
|
||||
current = link.next;
|
||||
}
|
||||
|
||||
try writer.print("]", .{});
|
||||
}
|
||||
};
|
||||
|
||||
// Function to free all nodes in a linked list
|
||||
fn freeList(allocator: std.mem.Allocator, list: ?*Link) void {
|
||||
var current = list;
|
||||
while (current) |node| {
|
||||
const next = node.next;
|
||||
allocator.destroy(node);
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
|
||||
fn linkInts(allocator: std.mem.Allocator, s: []const i32) !?*Link {
|
||||
if (s.len == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return try Link.new(allocator, s[0], try linkInts(allocator, s[1..]));
|
||||
}
|
||||
}
|
||||
|
||||
fn strandSort(allocator: std.mem.Allocator, a: ?*Link) !?*Link {
|
||||
var result: ?*Link = null;
|
||||
var current_a = a;
|
||||
|
||||
while (current_a) |head| {
|
||||
// Take the first element for our sublist
|
||||
current_a = head.next;
|
||||
head.next = null;
|
||||
|
||||
// Build sublist
|
||||
const sublist: ?*Link = head;
|
||||
var sublist_tail = sublist.?;
|
||||
|
||||
// Process the remaining elements in the original list
|
||||
var current = current_a;
|
||||
current_a = null;
|
||||
|
||||
// Start building a new 'a' list
|
||||
var new_a: ?*Link = null;
|
||||
var new_a_tail: ?*Link = null;
|
||||
|
||||
while (current) |node| {
|
||||
current = node.next;
|
||||
node.next = null;
|
||||
|
||||
if (node.value > sublist_tail.value) {
|
||||
// Append to sublist
|
||||
sublist_tail.next = node;
|
||||
sublist_tail = node;
|
||||
} else {
|
||||
// Add to the new 'a' list
|
||||
if (new_a == null) {
|
||||
new_a = node;
|
||||
new_a_tail = node;
|
||||
} else {
|
||||
new_a_tail.?.next = node;
|
||||
new_a_tail = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current_a = new_a;
|
||||
|
||||
// If result is empty, set it to the sublist
|
||||
if (result == null) {
|
||||
result = sublist;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Merge sublist with result
|
||||
result = try merge(allocator, result, sublist);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
fn merge(allocator: std.mem.Allocator, list1: ?*Link, list2: ?*Link) !?*Link {
|
||||
_ = allocator; // Allocator is not needed here, but keeping for consistency
|
||||
|
||||
if (list1 == null) return list2;
|
||||
if (list2 == null) return list1;
|
||||
|
||||
var head1 = list1.?;
|
||||
var head2 = list2.?;
|
||||
|
||||
// Start with the smaller value
|
||||
var result: ?*Link = null;
|
||||
var current: *Link = undefined;
|
||||
|
||||
if (head1.value <= head2.value) {
|
||||
result = head1;
|
||||
current = head1;
|
||||
head1 = head1.next orelse {
|
||||
current.next = head2;
|
||||
return result;
|
||||
};
|
||||
} else {
|
||||
result = head2;
|
||||
current = head2;
|
||||
head2 = head2.next orelse {
|
||||
current.next = head1;
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
// Merge the rest
|
||||
while (true) {
|
||||
if (head1.value <= head2.value) {
|
||||
current.next = head1;
|
||||
current = head1;
|
||||
head1 = head1.next orelse {
|
||||
current.next = head2;
|
||||
break;
|
||||
};
|
||||
} else {
|
||||
current.next = head2;
|
||||
current = head2;
|
||||
head2 = head2.next orelse {
|
||||
current.next = head1;
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
const allocator = gpa.allocator();
|
||||
defer {
|
||||
const deinit_status = gpa.deinit();
|
||||
if (deinit_status == .leak) @panic("MEMORY LEAK");
|
||||
}
|
||||
|
||||
const array = [_]i32{ 170, 45, 75, -90, -802, 24, 2, 66 };
|
||||
const a = try linkInts(allocator, &array);
|
||||
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
try stdout.print("before: ", .{});
|
||||
if (a) |link| {
|
||||
try stdout.print("{}", .{link});
|
||||
} else {
|
||||
try stdout.print("None", .{});
|
||||
}
|
||||
try stdout.print("\n", .{});
|
||||
|
||||
const b = try strandSort(allocator, a);
|
||||
try stdout.print("after: ", .{});
|
||||
if (b) |link| {
|
||||
try stdout.print("{}", .{link});
|
||||
} else {
|
||||
try stdout.print("None", .{});
|
||||
}
|
||||
try stdout.print("\n", .{});
|
||||
|
||||
// Free memory
|
||||
freeList(allocator, b);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue