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}} |