24 game/Solve: Difference between revisions

Content added Content deleted
(add task to arm assembly raspberry pi)
(add task to aarch64 assembly raspberry pi)
Line 10: Line 10:
*   [[Arithmetic Evaluator]]
*   [[Arithmetic Evaluator]]
<br><br>
<br><br>
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<lang AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program game24Solvex64.s */


/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"

.equ NBDIGITS, 4 // digits number
.equ TOTAL, 24
.equ BUFFERSIZE, 80

/*********************************/
/* Initialized data */
/*********************************/
.data
szMessRules: .ascii "24 Game\n"
.ascii "The program will display four randomly-generated \n"
.asciz "single-digit numbers and search a solution for a total to 24\n\n"

szMessDigits: .asciz "The four digits are @ @ @ @ and the score is 24. \n"
szMessOK: .asciz "Solution : \n"
szMessNotOK: .asciz "No solution for this problem !! \n"
szMessNewGame: .asciz "New game (y/n) ? \n"
szMessErrOper: .asciz "Error opérator in display result !!!"
szCarriageReturn: .asciz "\n"
.align 4
qGraine: .quad 123456
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
.align 4
sZoneConv: .skip 24
sBuffer: .skip BUFFERSIZE
qTabDigit: .skip 8 * NBDIGITS // digits table
qTabOperand1: .skip 8 * NBDIGITS // operand 1 table
qTabOperand2: .skip 8 * NBDIGITS // operand 2 table
qTabOperation: .skip 8 * NBDIGITS // operator table
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrszMessRules // display rules
bl affichageMess
1:
mov x3,#0
ldr x12,qAdrqTabDigit
ldr x5,qAdrszMessDigits
2: // loop generate random digits
mov x0,#8
bl genereraleas
add x0,x0,#1
str x0,[x12,x3,lsl 3] // store in table
ldr x1,qAdrsZoneConv
bl conversion10 // call decimal conversion
mov x0,x5
ldr x1,qAdrsZoneConv // insert conversion in message
bl strInsertAtCharInc
mov x5,x0
add x3,x3,#1
cmp x3,#NBDIGITS // end ?
blt 2b // no -> loop
mov x0,x5
bl affichageMess
mov x0,#0 // start leval
mov x1,x12 // address digits table
bl searchSoluce
cmp x0,#-1 // solution ?
bne 3f // no
ldr x0,qAdrszMessOK
bl affichageMess
bl writeSoluce // yes -> write solution in buffer
ldr x0,qAdrsBuffer // and display buffer
bl affichageMess
b 10f
3: // display message no solution
ldr x0,qAdrszMessNotOK
bl affichageMess


10: // display new game ?
ldr x0,qAdrszCarriageReturn
bl affichageMess
ldr x0,qAdrszMessNewGame
bl affichageMess
bl saisie
cmp x0,#'y'
beq 1b
cmp x0,#'Y'
beq 1b
100: // standard end of the program
mov x0,0 // return code
mov x8,EXIT // request to exit program
svc 0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrszMessRules: .quad szMessRules
qAdrszMessDigits: .quad szMessDigits
qAdrszMessNotOK: .quad szMessNotOK
qAdrszMessOK: .quad szMessOK
qAdrszMessNewGame: .quad szMessNewGame
qAdrsZoneConv: .quad sZoneConv
qAdrqTabDigit: .quad qTabDigit
/******************************************************************/
/* recherche solution */
/******************************************************************/
/* x0 level */
/* x1 table value address */
/* x0 return -1 if ok */
searchSoluce:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
stp x8,x9,[sp,-16]! // save registres
stp x10,x11,[sp,-16]! // save registres
stp x12,fp,[sp,-16]! // save registres
sub sp,sp,#8* NBDIGITS // reserve size new digits table
mov fp,sp // frame pointer = address stack
mov x10,x1 // save table
add x9,x0,#1 // new level
mov x13,#NBDIGITS
sub x3,x13,x9 // last element digits table
ldr x4,[x1,x3,lsl 3] // load last element
cmp x4,#TOTAL // equal to total to search ?
bne 0f // no
cmp x9,#NBDIGITS // all digits are used ?
bne 0f // no
mov x0,#-1 // yes -> it is ok -> end
b 100f
0:
mov x5,#0 // indice loop 1
1: // begin loop 1
cmp x5,x3
bge 9f
ldr x4,[x10,x5,lsl 3] // load first operand
ldr x8,qAdrqTabOperand1
str x4,[x8,x9,lsl 3] // and store in operand1 table
add x6,x5,#1 // indice loop 2
2: // begin loop 2
cmp x6,x3
bgt 8f
ldr x12,[x10,x6,lsl 3] // load second operand
ldr x8,qAdrqTabOperand2
str x12,[x8,x9,lsl 3] // and store in operand2 table
mov x7,#0 // k
mov x8,#0 // n
3:
cmp x7,x5
beq 4f
cmp x7,x6
beq 4f
ldr x0,[x10,x7,lsl 3] // copy other digits in new table on stack
str x0,[fp,x8,lsl 3]
add x8,x8,#1
4:
add x7,x7,#1
cmp x7,x3
ble 3b

