24 game/Solve: Difference between revisions

Content added Content deleted
(Added C#)
(add task to arm assembly raspberry pi)
Line 614: Line 614:
$ ./24_game_solve 1127
$ ./24_game_solve 1127
(1+2)*(1+7)</pre>
(1+2)*(1+7)</pre>
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<lang ARM Assembly>
/* ARM assembly Raspberry PI */
/* program game24Solver.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 STDIN, 0 @ Linux input console
.equ READ, 3 @ Linux syscall
.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"
szCarriageReturn: .asciz "\n"
.align 4
iGraine: .int 123456
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
.align 4
sZoneConv: .skip 24
sBuffer: .skip BUFFERSIZE
iTabDigit: .skip 4 * NBDIGITS @ digits table
iTabOperand1: .skip 4 * NBDIGITS @ operand 1 table
iTabOperand2: .skip 4 * NBDIGITS @ operand 2 table
iTabOperation: .skip 4 * NBDIGITS @ operator table
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
ldr r0,iAdrszMessRules @ display rules
bl affichageMess
1:
mov r3,#0
ldr r12,iAdriTabDigit
ldr r5,iAdrszMessDigits
2: @ loop generate random digits
mov r0,#8
bl genereraleas
add r0,r0,#1
str r0,[r12,r3,lsl #2] @ store in table
ldr r1,iAdrsZoneConv
bl conversion10 @ call decimal conversion
mov r2,#0
strb r2,[r1,r0] @ reduce size display area with zéro final
mov r0,r5
ldr r1,iAdrsZoneConv @ insert conversion in message
bl strInsertAtCharInc
mov r5,r0
add r3,r3,#1
cmp r3,#NBDIGITS @ end ?
blt 2b @ no -> loop
mov r0,r5
bl affichageMess
mov r0,#0 @ start leval
mov r1,r12 @ address digits table
bl searchSoluce
cmp r0,#-1 @ solution ?
bne 3f @ no
ldr r0,iAdrszMessOK
bl affichageMess
bl writeSoluce @ yes -> write solution in buffer
ldr r0,iAdrsBuffer @ and display buffer
bl affichageMess
b 10f
3: @ display message no solution
ldr r0,iAdrszMessNotOK
bl affichageMess


10: @ display new game ?
ldr r0,iAdrszCarriageReturn
bl affichageMess
ldr r0,iAdrszMessNewGame
bl affichageMess
bl saisie
cmp r0,#'y'
beq 1b
cmp r0,#'Y'
beq 1b
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
iAdrszMessRules: .int szMessRules
iAdrszMessDigits: .int szMessDigits
iAdrszMessNotOK: .int szMessNotOK
iAdrszMessOK: .int szMessOK
iAdrszMessNewGame: .int szMessNewGame
iAdrsZoneConv: .int sZoneConv
iAdriTabDigit: .int iTabDigit
/******************************************************************/
/* recherche solution */
/******************************************************************/
/* r0 level */
/* r1 table value address */
/* r0 return -1 if ok */
searchSoluce:
push {r1-r12,lr} @ save registers
sub sp,#4* NBDIGITS @ reserve size new digits table
mov fp,sp @ frame pointer = address stack
mov r10,r1 @ save table
add r9,r0,#1 @ new level
rsb r3,r9,#NBDIGITS @ last element digits table
ldr r4,[r1,r3,lsl #2] @ load last element
cmp r4,#TOTAL @ equal to total to search ?
bne 0f @ no
cmp r9,#NBDIGITS @ all digits are used ?
bne 0f @ no
mov r0,#-1 @ yes -> it is ok -> end
b 100f
0:
mov r5,#0 @ indice loop 1
1: @ begin loop 1
cmp r5,r3
bge 9f
ldr r4,[r10,r5,lsl #2] @ load first operand
ldr r8,iAdriTabOperand1
str r4,[r8,r9,lsl #2] @ and store in operand1 table
add r6,r5,#1 @ indice loop 2
2: @ begin loop 2
cmp r6,r3
bgt 8f
ldr r12,[r10,r6,lsl #2] @ load second operand
ldr r8,iAdriTabOperand2
str r12,[r8,r9,lsl #2] @ and store in operand2 table
mov r7,#0 @ k
mov r8,#0 @ n
3:
cmp r7,r5
beq 4f
cmp r7,r6
beq 4f
ldr r0,[r10,r7,lsl #2] @ copy other digits in new table on stack
str r0,[fp,r8,lsl #2]
add r8,r8,#1
4:
add r7,r7,#1
cmp r7,r3
ble 3b

add r7,r4,r12 @ addition test
str r7,[fp,r8,lsl #2] @ store result of addition
mov r7,#'+'
ldr r0,iAdriTabOperation
str r7,[r0,r9,lsl #2] @ store operator
mov r0,r9 @ pass new level
mov r1,fp @ pass new table address on stack
bl searchSoluce
cmp r0,#0
blt 100f
@ soustraction test
cmp r4,r12
subgt r7,r4,r12
suble r7,r12,r4
str r7,[fp,r8,lsl #2]
mov r7,#'-'
ldr r0,iAdriTabOperation
str r7,[r0,r9,lsl #2]
mov r0,r9
mov r1,fp
bl searchSoluce
cmp r0,#0
blt 100f
mul r7,r4,r12 @ multiplication test
str r7,[fp,r8,lsl #2]
mov r7,#'*'
//vidregtit mult
ldr r0,iAdriTabOperation
str r7,[r0,r9,lsl #2]
mov r0,r9
mov r1,fp
bl searchSoluce
cmp r0,#0
blt 100f
5: @ division test
push {r1-r3}
mov r0,r4
mov r1,r12
bl division
// mov r7,r9
cmp r3,#0
bne 6f
str r2,[fp,r8,lsl #2]
mov r7,#'/'
ldr r0,iAdriTabOperation
str r7,[r0,r9,lsl #2]
mov r0,r9
mov r1,fp
bl searchSoluce
b 7f
6:
mov r0,r12
mov r1,r4
bl division
cmp r3,#0
bne 7f
str r2,[fp,r8,lsl #2]
mov r7,#'/'
ldr r0,iAdriTabOperation
str r7,[r0,r9,lsl #2]
mov r0,r9
mov r1,fp
bl searchSoluce
7:
pop {r1-r3}
cmp r0,#0
blt 100f
add r6,r6,#1 @ increment indice loop 2
b 2b

8:
add r5,r5,#1 @ increment indice loop 1
b 1b
9:
100:
add sp,#4* NBDIGITS @ stack alignement
pop {r1-r12,lr}
bx lr @ return
iAdriTabOperand1: .int iTabOperand1
iAdriTabOperand2: .int iTabOperand2
iAdriTabOperation: .int iTabOperation
/******************************************************************/
/* write solution */
/******************************************************************/
writeSoluce:
push {r1-r12,lr} @ save registers
ldr r6,iAdriTabOperand1
ldr r7,iAdriTabOperand2
ldr r8,iAdriTabOperation
ldr r10,iAdrsBuffer
mov r4,#0 @ buffer indice
mov r9,#1
1:
ldr r0,[r6,r9,lsl #2] @ operand 1
ldr r11,[r7,r9,lsl #2] @ operand 2
ldr r12,[r8,r9,lsl #2] @ operator
cmp r12,#'-'
beq 2f
cmp r12,#'/'
beq 2f
b 3f
2: @ if division or souistraction
cmp r0,r11 @ reverse operand if operand 1 is < operand 2
movlt r2,r0
movlt r0,r11
movlt r11,r2
3: @ conversion operand 1 = r0
mov r1,#10
bl division
cmp r2,#0
addne r2,r2,#0x30
strneb r2,[r10,r4]
addne r4,r4,#1
add r3,r3,#0x30
strb r3,[r10,r4]
add r4,r4,#1
ldr r2,[r7,r9,lsl #2]

strb r12,[r10,r4] @ operator
add r4,r4,#1
mov r0,r11 @ conversion operand 2
mov r1,#10
bl division
cmp r2,#0
addne r2,r2,#0x30
strneb r2,[r10,r4]
addne r4,r4,#1
add r3,r3,#0x30
strb r3,[r10,r4]
add r4,r4,#1
mov r0,#'='
str r0,[r10,r4] @ conversion sous total
add r4,r4,#1
cmp r9,#1
ldreq r0,[r6,#12]
cmp r9,#2
ldreq r0,[r7,#12]
cmp r9,#3
moveq r0,#TOTAL @ display total
mov r1,#10
bl division
cmp r2,#0
addne r2,r2,#0x30
strneb r2,[r10,r4]
addne r4,r4,#1
add r3,r3,#0x30
strb r3,[r10,r4]
add r4,r4,#1
mov r0,#'\n'
str r0,[r10,r4]
add r4,r4,#1
add r9,#1
cmp r9,#NBDIGITS
blt 1b
mov r1,#0
strb r1,[r10,r4] @ store 0 final
100:
pop {r1-r12,lr}
bx lr @ return
iAdrsBuffer: .int sBuffer

/******************************************************************/
/* string entry */
/******************************************************************/
/* r0 return the first character of human entry */
saisie:
push {r1-r7,lr} @ save registers
mov r0,#STDIN @ Linux input console
ldr r1,iAdrsBuffer @ buffer address
mov r2,#BUFFERSIZE @ buffer size
mov r7,#READ @ request to read datas
svc 0 @ call system
ldr r1,iAdrsBuffer @ buffer address
ldrb r0,[r1] @ load first character
100:
pop {r1-r7,lr}
bx lr @ return
/***************************************************/
/* Generation random number */
/***************************************************/
/* r0 contains limit */
genereraleas:
push {r1-r4,lr} @ save registers
ldr r4,iAdriGraine
ldr r2,[r4]
ldr r3,iNbDep1
mul r2,r3,r2
ldr r3,iNbDep2
add r2,r2,r3
str r2,[r4] @ maj de la graine pour l appel suivant
cmp r0,#0
beq 100f
add r1,r0,#1 @ divisor
mov r0,r2 @ dividende
bl division
mov r0,r3 @ résult = remainder
100: @ end function
pop {r1-r4,lr} @ restaur registers
bx lr @ return
/*****************************************************/
iAdriGraine: .int iGraine
iNbDep1: .int 0x343FD
iNbDep2: .int 0x269EC3
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
</lang>
{{output}}
<pre>
New game (y/n) ?
y
The four digits are 8 3 9 1 and the score is 24.
Solution :
8*9=72
3*1=3
72/3=24

New game (y/n) ?
y
The four digits are 7 7 9 4 and the score is 24.
No solution for this problem !!

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

New game (y/n) ?
</pre>
=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
{{works with|AutoHotkey_L}}