Data update

This commit is contained in:
Ingy döt Net 2026-04-30 12:34:36 -04:00
parent 4bb20c9b71
commit cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions

View file

@ -0,0 +1,288 @@
----------------------------------------------------------------------
with Ada.Text_IO;
procedure patience_sort_task is
use Ada.Text_IO;
function next_power_of_two
(n : in Natural)
return Positive is
-- This need not be a fast implementation.
pow2 : Positive;
begin
pow2 := 1;
while pow2 < n loop
pow2 := pow2 + pow2;
end loop;
return pow2;
end next_power_of_two;
generic
type t is private;
type t_array is array (Integer range <>) of t;
type sorted_t_indices is array (Integer range <>) of Integer;
procedure patience_sort
(less : access function
(x, y : t)
return Boolean;
ifirst : in Integer;
ilast : in Integer;
arr : in t_array;
sorted : out sorted_t_indices);
procedure patience_sort
(less : access function
(x, y : t)
return Boolean;
ifirst : in Integer;
ilast : in Integer;
arr : in t_array;
sorted : out sorted_t_indices) is
num_piles : Integer;
piles : array (1 .. ilast - ifirst + 1) of Integer :=
(others => 0);
links : array (1 .. ilast - ifirst + 1) of Integer :=
(others => 0);
function find_pile
(q : in Positive)
return Positive is
--
-- 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
--
index : Positive;
i, j, k : Natural;
begin
if num_piles = 0 then
index := 1;
else
j := 0;
k := num_piles - 1;
while j /= k loop
i := (j + k) / 2;
if less
(arr (piles (j + 1) + ifirst - 1), arr (q + ifirst - 1))
then
j := i + 1;
else
k := i;
end if;
end loop;
if j = num_piles - 1 then
if less
(arr (piles (j + 1) + ifirst - 1), arr (q + ifirst - 1))
then
-- A new pile is needed.
j := j + 1;
end if;
end if;
index := j + 1;
end if;
return index;
end find_pile;
procedure deal is
i : Positive;
begin
for q in links'range loop
i := find_pile (q);
links (q) := piles (i);
piles (i) := q;
num_piles := Integer'max (num_piles, i);
end loop;
end deal;
procedure k_way_merge is
--
-- 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.
--
total_external_nodes : Positive;
total_nodes : Positive;
begin
total_external_nodes := next_power_of_two (num_piles);
total_nodes := (2 * total_external_nodes) - 1;
declare
-- In Fortran I had the length-2 dimension come first, to
-- take some small advantage of column-major order. The
-- recommendation for Ada compilers, however, is to use
-- row-major order. So I have reversed the order.
winners : array (1 .. total_nodes, 1 .. 2) of Integer :=
(others => (0, 0));
function find_opponent
(i : Natural)
return Natural is
begin
return (if i rem 2 = 0 then i + 1 else i - 1);
end find_opponent;
function play_game
(i : Positive)
return Positive is
j, iwinner : Positive;
begin
j := find_opponent (i);
if winners (i, 1) = 0 then
iwinner := j;
elsif winners (j, 1) = 0 then
iwinner := i;
elsif less
(arr (winners (j, 1) + ifirst - 1),
arr (winners (i, 1) + ifirst - 1))
then
iwinner := j;
else
iwinner := i;
end if;
return iwinner;
end play_game;
procedure replay_games
(i : Positive) is
j, iwinner : Positive;
begin
j := i;
while j /= 1 loop
iwinner := play_game (j);
j := j / 2;
winners (j, 1) := winners (iwinner, 1);
winners (j, 2) := winners (iwinner, 2);
end loop;
end replay_games;
procedure build_tree is
istart, i, iwinner : Positive;
begin
for i in 1 .. total_external_nodes loop
-- Record which pile a winner will have come from.
winners (total_external_nodes - 1 + i, 2) := i;
end loop;
for i in 1 .. num_piles loop
-- The top of each pile becomes a starting competitor.
winners (total_external_nodes + i - 1, 1) := piles (i);
end loop;
for i in 1 .. num_piles loop
-- Discard the top of each pile
piles (i) := links (piles (i));
end loop;
istart := total_external_nodes;
while istart /= 1 loop
i := istart;
while i <= (2 * istart) - 1 loop
iwinner := play_game (i);
winners (i / 2, 1) := winners (iwinner, 1);
winners (i / 2, 2) := winners (iwinner, 2);
i := i + 2;
end loop;
istart := istart / 2;
end loop;
end build_tree;
isorted, i, next : Integer;
begin
build_tree;
isorted := 0;
while winners (1, 1) /= 0 loop
sorted (sorted'first + 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.
end if;
i := (total_nodes / 2) + i;
winners (i, 1) := next;
replay_games (i);
end loop;
end;
end k_way_merge;
begin
deal;
k_way_merge;
end patience_sort;
begin
-- A demonstration.
declare
type integer_array is array (Integer range <>) of Integer;
procedure integer_patience_sort is new patience_sort
(Integer, integer_array, integer_array);
subtype int25_array is integer_array (1 .. 25);
example_numbers : constant int25_array :=
(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_numbers : int25_array := (others => 0);
function less
(x, y : Integer)
return Boolean is
begin
return (x < y);
end less;
begin
integer_patience_sort
(less'access, example_numbers'first, example_numbers'last,
example_numbers, sorted_numbers);
Put ("unsorted ");
for i of example_numbers loop
Put (Integer'image (i));
end loop;
Put_Line ("");
Put ("sorted ");
for i of sorted_numbers loop
Put (Integer'image (example_numbers (i)));
end loop;
Put_Line ("");
end;
end patience_sort_task;
----------------------------------------------------------------------

View file

@ -0,0 +1,44 @@
local fmt = require "fmt"
local function patience_sort(a)
local size = #a
if size < 2 then return end
local piles = {}
for a as e do
local outer = false
for piles as pile do
if pile:back() > e then
pile:insert(e)
outer = true
break
end
end
if !outer then piles:insert({e}) end
end
for i = 1, size do
local min = piles[1]:back()
local min_pile_index = 1
for j = 2, #piles do
if piles[j]:back() < min then
min = piles[j]:back()
min_pile_index = j
end
end
a[i] = min
local min_pile = piles[min_pile_index]
min_pile:remove()
if #min_pile == 0 then piles:remove(min_pile_index) end
end
end
local ia = {4, 65, 2, -31, 0, 99, 83, 782, 1}
patience_sort(ia)
fmt.lprint(ia)
local ca = {"n", "o", "n", "z", "e", "r", "o", "s", "u", "m"}
patience_sort(ca)
fmt.lprint(ca)
local sa = {"dog", "cow", "cat", "ape", "ant", "man", "pig", "ass", "gnu"}
patience_sort(sa)
fmt.lprint(sa)

View file

@ -0,0 +1,37 @@
patiencesort <- function(list) {
piles <- list()
for (n in list) {
# Find the first pile where the last element is >= n
i <- sapply(piles, function(pile) n <= tail(pile, 1))
if (length(piles) == 0 || !any(i)) {
piles <- append(piles, list(n))
} else {
# Find the index of the first TRUE in i
idx <- which(i)[1]
piles[[idx]] <- c(piles[[idx]], n)
}
}
mergesorted(piles)
}
mergesorted <- function(vecvec) {
allsum <- sum(sapply(vecvec, length))
sorted <- vector("numeric", allsum)
for (i in 1:allsum) {
# Find the pile with the smallest last element
last_elements <- sapply(vecvec, tail, 1)
idx <- which.min(last_elements)
sorted[i] <- tail(vecvec[[idx]], 1)
vecvec[[idx]] <- head(vecvec[[idx]], -1)
# Remove empty piles
if (length(vecvec[[idx]]) == 0) {
vecvec <- vecvec[-idx]
}
}
sorted
}
# Example usage
set.seed(123)
random_list <- sample(1:1000, 12)
print(patiencesort(random_list))

View file

@ -0,0 +1,400 @@
# riscv assembly raspberry pico2 rp2350
# program patiencesort.s
# connexion putty com3
/*********************************************/
/* CONSTANTES */
/********************************************/
/* for this file see risc-v task include a file */
.include "../../constantesRiscv.inc"
.equ HEAPSIZE, 50000
/****************************************************/
/* MACROS */
/****************************************************/
#.include "../ficmacrosriscv.inc" # for debugging only
/*******************************************/
/* Structures */
/********************************************/
/* structure Doublylinkedlist*/
.struct 0
dllist_head: # head node
.struct dllist_head + 4
dllist_tail: # tail node
.struct dllist_tail + 4
dllist_end:
/* structure Node Doublylinked List*/
.struct 0
NDlist_next: # next element
.struct NDlist_next + 4
NDlist_prev: # previous element
.struct NDlist_prev + 4
NDlist_value: # element value or key
.struct NDlist_value + 4
NDlist_end:
/*******************************************/
/* INITIALED DATAS */
/*******************************************/
.data
szMessStart: .asciz "Program riscv start.\r\n"
szMessEnd: .asciz "\nProgram end OK.\r\n"
szCariageReturn: .asciz "\r\n"
szMessSortOk: .asciz "Area sorted.\n"
szMessSortNok: .asciz "Area not sorted !!!!!.\n"
szLibSort: .asciz "\nAfter sort\n"
szSpace: .asciz " "
.align 2
tabNumber: .int 5,7,8,3,2,9,1,4,6
#tabNumber: .int 9,8,7,6,5,4,3,2,1
.equ NBTABNUMBER1, . - tabNumber
.equ NBTABNUMBER, NBTABNUMBER1 / 4 # compute items number
ptHeapReserve: .int heapReserve
/*******************************************/
/* UNINITIALED DATA */
/*******************************************/
.bss
.align 2
sConvArea: .skip 24
heapReserve: .skip HEAPSIZE
/********************************...-..--*****/
/* SECTION CODE */
/**********************************************/
.text
.global main
main:
call stdio_init_all # général init
1: # start loop connexion
li a0,0 # raz argument register
call tud_cdc_n_connected # waiting for USB connection
beqz a0,1b # return code = zero ?
la a0,szMessStart # message address
call writeString # display message
la s0,tabNumber # number array address
li s1,0
li s2,NBTABNUMBER
2: # item loop
sh2add t3,s1,s0 # compute item address
lw a0,(t3)
call displayResultD
add s1,s1,1
blt s1,s2,2b
la a0,szCariageReturn
call writeString
mv a0,s0 # number array address
li a1,0 # first item
mv a2,s2
call patienceSort # sort
mv a0,s0 # number array address
li a1,0 # first item
addi a2,s2,-1 # last item
call isSorted
la a0,szLibSort
call writeString
li s1,0
3: # item loop
sh2add t3,s1,s0 # compute item address
lw a0,(t3)
call displayResultD
add s1,s1,1
blt s1,s2,3b
la a0,szCariageReturn
call writeString
la a0,szMessEnd
call writeString
call getchar
100: # final loop
j 100b
/**********************************************/
/* display Result décimal */
/**********************************************/
/* a0 value */
.equ LGZONECONV, 20
displayResultD:
addi sp, sp, -4 # reserve stack
sw ra, 0(sp)
la a1,sConvArea # conversion result address
call conversion10 # binary conversion
la a0,sConvArea # message address
call writeString # display message
la a0,szSpace
call writeString
100:
lw ra, 0(sp)
addi sp, sp, 4
ret
/**********************************************/
/* sort control */
/**********************************************/
/* a0 area address */
/* a1 first element */
/* a2 last element */
.equ LGZONECONV, 20
isSorted:
addi sp, sp, -4 # reserve stack
sw ra, 0(sp)
mv t0,a1
sh2add t1,t0,a0
lw t2,(t1) # load first element
1:
addi t0,t0,1
ble t0,a2,2f # end indice ?
la a0,szMessSortOk
call writeString
li a0,1 # yes -> area is sorted
j 100f
2:
sh2add t1,t0,a0
lw t3,(t1) # load next element
bge t3,t2,3f # >= ?
la a0,szMessSortNok
call writeString
li a0,0 # no -> area is not sorted
j 100f
3:
mv t2,t3
j 1b
100:
lw ra, 0(sp)
addi sp, sp, 4
ret
/******************************************************************/
/* patience sort */
/******************************************************************/
/* a0 contains array address */
/* a1 contains the first element */
/* a2 contains the array size */
patienceSort:
addi sp, sp, -48 # reserve stack
sw ra, 0(sp) # save registers
sw s0, 4(sp)
sw s1, 8(sp)
sw s2, 12(sp)
sw s3, 16(sp)
sw s4, 20(sp)
sw s5, 24(sp)
sw s6, 28(sp)
sw s7, 32(sp)
sw s8, 36(sp)
sw s9, 40(sp)
sw s10, 44(sp)
slli s0,a2,1
slli s9,s0,3
mv s2,a0 # save table address
mv s3,a2 # save array size
sub sp,sp,s9 # reserve on stacm
mv s10,sp
li s8,0
1:
sh2add t0,s8,s10
sw x0,(t0) # init piles area
addi s8,s8,1 # increment index
blt s8,s0,1b
li s8,0 # index value
li s1,0 # counter first pile
2:
sh2add t0,s8,s2 # compute array address
lw a1,(t0) # load value
sh3add a0,s1,s10 # stack address
lw t0,dllist_head(a0)
bnez t0,3f # empty stack
call insertHead # insert value a1
blez a0,100f
j 5f
3:
lw t5,dllist_head(a0)
lw t5,NDlist_value(t5) # load first list value
blt a1,t5,4f
call insertHead
blez a0,100f
j 5f
4: # value is smaller créate a new pile
addi s1,s1,1
sh3add a0,s1,s10 # new stack address
call insertHead # insert value r1
blez a0,100f
5:
addi s8,s8,1 # increment index value
blt s8,s3,2b # end ? no -> loop
li s7,0 # init index value table
6:
li s8,0 # stack index
li s5,1<<30 # minimum
7: # search minimum
sh3add a0,s8,s10 # stack address
lw a0,dllist_head(a0)
beqz a0,8f # empty stack
call searchMinList
bge a0,s5,8f # compare min global
mv s5,a0 # smaller -> store new min
mv s4,a1 # and pointer to min
sh3add s6,s8,s10 # and head list
8:
addi s8,s8,1 # next stack
ble s8,s1,7b # end ? no -> loop
sh2add t0,s7,s2
sw s5,(t0) # store min to table value
mv a0,s6
mv a1,s4
call suppressNode
addi s7,s7,1
blt s7,s3,6b # end ? no -> loop
100:
add sp,sp,s9 # stack alignement
lw ra, 0(sp)
lw s0, 4(sp)
lw s1, 8(sp)
lw s2, 12(sp)
lw s3, 16(sp)
lw s4, 20(sp)
lw s5, 24(sp)
lw s6, 28(sp)
lw s7, 32(sp)
lw s8, 36(sp)
lw s9, 40(sp)
lw s10, 44(sp)
addi sp, sp, 48
ret
/**********************************************/
/* create new double linked list */
/**********************************************/
/* a0 linked list address */
newDList: # INFO: newDList
addi sp, sp, -4
sw ra, 0(sp)
sw x0,dllist_tail(a0) # raz pointer
sw x0,dllist_head(a0) # raz pointer
lw ra, 0(sp)
addi sp, sp, 4
ret
/**********************************************/
/* insertion value in head */
/**********************************************/
/* a0 double linked list address */
/* a1 contains the value of element */
/* a0 returns address of element or - 1 if error */
insertHead: # INFO: insertTail
addi sp, sp, -8
sw ra, 0(sp)
sw s0, 4(sp)
mv s0,a0 # save address
mv a0,a1 # value
call createNode # create new node
blez a0,100f # error ?
lw t0,dllist_head(s0) # load address first node
sw t0,NDlist_next(a0) # store in next pointer on new node
sw x0,NDlist_prev(a0) # store null on prev pointer
sw a0,dllist_head(s0) # store address new node on list head
beqz t0,1f # address last node is null ?
sw a0,NDlist_prev(t0) # no store address new node in next pointer
j 2f
1:
sw a0,dllist_tail(s0) # else store in head list
2:
100:
lw ra, 0(sp)
lw s0, 4(sp)
addi sp, sp, 8
ret
/**********************************************/
/* search value minimum */
/**********************************************/
/* a0 contains the address of the list structure */
/* a0 return min */
/* a1 return node address */
searchMinList: # INFO: searchMinList
addi sp, sp, -4
sw ra, 0(sp)
mv t0,a0
li t3,1<<30
li a1,0 # init node address
1:
bnez t0,2f # equal zero ?
mv a0,t3 # yes -> end
j 100f
2:
lw t1,NDlist_value(t0) # load node value
bge t1,t3,3f # < ?
mv t3,t1 # yes -> min = new value
mv a1,t0
3:
lw t0,NDlist_next(t0) # load address next node
j 1b # and loop
100:
lw ra, 0(sp)
addi sp, sp, 4
ret
/**********************************************/
/* create node on heap */
/**********************************************/
/* a0 value */
/* a0 return node address or -1 if error */
createNode: # INFO: createNode
addi sp, sp, -4
sw ra, 0(sp)
la t0,ptHeapReserve
lw t1,(t0) # free heap address
addi t2,t1,NDlist_end # reserve area on heap
la t3,heapReserve
li t4,HEAPSIZE
add t3,t3,t4
blt t2,t3,2f
li a0,-1
j 100f
2:
sw t2,(t0) # save new value heap used
sw a0,NDlist_value(t1) # store value on heap
sw x0,NDlist_next(t1) # raz pointer next
sw x0,NDlist_prev(t1) # raz pointer previous
mv a0,t1 # return node address
100:
lw ra, 0(sp)
addi sp, sp, 4
ret
/**********************************************/
/* suppress node on list */
/**********************************************/
/* a0 contains the address of the list structure */
/* a1 contains the address to node to suppress */
suppressNode: # INFO: suppressNode
addi sp, sp, -4
sw ra, 0(sp)
lw t0,NDlist_next(a1) # load addresse next node
lw t1,NDlist_prev(a1) # load addresse prev node
beqz t1,1f
sw t0,NDlist_next(t1)
j 2f
1:
sw t1,NDlist_next(a0)
2:
beqz t0,3f
sw t1,NDlist_prev(t0)
j 100f
3:
sw t0,NDlist_prev(a0)
100:
lw ra, 0(sp)
addi sp, sp, 4
ret
/************************************/
/* file include Fonctions */
/***********************************/
/* for this file see risc-v task include a file */
.include "../../includeFunctions.s"