add x7,x4,x12 // addition test
str x7,[fp,x8,lsl 3] // store result of addition
mov x7,#'+'
ldr x0,qAdrqTabOperation
str x7,[x0,x9,lsl 3] // store operator
mov x0,x9 // pass new level
mov x1,fp // pass new table address on stack
bl searchSoluce
cmp x0,#0
blt 100f
// soustraction test
sub x13,x4,x12
sub x14,x12,x4
cmp x4,x12
csel x7,x13,x14,gt
str x7,[fp,x8,lsl 3]
mov x7,#'-'
ldr x0,qAdrqTabOperation
str x7,[x0,x9,lsl 3]
mov x0,x9
mov x1,fp
bl searchSoluce
cmp x0,#0
blt 100f
mul x7,x4,x12 // multiplication test
str x7,[fp,x8,lsl 3]
mov x7,#'*'
ldr x0,qAdrqTabOperation
str x7,[x0,x9,lsl 3]
mov x0,x9
mov x1,fp
bl searchSoluce
cmp x0,#0
blt 100f
5: // division test
udiv x13,x4,x12
msub x14,x13,x12,x4
cmp x14,#0
bne 6f
str x13,[fp,x8,lsl 3]
mov x7,#'/'
ldr x0,qAdrqTabOperation
str x7,[x0,x9,lsl 3]
mov x0,x9
mov x1,fp
bl searchSoluce
b 7f
6:
udiv x13,x12,x4
msub x14,x13,x4,x12
cmp x14,#0
bne 7f
str x13,[fp,x8,lsl 3]
mov x7,#'/'
ldr x0,qAdrqTabOperation
str x7,[x0,x9,lsl 3]
mov x0,x9
mov x1,fp
bl searchSoluce
7:
cmp x0,#0
blt 100f
add x6,x6,#1 // increment indice loop 2
b 2b

8:
add x5,x5,#1 // increment indice loop 1
b 1b
9:
100:
add sp,sp,8* NBDIGITS // stack alignement
ldp x12,fp,[sp],16 // restaur des 2 registres
ldp x10,x11,[sp],16 // restaur des 2 registres
ldp x8,x9,[sp],16 // restaur des 2 registres
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
qAdrqTabOperand1: .quad qTabOperand1
qAdrqTabOperand2: .quad qTabOperand2
qAdrqTabOperation: .quad qTabOperation
/******************************************************************/
/* write solution */
/******************************************************************/
writeSoluce:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
stp x8,x9,[sp,-16]! // save registres
stp x10,x11,[sp,-16]! // save registres
stp x12,fp,[sp,-16]! // save registres
ldr x6,qAdrqTabOperand1
ldr x7,qAdrqTabOperand2
ldr x8,qAdrqTabOperation
ldr x10,qAdrsBuffer
mov x4,#0 // buffer indice
mov x9,#1
1:
ldr x13,[x6,x9,lsl 3] // operand 1
ldr x11,[x7,x9,lsl 3] // operand 2
ldr x12,[x8,x9,lsl 3] // operator
cmp x12,#'-'
beq 2f
cmp x12,#'/'
beq 2f
b 3f
2: // if division or soustraction
cmp x13,x11 // reverse operand if operand 1 is < operand 2
bge 3f
mov x2,x13
mov x13,x11
mov x11,x2
3: // conversion operand 1 = x13
mov x1,#10
udiv x2,x13,x1
msub x3,x1,x2,x13
cmp x2,#0
beq 31f
add x2,x2,#0x30
strb w2,[x10,x4]
add x4,x4,#1
31:
add x3,x3,#0x30
strb w3,[x10,x4]
add x4,x4,#1
ldr x2,[x7,x9,lsl 3]

