Anagrams: Difference between revisions
Content added Content deleted
(add task to arm assembly raspberry pi) |
|||
Line 601: | Line 601: | ||
{{output}} |
{{output}} |
||
<lang applescript>{{"abel", "able", "bale", "bela", "elba"}, {"alger", "glare", "lager", "large", "regal"}, {"angel", "angle", "galen", "glean", "lange"}, {"caret", "carte", "cater", "crate", "trace"}, {"elan", "lane", "lean", "lena", "neal"}, {"evil", "levi", "live", "veil", "vile"}}</lang> |
<lang applescript>{{"abel", "able", "bale", "bela", "elba"}, {"alger", "glare", "lager", "large", "regal"}, {"angel", "angle", "galen", "glean", "lange"}, {"caret", "carte", "cater", "crate", "trace"}, {"elan", "lane", "lean", "lena", "neal"}, {"evil", "levi", "live", "veil", "vile"}}</lang> |
||
=={{header|ARM Assembly}}== |
|||
{{works with|as|Raspberry Pi <br> or android 32 bits with application Termux}} |
|||
<lang ARM Assembly> |
|||
/* ARM assembly Raspberry PI */ |
|||
/* program anagram.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" |
|||
.equ MAXI, 40000 |
|||
.equ BUFFERSIZE, 300000 |
|||
.equ READ, 3 @ system call |
|||
.equ OPEN, 5 @ system call |
|||
.equ CLOSE, 6 @ system call |
|||
.equ O_RDWR, 0x0002 @ open for reading and writing |
|||
/*********************************/ |
|||
/* Initialized data */ |
|||
/*********************************/ |
|||
.data |
|||
szFileName: .asciz "./listword.txt" |
|||
szMessErreur: .asciz "FILE ERROR." |
|||
szCarriageReturn: .asciz "\n" |
|||
szMessSpace: .asciz " " |
|||
ptBuffer1: .int sBuffer1 |
|||
/*********************************/ |
|||
/* UnInitialized data */ |
|||
/*********************************/ |
|||
.bss |
|||
ptTabBuffer: .skip 4 * MAXI |
|||
ptTabAna: .skip 4 * MAXI |
|||
tbiCptAna: .skip 4 * MAXI |
|||
iNBword: .skip 4 |
|||
sBuffer: .skip BUFFERSIZE |
|||
sBuffer1: .skip BUFFERSIZE |
|||
/*********************************/ |
|||
/* code section */ |
|||
/*********************************/ |
|||
.text |
|||
.global main |
|||
main: @ entry of program |
|||
mov r4,#0 @ loop indice |
|||
ldr r0,iAdrszFileName @ file name |
|||
mov r1,#O_RDWR @ flags |
|||
mov r2,#0 @ mode |
|||
mov r7,#OPEN @ |
|||
svc 0 |
|||
cmp r0,#0 @ error open |
|||
ble 99f |
|||
mov r8,r0 @ FD save Fd |
|||
ldr r1,iAdrsBuffer @ buffer address |
|||
ldr r2,iSizeBuf @ buffersize |
|||
mov r7, #READ |
|||
svc 0 |
|||
cmp r0,#0 @ error read ? |
|||
blt 99f |
|||
mov r5,r0 @ save size read bytes |
|||
ldr r4,iAdrsBuffer @ buffer address |
|||
ldr r0,iAdrsBuffer @ start word address |
|||
mov r2,#0 |
|||
mov r1,#0 @ word length |
|||
1: |
|||
cmp r2,r5 |
|||
bge 2f |
|||
ldrb r3,[r4,r2] |
|||
cmp r3,#0xD @ end word ? |
|||
addne r1,r1,#1 @ increment word length |
|||
addne r2,r2,#1 @ increment indice |
|||
bne 1b @ and loop |
|||
mov r3,#0 |
|||
strb r3,[r4,r2] @ store final zero |
|||
bl anaWord @ sort word letters |
|||
add r2,r2,#2 @ jump OD and 0A |
|||
add r0,r4,r2 @ new address begin word |
|||
mov r1,#0 @ init length |
|||
b 1b @ and loop |
|||
2: |
|||
mov r3,#0 @ last word |
|||
strb r3,[r4,r2] |
|||
bl anaWord |
|||
mov r0,r8 @ file Fd |
|||
mov r7, #CLOSE |
|||
svc 0 |
|||
cmp r0,#0 @ error close ? |
|||
blt 99f |
|||
ldr r0,iAdrptTabAna @ address sorted string area |
|||
mov r1,#0 @ first indice |
|||
ldr r2,iAdriNBword |
|||
ldr r2,[r2] @ last indice |
|||
ldr r3,iAdrptTabBuffer @ address sorted string area |
|||
bl triRapide @ quick sort |
|||
ldr r4,iAdrptTabAna @ address sorted string area |
|||
ldr r7,iAdrptTabBuffer @ address sorted string area |
|||
ldr r10,iAdrtbiCptAna @ address counter occurences |
|||
mov r9,r2 @ size word array |
|||
mov r8,#0 @ indice first occurence |
|||
ldr r3,[r4,r8,lsl #2] @ load first value |
|||
mov r2,#1 @ loop indice |
|||
mov r6,#0 @ counter |
|||
mov r12,#0 @ counter value max |
|||
3: |
|||
ldr r5,[r4,r2,lsl #2] @ load next value |
|||
mov r0,r3 |
|||
mov r1,r5 |
|||
bl comparStrings |
|||
cmp r0,#0 @ sorted strings equal ? |
|||
bne 4f |
|||
add r6,r6,#1 @ yes increment counter |
|||
b 5f |
|||
4: @ no |
|||
str r6,[r10,r8,lsl #2] @ store counter in first occurence |
|||
cmp r6,r12 @ counter > value max |
|||
movgt r12,r6 @ yes counter -> value max |
|||
mov r6,#0 @ raz counter |
|||
mov r8,r2 @ init index first occurence |
|||
mov r3,r5 @ init value first occurence |
|||
5: |
|||
add r2,r2,#1 @ increment indice |
|||
cmp r2,r9 @ end word array ? |
|||
blt 3b @ no -> loop |
|||
mov r2,#0 @ raz indice |
|||
6: @ display loop |
|||
ldr r6,[r10,r2,lsl #2] @ load counter |
|||
cmp r6,r12 @ equal to max value ? |
|||
bne 8f |
|||
ldr r0,[r7,r2,lsl #2] @ load address first word |
|||
bl affichageMess |
|||
add r3,r2,#1 @ increment new indixe |
|||
mov r4,#0 @ counter |
|||
7: |
|||
ldr r0,iAdrszMessSpace |
|||
bl affichageMess |
|||
ldr r0,[r7,r3,lsl #2] @ load address other word |
|||
bl affichageMess |
|||
add r3,r3,#1 @ increment indice |
|||
add r4,r4,#1 @ increment counter |
|||
cmp r4,r6 @ max value ? |
|||
blt 7b @ no loop |
|||
ldr r0,iAdrszCarriageReturn |
|||
bl affichageMess |
|||
8: |
|||
add r2,r2,#1 @ increment indice |
|||
cmp r2,r9 @ maxi ? |
|||
blt 6b @ no -> loop |
|||
b 100f |
|||
99: @ display error |
|||
ldr r1,iAdrszMessErreur |
|||
bl displayError |
|||
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 |
|||
iAdrszFileName: .int szFileName |
|||
iAdrszMessErreur: .int szMessErreur |
|||
iAdrsBuffer: .int sBuffer |
|||
iSizeBuf: .int BUFFERSIZE |
|||
iAdrszMessSpace: .int szMessSpace |
|||
iAdrtbiCptAna: .int tbiCptAna |
|||
/******************************************************************/ |
|||
/* analizing word */ |
|||
/******************************************************************/ |
|||
/* r0 word address */ |
|||
/* r1 word length */ |
|||
anaWord: |
|||
push {r1-r6,lr} |
|||
mov r5,r0 |
|||
mov r6,r1 |
|||
ldr r1,iAdrptTabBuffer |
|||
ldr r2,iAdriNBword |
|||
ldr r3,[r2] |
|||
str r0,[r1,r3,lsl #2] |
|||
ldr r1,iAdrptTabAna |
|||
ldr r4,iAdrptBuffer1 |
|||
ldr r0,[r4] |
|||
add r6,r6,r0 |
|||
add r6,r6,#1 |
|||
str r6,[r4] |
|||
str r0,[r1,r3,lsl #2] |
|||
add r3,r3,#1 |
|||
str r3,[r2] |
|||
mov r1,r0 |
|||
mov r0,r5 |
|||
bl triLetters @ sort word letters |
|||
mov r2,#0 |
|||
100: |
|||
pop {r1-r6,pc} |
|||
iAdrptTabBuffer: .int ptTabBuffer |
|||
iAdrptTabAna: .int ptTabAna |
|||
iAdriNBword: .int iNBword |
|||
iAdrptBuffer1: .int ptBuffer1 |
|||
/******************************************************************/ |
|||
/* sort word letters */ |
|||
/******************************************************************/ |
|||
/* r0 address begin word */ |
|||
/* r1 address recept array */ |
|||
triLetters: |
|||
push {r1-r7,lr} |
|||
mov r2,#0 |
|||
1: |
|||
ldrb r3,[r0,r2] @ load letter |
|||
cmp r3,#0 @ end word ? |
|||
beq 6f |
|||
cmp r2,#0 @ first letter ? |
|||
bne 2f |
|||
strb r3,[r1,r2] @ yes store in first position |
|||
add r2,r2,#1 @ increment indice |
|||
b 1b @ and loop |
|||
2: |
|||
mov r4,#0 |
|||
3: @ begin loop to search insertion position |
|||
ldrb r5,[r1,r4] @ load letter |
|||
cmp r3,r5 @ compare |
|||
blt 4f @ to low -> insertion |
|||
add r4,r4,#1 @ increment indice |
|||
cmp r4,r2 @ compare to letters number in place |
|||
blt 3b @ search loop |
|||
strb r3,[r1,r2] @ else store in last position |
|||
add r2,r2,#1 |
|||
b 1b @ and loop |
|||
4: @ move first letters in one position |
|||
sub r6,r2,#1 @ start indice |
|||
5: |
|||
ldrb r5,[r1,r6] @ load letter |
|||
add r7,r6,#1 @ store indice - 1 |
|||
strb r5,[r1,r7] @ store letter |
|||
sub r6,r6,#1 @ decrement indice |
|||
cmp r6,r4 @ end ? |
|||
bge 5b @ no loop |
|||
strb r3,[r1,r4] @ else store letter in free position |
|||
add r2,r2,#1 |
|||
b 1b @ and loop |
|||
6: |
|||
mov r3,#0 @ final zéro |
|||
strb r3,[r1,r2] |
|||
100: |
|||
pop {r1-r7,pc} |
|||
/***************************************************/ |
|||
/* Appel récursif Tri Rapide quicksort */ |
|||
/***************************************************/ |
|||
/* r0 contains the address of table */ |
|||
/* r1 contains index of first item */ |
|||
/* r2 contains the number of elements > 0 */ |
|||
/* r3 contains the address of table 2 */ |
|||
triRapide: |
|||
push {r2-r6,lr} @ save registers |
|||
mov r6,r3 |
|||
sub r2,#1 @ last item index |
|||
cmp r1,r2 @ first > last ? |
|||
bge 100f @ yes -> end |
|||
mov r4,r0 @ save r0 |
|||
mov r5,r2 @ save r2 |
|||
mov r3,r6 |
|||
bl partition1 @ cutting into 2 parts |
|||
mov r2,r0 @ index partition |
|||
mov r0,r4 @ table address |
|||
bl triRapide @ sort lower part |
|||
mov r0,r4 @ table address |
|||
add r1,r2,#1 @ index begin = index partition + 1 |
|||
add r2,r5,#1 @ number of elements |
|||
bl triRapide @ sort higter part |
|||
100: @ end function |
|||
pop {r2-r6,lr} @ restaur registers |
|||
bx lr @ return |
|||
/******************************************************************/ |
|||
/* Partition table elements */ |
|||
/******************************************************************/ |
|||
/* r0 contains the address of table */ |
|||
/* r1 contains index of first item */ |
|||
/* r2 contains index of last item */ |
|||
/* r3 contains the address of table 2 */ |
|||
partition1: |
|||
push {r1-r12,lr} @ save registers |
|||
mov r8,r0 @ save address table 2 |
|||
mov r9,r1 |
|||
ldr r10,[r8,r2,lsl #2] @ load string address last index |
|||
mov r4,r9 @ init with first index |
|||
mov r5,r9 @ init with first index |
|||
1: @ begin loop |
|||
ldr r6,[r8,r5,lsl #2] @ load string address |
|||
mov r0,r6 |
|||
mov r1,r10 |
|||
bl comparStrings |
|||
cmp r0,#0 |
|||
ldrlt r7,[r8,r4,lsl #2] @ if < swap value table |
|||
strlt r6,[r8,r4,lsl #2] |
|||
strlt r7,[r8,r5,lsl #2] |
|||
ldrlt r7,[r3,r4,lsl #2] @ swap array 2 |
|||
ldrlt r12,[r3,r5,lsl #2] |
|||
strlt r7,[r3,r5,lsl #2] |
|||
strlt r12,[r3,r4,lsl #2] |
|||
addlt r4,#1 @ and increment index 1 |
|||
add r5,#1 @ increment index 2 |
|||
cmp r5,r2 @ end ? |
|||
blt 1b @ no -> loop |
|||
ldr r7,[r8,r4,lsl #2] @ swap value |
|||
str r10,[r8,r4,lsl #2] |
|||
str r7,[r8,r2,lsl #2] |
|||
ldr r7,[r3,r4,lsl #2] @ swap array 2 |
|||
ldr r12,[r3,r2,lsl #2] |
|||
str r7,[r3,r2,lsl #2] |
|||
str r12,[r3,r4,lsl #2] |
|||
mov r0,r4 @ return index partition |
|||
100: |
|||
pop {r1-r12,lr} |
|||
bx lr |
|||
/************************************/ |
|||
/* Strings case sensitive comparisons */ |
|||
/************************************/ |
|||
/* r0 et r1 contains the address of strings */ |
|||
/* return 0 in r0 if equals */ |
|||
/* return -1 if string r0 < string r1 */ |
|||
/* return 1 if string r0 > string r1 */ |
|||
comparStrings: |
|||
push {r1-r4} @ save des registres |
|||
mov r2,#0 @ counter |
|||
1: |
|||
ldrb r3,[r0,r2] @ byte string 1 |
|||
ldrb r4,[r1,r2] @ byte string 2 |
|||
cmp r3,r4 |
|||
movlt r0,#-1 @ small |
|||
movgt r0,#1 @ greather |
|||
bne 100f @ not equals |
|||
cmp r3,#0 @ 0 end string |
|||
moveq r0,#0 @ equals |
|||
beq 100f @ end string |
|||
add r2,r2,#1 @ else add 1 in counter |
|||
b 1b @ and loop |
|||
100: |
|||
pop {r1-r4} |
|||
bx lr |
|||
/***************************************************/ |
|||
/* ROUTINES INCLUDE */ |
|||
/***************************************************/ |
|||
.include "../affichage.inc" |
|||
</lang> |
|||
<pre> |
|||
bale able bela abel elba |
|||
cater carte crate caret trace |
|||
galen glean angle lange angel |
|||
regal glare alger lager large |
|||
lena lane lean elan neal |
|||
veil levi live vile evil |
|||
</pre> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
Following code should work for AHK 1.0.* and 1.1* versions: |
Following code should work for AHK 1.0.* and 1.1* versions: |