Aliquot sequence classifications: Difference between revisions

add task to arm assembly raspberry pi
(Add CLU)
(add task to arm assembly raspberry pi)
Line 336:
1488: non-terminating 1488, 2480, 3472, 4464, 8432, 9424, 10416, 21328, 22320, 55056, 95728, 96720, 236592, 459792, 881392, 882384
1.535571778608E+13: non-terminating 1.535571778608E+13, 4.453466360112E+13, 1.449400874645E+14"</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 aliquotSeq.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 MAXINUM, 10
.equ MAXI, 16
.equ NBDIVISORS, 1000
 
/*******************************************/
/* Initialized data */
/*******************************************/
.data
szMessStartPgm: .asciz "Program start \n"
szMessEndPgm: .asciz "Program normal end.\n"
szMessErrorArea: .asciz "\033[31mError : area divisors too small.\033[0m \n"
szMessError: .asciz "\033[31mError !!!\033[0m \n"
szMessErrGen: .asciz "Error end program.\033[0m \n"
 
szCarriageReturn: .asciz "\n"
szLibPerf: .asciz "Perfect \n"
szLibAmic: .asciz "Amicable \n"
szLibSoc: .asciz "Sociable \n"
szLibAspi: .asciz "Aspiring \n"
szLibCycl: .asciz "Cyclic \n"
szLibTerm: .asciz "Terminating \n"
szLibNoTerm: .asciz "No terminating\n"
 
/* datas message display */
szMessResult: .asciz " @ "
szMessResHead: .asciz "Number @ :"
 
.align 4
tbNumber: .int 11,12,28,496,220,1184,12496,1264460,790,909,562,1064,1488
.equ NBNUMBER, (. - tbNumber ) / 4
 
/*******************************************/
/* UnInitialized data */
/*******************************************/
.bss
.align 4
sZoneConv: .skip 24
tbZoneDecom: .skip 4 * NBDIVISORS // facteur 4 octets
tbNumberSucc: .skip 4 * MAXI
/*******************************************/
/* code section */
/*******************************************/
.text
.global main
main: @ program start
ldr r0,iAdrszMessStartPgm @ display start message
bl affichageMess
 