strb w12,[x10,x4] // operator
add x4,x4,#1
mov x1,#10 // conversion operand 2 = x11
udiv x2,x11,x1
msub x3,x2,x1,x11
cmp x2,#0
beq 32f
add x2,x2,#0x30
strb w2,[x10,x4]
add x4,x4,#1
32:
add x3,x3,#0x30
strb w3,[x10,x4]
add x4,x4,#1
mov x0,#'='
strb w0,[x10,x4] // compute sous total
add x4,x4,#1
cmp x12,'+' // addition
bne 33f
add x0,x13,x11
b 37f
33:
cmp x12,'-' // soustraction
bne 34f
sub x0,x13,x11
b 37f
34:
cmp x12,'*' // multiplication
bne 35f
mul x0,x13,x11
b 37f
35:
cmp x12,'/' // division
bne 36f
udiv x0,x13,x11
b 37f
36: // error
ldr x0,qAdrszMessErrOper
bl affichageMess
b 100f
37: // and conversion ascii
mov x1,#10
udiv x2,x0,x1
msub x3,x2,x1,x0
cmp x2,#0
beq 36f
add x2,x2,#0x30
strb w2,[x10,x4]
add x4,x4,#1
36:
add x3,x3,#0x30
strb w3,[x10,x4]
add x4,x4,#1
mov x0,#'\n'
strb w0,[x10,x4]
add x4,x4,#1
add x9,x9,1
cmp x9,#NBDIGITS
blt 1b
mov x1,#0
strb w1,[x10,x4] // store 0 final
100:
ldp x12,fp,[sp],16 // restaur des 2 registres
ldp x10,x11,[sp],16 // restaur des 2 registres
ldp x8,x9,[sp],16 // restaur des 2 registres
ldp x6,x7,[sp],16 // restaur des 2 registres
ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
qAdrsBuffer: .quad sBuffer
qAdrszMessErrOper: .quad szMessErrOper
/******************************************************************/
/* string entry */
/******************************************************************/
/* x0 return the first character of human entry */
saisie:
stp x1,lr,[sp,-16]! // save registres
stp x2,x8,[sp,-16]! // save registres
mov x0,#STDIN // Linux input console
ldr x1,qAdrsBuffer // buffer address
mov x2,#BUFFERSIZE // buffer size
mov x8,#READ // request to read datas
svc 0 // call system
ldr x1,qAdrsBuffer // buffer address
ldrb w0,[x1] // load first character
100:
ldp x2,x8,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/***************************************************/
/* Generation random number */
/***************************************************/
/* x0 contains limit */
genereraleas:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
ldr x4,qAdrqGraine
ldr x2,[x4]
ldr x3,qNbDep1
mul x2,x3,x2
ldr x3,qNbDep2
add x2,x2,x3
str x2,[x4] // maj de la graine pour l appel suivant
cmp x0,#0
beq 100f
add x1,x0,#1 // divisor
mov x0,x2 // dividende
udiv x3,x2,x1
msub x0,x3,x1,x0 // résult = remainder
100: // end function

ldp x4,x5,[sp],16 // restaur des 2 registres
ldp x2,x3,[sp],16 // restaur des 2 registres
ldp x1,lr,[sp],16 // restaur des 2 registres
ret
/*****************************************************/
qAdrqGraine: .quad qGraine
qNbDep1: .quad 0x0019660d
qNbDep2: .quad 0x3c6ef35f
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</lang>
{{Output}}
<pre>
The four digits are 6 8 3 1 and the score is 24.
Solution :
6*8=48
3-1=2
48/2=24

New game (y/n) ?
y
The four digits are 8 6 6 5 and the score is 24.
Solution :
8-5=3
6*3=18
6+18=24

New game (y/n) ?
</pre>
=={{header|ABAP}}==
=={{header|ABAP}}==
Will generate all possible solutions of any given four numbers according to the rules of the 24 game.
Will generate all possible solutions of any given four numbers according to the rules of the 24 game.