Sorting algorithms/Patience sort: Difference between revisions
Content added Content deleted
m (added Category:Sorting) |
(add task to arm assembly raspberry pi) |
||
Line 9: | Line 9: | ||
:* [[Longest increasing subsequence]] |
:* [[Longest increasing subsequence]] |
||
<br><br> |
<br><br> |
||
=={{header|ARM Assembly}}== |
|||
{{works with|as|Raspberry Pi}} |
|||
<lang ARM Assembly> |
|||
/* ARM assembly Raspberry PI */ |
|||
/* program patienceSort.s */ |
|||
/* REMARK 1 : this program use routines in a include file |
|||
see task Include a file language arm assembly |
|||
for the routine affichageMess conversion10 |
|||
see at end of this program the instruction include */ |
|||
/* for constantes see task include a file in arm assembly */ |
|||
/************************************/ |
|||
/* Constantes */ |
|||
/************************************/ |
|||
.include "../constantes.inc" |
|||
.include "../../ficmacros.s" |
|||
/*******************************************/ |
|||
/* Structures */ |
|||
/********************************************/ |
|||
/* structure Doublylinkedlist*/ |
|||
.struct 0 |
|||
dllist_head: @ head node |
|||
.struct dllist_head + 4 |
|||
dllist_tail: @ tail node |
|||
.struct dllist_tail + 4 |
|||
dllist_fin: |
|||
/* 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_fin: |
|||
/*********************************/ |
|||
/* Initialized data */ |
|||
/*********************************/ |
|||
.data |
|||
szMessSortOk: .asciz "Table sorted.\n" |
|||
szMessSortNok: .asciz "Table not sorted !!!!!.\n" |
|||
sMessResult: .asciz "Value : @ \n" |
|||
szCarriageReturn: .asciz "\n" |
|||
.align 4 |
|||
TableNumber: .int 1,11,3,6,2,5,9,10,8,4,7 |
|||
#TableNumber: .int 10,9,8,7,6,5,4,3,2,1 |
|||
.equ NBELEMENTS, (. - TableNumber) / 4 |
|||
/*********************************/ |
|||
/* UnInitialized data */ |
|||
/*********************************/ |
|||
.bss |
|||
sZoneConv: .skip 24 |
|||
/*********************************/ |
|||
/* code section */ |
|||
/*********************************/ |
|||
.text |
|||
.global main |
|||
main: @ entry of program |
|||
ldr r0,iAdrTableNumber @ address number table |
|||
mov r1,#0 @ first element |
|||
mov r2,#NBELEMENTS @ number of élements |
|||
bl patienceSort |
|||
ldr r0,iAdrTableNumber @ address number table |
|||
bl displayTable |
|||
ldr r0,iAdrTableNumber @ address number table |
|||
mov r1,#NBELEMENTS @ number of élements |
|||
bl isSorted @ control sort |
|||
cmp r0,#1 @ sorted ? |
|||
beq 1f |
|||
ldr r0,iAdrszMessSortNok @ no !! error sort |
|||
bl affichageMess |
|||
b 100f |
|||
1: @ yes |
|||
ldr r0,iAdrszMessSortOk |
|||
bl affichageMess |
|||
100: @ standard end of the program |
|||
mov r0, #0 @ return code |
|||
mov r7, #EXIT @ request to exit program |
|||
svc #0 @ perform the system call |
|||
iAdrszCarriageReturn: .int szCarriageReturn |
|||
iAdrsMessResult: .int sMessResult |
|||
iAdrTableNumber: .int TableNumber |
|||
iAdrszMessSortOk: .int szMessSortOk |
|||
iAdrszMessSortNok: .int szMessSortNok |
|||
/******************************************************************/ |
|||
/* control sorted table */ |
|||
/******************************************************************/ |
|||
/* r0 contains the address of table */ |
|||
/* r1 contains the number of elements > 0 */ |
|||
/* r0 return 0 if not sorted 1 if sorted */ |
|||
isSorted: |
|||
push {r2-r4,lr} @ save registers |
|||
mov r2,#0 |
|||
ldr r4,[r0,r2,lsl #2] |
|||
1: |
|||
add r2,#1 |
|||
cmp r2,r1 |
|||
movge r0,#1 |
|||
bge 100f |
|||
ldr r3,[r0,r2, lsl #2] |
|||
cmp r3,r4 |
|||
movlt r0,#0 |
|||
blt 100f |
|||
mov r4,r3 |
|||
b 1b |
|||
100: |
|||
pop {r2-r4,lr} |
|||
bx lr @ return |
|||
/******************************************************************/ |
|||
/* patience sort */ |
|||
/******************************************************************/ |
|||
/* r0 contains the address of table */ |
|||
/* r1 contains first start index |
|||
/* r2 contains the number of elements */ |
|||
patienceSort: |
|||
push {r1-r9,lr} @ save registers |
|||
lsl r9,r2,#1 @ compute total size of piles (2 list pointer by pile ) |
|||
lsl r10,r9,#2 @ 4 bytes by number |
|||
sub sp,sp,r10 @ reserve place to stack |
|||
mov fp,sp @ frame pointer = stack |
|||
mov r3,#0 @ index |
|||
mov r4,#0 |
|||
1: |
|||
str r4,[fp,r3,lsl #2] @ init piles area |
|||
add r3,r3,#1 @ increment index |
|||
cmp r3,r9 |
|||
blt 1b |
|||
mov r3,#0 @ index value |
|||
mov r4,#0 @ counter first pile |
|||
mov r8,r0 @ save table address |
|||
2: |
|||
ldr r1,[r8,r3,lsl #2] @ load value |
|||
add r0,fp,r4,lsl #3 @ pile address |
|||
bl isEmpty |
|||
cmp r0,#0 @ pile empty ? |
|||
bne 3f |
|||
add r0,fp,r4,lsl #3 @ pile address |
|||
bl insertHead @ insert value r1 |
|||
b 5f |
|||
3: |
|||
add r0,fp,r4,lsl #3 @ pile address |
|||
ldr r5,[r0,#dllist_head] |
|||
ldr r5,[r5,#NDlist_value] @ load first list value |
|||
cmp r1,r5 @ compare value and last value on the pile |
|||
blt 4f |
|||
add r0,fp,r4,lsl #3 @ pile address |
|||
bl insertHead @ insert value r1 |
|||
b 5f |
|||
4: @ value is smaller créate a new pile |
|||
add r4,r4,#1 |
|||
add r0,fp,r4,lsl #3 @ pile address |
|||
bl insertHead @ insert value r1 |
|||
5: |
|||
add r3,r3,#1 @ increment index value |
|||
cmp r3,r2 @ end |
|||
blt 2b @ and loop |
|||
/* step 2 */ |
|||
mov r6,#0 @ index value table |
|||
6: |
|||
mov r3,#0 @ index pile |
|||
mov r5,# 1<<30 @ min |
|||
7: @ search minimum |
|||
add r0,fp,r3,lsl #3 |
|||
bl isEmpty |
|||
cmp r0,#0 |
|||
beq 8f |
|||
add r0,fp,r3,lsl #3 |
|||
bl searchMinList |
|||
cmp r0,r5 @ compare min global |
|||
movlt r5,r0 @ smaller -> store new min |
|||
movlt r7,r1 @ and pointer to min |
|||
addlt r9,fp,r3,lsl #3 @ and head list |
|||
8: |
|||
add r3,r3,#1 @ next pile |
|||
cmp r3,r4 @ end ? |
|||
ble 7b |
|||
str r5,[r8,r6,lsl #2] @ store min to table value |
|||
mov r0,r9 @ and suppress the value in the pile |
|||
mov r1,r7 |
|||
bl suppressNode |
|||
add r6,r6,#1 @ increment index value |
|||
cmp r6,r2 @ end ? |
|||
blt 6b |
|||
add sp,sp,r10 @ stack alignement |
|||
100: |
|||
pop {r1-r9,lr} |
|||
bx lr @ return |
|||
/******************************************************************/ |
|||
/* Display table elements */ |
|||
/******************************************************************/ |
|||
/* r0 contains the address of table */ |
|||
displayTable: |
|||
push {r0-r3,lr} @ save registers |
|||
mov r2,r0 @ table address |
|||
mov r3,#0 |
|||
1: @ loop display table |
|||
ldr r0,[r2,r3,lsl #2] |
|||
ldr r1,iAdrsZoneConv @ |
|||
bl conversion10S @ décimal conversion |
|||
ldr r0,iAdrsMessResult |
|||
ldr r1,iAdrsZoneConv @ insert conversion |
|||
bl strInsertAtCharInc |
|||
bl affichageMess @ display message |
|||
add r3,#1 |
|||
cmp r3,#NBELEMENTS - 1 |
|||
ble 1b |
|||
ldr r0,iAdrszCarriageReturn |
|||
bl affichageMess |
|||
mov r0,r2 |
|||
100: |
|||
pop {r0-r3,lr} |
|||
bx lr |
|||
iAdrsZoneConv: .int sZoneConv |
|||
/******************************************************************/ |
|||
/* list is empty ? */ |
|||
/******************************************************************/ |
|||
/* r0 contains the address of the list structure */ |
|||
/* r0 return 0 if empty else return 1 */ |
|||
isEmpty: |
|||
ldr r0,[r0,#dllist_head] |
|||
cmp r0,#0 |
|||
movne r0,#1 |
|||
bx lr @ return |
|||
/******************************************************************/ |
|||
/* insert value at list head */ |
|||
/******************************************************************/ |
|||
/* r0 contains the address of the list structure */ |
|||
/* r1 contains value */ |
|||
insertHead: |
|||
push {r1-r4,lr} @ save registers |
|||
mov r4,r0 @ save address |
|||
mov r0,r1 @ value |
|||
bl createNode |
|||
cmp r0,#-1 @ allocation error ? |
|||
beq 100f |
|||
ldr r2,[r4,#dllist_head] @ load address first node |
|||
str r2,[r0,#NDlist_next] @ store in next pointer on new node |
|||
mov r1,#0 |
|||
str r1,[r0,#NDlist_prev] @ store zero in previous pointer on new node |
|||
str r0,[r4,#dllist_head] @ store address new node in address head list |
|||
cmp r2,#0 @ address first node is null ? |
|||
strne r0,[r2,#NDlist_prev] @ no store adresse new node in previous pointer |
|||
streq r0,[r4,#dllist_tail] @ else store new node in tail address |
|||
100: |
|||
pop {r1-r4,lr} @ restaur registers |
|||
bx lr @ return |
|||
/******************************************************************/ |
|||
/* search value minimum */ |
|||
/******************************************************************/ |
|||
/* r0 contains the address of the list structure */ |
|||
/* r0 return min */ |
|||
/* r1 return address of node */ |
|||
searchMinList: |
|||
push {r2,r3,lr} @ save registers |
|||
ldr r0,[r0,#dllist_head] @ load first node |
|||
mov r3,#1<<30 |
|||
mov r1,#0 |
|||
1: |
|||
cmp r0,#0 @ null -> end |
|||
moveq r0,r3 |
|||
beq 100f |
|||
ldr r2,[r0,#NDlist_value] @ load node value |
|||
cmp r2,r3 @ min ? |
|||
movlt r3,r2 @ value -> min |
|||
movlt r1,r0 @ store pointer |
|||
ldr r0,[r0,#NDlist_next] @ load addresse next node |
|||
b 1b @ and loop |
|||
100: |
|||
pop {r2,r3,lr} @ restaur registers |
|||
bx lr @ return |
|||
/******************************************************************/ |
|||
/* suppress node */ |
|||
/******************************************************************/ |
|||
/* r0 contains the address of the list structure */ |
|||
/* r1 contains the address to node to suppress */ |
|||
/* r0 return address of node or -1 if not found */ |
|||
suppressNode: |
|||
push {r2,r3,lr} @ save registers |
|||
ldr r2,[r1,#NDlist_next] @ load addresse next node |
|||
ldr r3,[r1,#NDlist_prev] @ load addresse prev node |
|||
cmp r3,#0 |
|||
strne r2,[r3,#NDlist_next] |
|||
streq r3,[r0,#NDlist_next] |
|||
cmp r2,#0 |
|||
strne r3,[r2,#NDlist_prev] |
|||
streq r2,[r0,#NDlist_prev] |
|||
100: |
|||
pop {r2,r3,lr} @ restaur registers |
|||
bx lr @ return |
|||
/******************************************************************/ |
|||
/* Create new node */ |
|||
/******************************************************************/ |
|||
/* r0 contains the value */ |
|||
/* r0 return node address or -1 if allocation error*/ |
|||
createNode: |
|||
push {r1-r7,lr} @ save registers |
|||
mov r4,r0 @ save value |
|||
@ allocation place on the heap |
|||
mov r0,#0 @ allocation place heap |
|||
mov r7,#0x2D @ call system 'brk' |
|||
svc #0 |
|||
mov r5,r0 @ save address heap for output string |
|||
add r0,#NDlist_fin @ reservation place one element |
|||
mov r7,#0x2D @ call system 'brk' |
|||
svc #0 |
|||
cmp r0,#-1 @ allocation error |
|||
beq 100f |
|||
mov r0,r5 |
|||
str r4,[r0,#NDlist_value] @ store value |
|||
mov r2,#0 |
|||
str r2,[r0,#NDlist_next] @ store zero to pointer next |
|||
str r2,[r0,#NDlist_prev] @ store zero to pointer previous |
|||
100: |
|||
pop {r1-r7,lr} @ restaur registers |
|||
bx lr @ return |
|||
/***************************************************/ |
|||
/* ROUTINES INCLUDE */ |
|||
/***************************************************/ |
|||
.include "../affichage.inc" |
|||
</lang> |
|||
=={{header|C}}== |
=={{header|C}}== |
||
Takes integers as input, prints out usage on incorrect invocation |
Takes integers as input, prints out usage on incorrect invocation |