mov r4,#1
1:
mov r0,r4 @ number
bl aliquotClassif @ aliquot classification
cmp r0,#-1 @ error ?
beq 99f
add r4,r4,#1
cmp r4,#MAXINUM
ble 1b
ldr r5,iAdrtbNumber @ number array
mov r4,#0
2:
ldr r0,[r5,r4,lsl #2] @ load a number
bl aliquotClassif @ aliquot classification
cmp r0,#-1 @ error ?
beq 99f
add r4,r4,#1 @ next number
cmp r4,#NBNUMBER @ maxi ?
blt 2b @ no -> loop
ldr r0,iAdrszMessEndPgm @ display end message
bl affichageMess
b 100f
99: @ display error message
ldr r0,iAdrszMessError
bl affichageMess
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc 0 @ perform system call
iAdrszMessStartPgm: .int szMessStartPgm
iAdrszMessEndPgm: .int szMessEndPgm
iAdrszMessError: .int szMessError
iAdrszCarriageReturn: .int szCarriageReturn
iAdrtbZoneDecom: .int tbZoneDecom
iAdrszMessResult: .int szMessResult
iAdrsZoneConv: .int sZoneConv
iAdrtbNumber: .int tbNumber
/******************************************************************/
/* function aliquot classification */
/******************************************************************/
/* r0 contains number */
aliquotClassif:
push {r3-r8,lr} @ save registers
mov r5,r0 @ save number
ldr r1,iAdrsZoneConv
bl conversion10 @ convert ascii string
mov r2,#0
strb r2,[r1,r0]
ldr r0,iAdrszMessResHead
ldr r1,iAdrsZoneConv
bl strInsertAtCharInc @ put in head message
bl affichageMess @ and display
mov r0,r5 @ restaur number
ldr r7,iAdrtbNumberSucc @ number successif array
mov r4,#0 @ counter number successif
1:
mov r6,r0 @ previous number
ldr r1,iAdrtbZoneDecom
bl decompFact @ create area of divisors
cmp r0,#0 @ error ?
blt 99f
sub r3,r1,r6 @ sum
mov r0,r3
ldr r1,iAdrsZoneConv
bl conversion10 @ convert ascii string
mov r2,#0
strb r2,[r1,r0]
ldr r0,iAdrszMessResult
ldr r1,iAdrsZoneConv
bl strInsertAtCharInc @ and put in message
bl affichageMess
cmp r3,#0 @ sum = zero
bne 11f
ldr r0,iAdrszLibTerm @ terminating
bl affichageMess
b 100f
11:
cmp r5,r3 @ compare number and sum
bne 4f
cmp r4,#0 @ first loop ?
bne 2f
ldr r0,iAdrszLibPerf @ perfect
bl affichageMess
b 100f
2:
cmp r4,#1 @ second loop ?
bne 3f
ldr r0,iAdrszLibAmic @ amicable
bl affichageMess
b 100f
3: @ other loop
ldr r0,iAdrszLibSoc @ sociable
bl affichageMess
b 100f
4:
cmp r6,r3 @ compare sum and (sum - 1)
bne 5f
ldr r0,iAdrszLibAspi @ aspirant
bl affichageMess
b 100f
5:
cmp r3,#1 @ if one ,no search in array
beq 7f
mov r2,#0 @ search indice
6: @ search number in array
ldr r8,[r7,r2,lsl #2]
cmp r8,r3 @ equal ?
beq 8f @ yes -> cycling
add r2,r2,#1 @ increment indice
cmp r2,r4 @ end ?
blt 6b @ no -> loop
7:
cmp r4,#MAXI
blt 10f
ldr r0,iAdrszLibNoTerm @ no terminating
bl affichageMess
b 100f
8: @ cycling
ldr r0,iAdrszLibCycl
bl affichageMess
b 100f
10:
str r3,[r7,r4,lsl #2] @ store new sum in array
add r4,r4,#1 @ increment counter
mov r0,r3 @ new number = new sum
b 1b @ and loop
99: @ display error
ldr r0,iAdrszMessError
bl affichageMess
100:
pop {r3-r8,lr} @ restaur registers
bx lr
iAdrszMessResHead: .int szMessResHead
iAdrszLibPerf: .int szLibPerf
iAdrszLibAmic: .int szLibAmic
iAdrszLibSoc: .int szLibSoc
iAdrszLibCycl: .int szLibCycl
iAdrszLibAspi: .int szLibAspi
iAdrszLibNoTerm: .int szLibNoTerm
iAdrszLibTerm: .int szLibTerm
iAdrtbNumberSucc: .int tbNumberSucc
/******************************************************************/
/* factor decomposition */
/******************************************************************/
/* r0 contains number */
/* r1 contains address of divisors area */
/* r0 return divisors items in array */
/* r1 return the sum of divisors */
decompFact:
push {r3-r12,lr} @ save registers
cmp r0,#1
moveq r1,#1
beq 100f
mov r5,r1
mov r8,r0 @ save number
bl isPrime @ prime ?
cmp r0,#1
beq 98f @ yes is prime
mov r1,#1
str r1,[r5] @ first factor
mov r12,#1 @ divisors sum
mov r10,#1 @ indice divisors table
mov r9,#2 @ first divisor
mov r6,#0 @ previous divisor
mov r7,#0 @ number of same divisors
/* division loop */
2:
mov r0,r8 @ dividende
mov r1,r9 @ divisor
bl division @ r2 quotient r3 remainder
cmp r3,#0
beq 3f @ if remainder zero -> divisor
/* not divisor -> increment next divisor */
cmp r9,#2 @ if divisor = 2 -> add 1
addeq r9,#1
addne r9,#2 @ else add 2
b 2b
/* divisor compute the new factors of number */
3:
mov r8,r2 @ else quotient -> new dividende
cmp r9,r6 @ same divisor ?
beq 4f @ yes
mov r0,r5 @ table address
mov r1,r10 @ number factors in table
mov r2,r9 @ divisor
mov r3,r12 @ somme
mov r4,#0
bl computeFactors
cmp r0,#-1
beq 100f
mov r10,r1
mov r12,r0
mov r6,r9 @ new divisor
b 7f
4: @ same divisor
sub r7,r10,#1
5: @ search in table the first use of divisor
ldr r3,[r5,r7,lsl #2 ]
cmp r3,r9
subne r7,#1
bne 5b
@ and compute new factors after factors
sub r4,r10,r7 @ start indice
mov r0,r5
mov r1,r10
mov r2,r9 @ divisor
mov r3,r12
bl computeFactors
cmp r0,#-1
beq 100f
mov r12,r0
mov r10,r1
 
/* divisor -> test if new dividende is prime */
7:
cmp r8,#1 @ dividende = 1 ? -> end
beq 10f
mov r0,r8 @ new dividende is prime ?
mov r1,#0
bl isPrime @ the new dividende is prime ?
cmp r0,#1
bne 10f @ the new dividende is not prime
 
cmp r8,r6 @ else dividende is same divisor ?
beq 8f @ yes
mov r0,r5
mov r1,r10
mov r2,r8
mov r3,r12
mov r4,#0
bl computeFactors
cmp r0,#-1
beq 100f
mov r12,r0
mov r10,r1
mov r7,#0
b 11f
8:
sub r7,r10,#1
9:
ldr r3,[r5,r7,lsl #2 ]
cmp r3,r8
subne r7,#1
bne 9b
mov r0,r5
mov r1,r10
sub r4,r10,r7
mov r2,r8
mov r3,r12
bl computeFactors
cmp r0,#-1
beq 100f
mov r12,r0
mov r10,r1
b 11f
10:
cmp r9,r8 @ current divisor > new dividende ?
ble 2b @ no -> loop
/* end decomposition */
11:
mov r0,r10 @ return number of table items
mov r1,r12 @ return sum
mov r3,#0
str r3,[r5,r10,lsl #2] @ store zéro in last table item
b 100f
 
98: @ prime number
add r1,r8,#1
mov r0,#0 @ return code
b 100f
99:
ldr r0,iAdrszMessError
bl affichageMess
mov r0,#-1 @ error code
b 100f
100:
pop {r3-r12,pc} @ restaur registers
/******************************************************************/
/* compute all factors */
/******************************************************************/
 
/* r0 table factors address */
/* r1 number factors in table */
/* r2 new divisor */
/* r3 sum */
/* r4 start indice */
/* r0 return sum */
/* r1 return number factors in table */
computeFactors:
push {r2-r6,lr} @ save registers
mov r6,r1 @ number factors in table
1:
ldr r5,[r0,r4,lsl #2 ] @ load one factor
mul r5,r2,r5 @ multiply
str r5,[r0,r1,lsl #2] @ and store in the table
 
adds r3,r5
movcs r0,#-1 @ overflow
bcs 100f
add r1,r1,#1 @ and increment counter
add r4,r4,#1
cmp r4,r6
blt 1b
mov r0,r3 @ factors sum
100: @ fin standard de la fonction
pop {r2-r6,pc} @ restaur des registres
/***************************************************/
/* check if a number is prime */
/***************************************************/
/* r0 contains the number */
/* r0 return 1 if prime 0 else */
isPrime:
push {r1-r6,lr} @ save registers
cmp r0,#0
beq 90f
cmp r0,#17
bhi 1f
cmp r0,#3
bls 80f @ for 1,2,3 return prime
cmp r0,#5
beq 80f @ for 5 return prime
cmp r0,#7
beq 80f @ for 7 return prime
cmp r0,#11
beq 80f @ for 11 return prime
cmp r0,#13
beq 80f @ for 13 return prime
cmp r0,#17
beq 80f @ for 17 return prime
1:
tst r0,#1 @ even ?
beq 90f @ yes -> not prime
mov r2,r0 @ save number
sub r1,r0,#1 @ exposant n - 1
mov r0,#3 @ base
bl moduloPuR32 @ compute base power n - 1 modulo n
cmp r0,#1
bne 90f @ if <> 1 -> not prime
mov r0,#5
bl moduloPuR32
cmp r0,#1
bne 90f
mov r0,#7
bl moduloPuR32
cmp r0,#1
bne 90f
mov r0,#11
bl moduloPuR32
cmp r0,#1
bne 90f
mov r0,#13
bl moduloPuR32
cmp r0,#1
bne 90f
mov r0,#17
bl moduloPuR32
cmp r0,#1
bne 90f
80:
mov r0,#1 @ is prime
b 100f
90:
mov r0,#0 @ no prime
100: @ fin standard de la fonction
pop {r1-r6,pc} @ restaur des registres
/********************************************************/
/* Calcul modulo de b puissance e modulo m */
/* Exemple 4 puissance 13 modulo 497 = 445 */
/* */
/********************************************************/
/* r0 nombre */
/* r1 exposant */
/* r2 modulo */
/* r0 return result */
moduloPuR32:
push {r1-r7,lr} @ save registers
cmp r0,#0 @ verif <> zero
beq 100f
cmp r2,#0 @ verif <> zero
beq 100f @ TODO: v鲩fier les cas d erreur
1:
mov r4,r2 @ save modulo
mov r5,r1 @ save exposant
mov r6,r0 @ save base
mov r3,#1 @ start result
 
mov r1,#0 @ division de r0,r1 par r2
bl division32R
mov r6,r2 @ base <- remainder
2:
tst r5,#1 @ exposant even or odd
beq 3f
umull r0,r1,r6,r3
mov r2,r4
bl division32R
mov r3,r2 @ result <- remainder
3:
umull r0,r1,r6,r6
mov r2,r4
bl division32R
mov r6,r2 @ base <- remainder
 
lsr r5,#1 @ left shift 1 bit
cmp r5,#0 @ end ?
bne 2b
mov r0,r3
100: @ fin standard de la fonction
pop {r1-r7,pc} @ restaur des registres
 
/***************************************************/
/* division number 64 bits in 2 registers by number 32 bits */
/***************************************************/
/* r0 contains lower part dividende */
/* r1 contains upper part dividende */
/* r2 contains divisor */
/* r0 return lower part quotient */
/* r1 return upper part quotient */
/* r2 return remainder */
division32R:
push {r3-r9,lr} @ save registers
mov r6,#0 @ init upper upper part remainder !!
mov r7,r1 @ init upper part remainder with upper part dividende
mov r8,r0 @ init lower part remainder with lower part dividende
mov r9,#0 @ upper part quotient
mov r4,#0 @ lower part quotient
mov r5,#32 @ bits number
1: @ begin loop
lsl r6,#1 @ shift upper upper part remainder
lsls r7,#1 @ shift upper part remainder
orrcs r6,#1
lsls r8,#1 @ shift lower part remainder
orrcs r7,#1
lsls r4,#1 @ shift lower part quotient
lsl r9,#1 @ shift upper part quotient
orrcs r9,#1
@ divisor sustract upper part remainder
subs r7,r2
sbcs r6,#0 @ and substract carry
bmi 2f @ n駡tive ?
@ positive or equal
orr r4,#1 @ 1 -> right bit quotient
b 3f
2: @ negative
orr r4,#0 @ 0 -> right bit quotient
adds r7,r2 @ and restaur remainder
adc r6,#0
3:
subs r5,#1 @ decrement bit size
bgt 1b @ end ?
mov r0,r4 @ lower part quotient
mov r1,r9 @ upper part quotient
mov r2,r7 @ remainder
100: @ function end
pop {r3-r9,pc} @ restaur registers
 
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
 
</lang>
<pre>
Program start
Number 1 : 0 Terminating
Number 2 : 1 0 Terminating
Number 3 : 1 0 Terminating
Number 4 : 3 1 0 Terminating
Number 5 : 1 0 Terminating
Number 6 : 6 Perfect
Number 7 : 1 0 Terminating
Number 8 : 7 1 0 Terminating
Number 9 : 4 3 1 0 Terminating
Number 10 : 8 7 1 0 Terminating
Number 11 : 1 0 Terminating
Number 12 : 16 15 9 4 3 1 0 Terminating
Number 28 : 28 Perfect
Number 496 : 496 Perfect
Number 220 : 284 220 Amicable
Number 1184 : 1210 1184 Amicable
Number 12496 : 14288 15472 14536 14264 12496 Sociable
Number 1264460 : 1547860 1727636 1305184 1264460 Sociable
Number 790 : 650 652 496 496 Aspiring
Number 909 : 417 143 25 6 6 Aspiring
Number 562 : 284 220 284 Cyclic
Number 1064 : 1336 1184 1210 1184 Cyclic
Number 1488 : 2480 3472 4464 8432 9424 10416 21328 22320 55056 95728 96720 236592 459792 881392 882384 1474608 2461648 No terminating
Program normal end.
</pre>
=={{header|AWK}}==