8051 Assembly (compiles to 158 bytes)
This is a VEEEEEEEEEERRY naive approch, this is yet untested and ungolfed but im pretty confident that works. Things to consider are:
1) the 8051 is an accumulator machine ie. it needs mov instructions that other architectures may not need at all.
2) the 8051 is an 8bit machine therefor there has to be done some trickery for the numbers >255 which makes for more code and is therefor a disadvantage of the platform over the others.
CSEG AT 0000H
coinStackOnes equ 0xf3
coinStackTens equ 0xf4
coinStackHundreds equ 0xf5 ; leave one byte as guard so that if that gets corrupted it doesnt really matter
values1 equ 0xf7
values2 equ 0xf8
values3 equ 0xf9
values4 equ 0xfa
numOfFlowers equ 0xfb
numOfLeaf equ 0xfc
numOfBell equ 0xfd
numOfCherry equ 0xfe
numOfBoomerang equ 0xff
flower equ 1
leaf equ 2
bell equ 3
cherry equ 4
boomerang equ 5
numOfHeartsReceived equ 0xf1
mov r1, #4
mov r0, numOfFlowers
clearNumOfRegs: mov @r0, #0d
inc r0
djnz r1, clearNumOfRegs
;if you reach this all numOfXXXX registers are zeroed
mov r0, #values1
mov r1, #flower
mov a, #6 ; innercounter
mov b, #5 ; outercounter
checkfornextpossibleitem: mov r2, a; backup countervar
mov a, @r0 ; store given value in a
xrl a, @r1 ; xor a with item
jnz nextItem ; if value!=item -> nextitem
mov a, #numOfFlowers ;if you end up here a=0 (ie value == item) --> generate addr for numOfReg <-- load a with addr for numOfFlowers
add a, r1 ; since items are only numbers you can add the item to get the addr for numOfReg a=addr(numOfReg)
xch a, r1 ; change the item with the addr as r1 is indirect register
inc @r1 ; increment numOfRegister
xch a, r1; r1 = item
;next item
nextItem: inc r1 ; increment item
mov a, r2 ; restore counter
dec a; decrement counter
cjne a, #0, checkfornextpossibleitem
;if you reach this you have successfully tested one value against all items and therefor the next value must be tested
mov a, #6; reset the innercounter
dec b; decrement the outercounter
inc r0; increment the register that points to the value-under-test
xch a,b; cjne works with a but not with b therefor exchange them
cjne a, #0, here ; do the comparison; if you dont jump here you have tested all values
jmp howManyPairsDoIHave; if you didnt jump above you have the now the number of flowers and so on
here: xch a,b ; and change back
jmp checkfornextpossibleitem ; check the next value
howManyPairsDoIHave: mov r0,#0; store numOfPairsHere initialize with zeros
mov r1, numOfFlowers;
mov b, #6; use as counter to know when you went through all numOfRegisters
analyseNumOfRegister: mov a, @r1 ; load the numOfregister for some math
xrl a, #2; a will contain zero if numOfXXX = 2
jnz numOfXXXWasNot2; if you do not jump here you have 2 XXX therefor
inc r0; increment the number of pairs
jmp nextNumOfRegister; continiue with the next one
numOfXXXWasNot2: mov a, @r1; restore the number of XXX and try the next magic value
xrl a, #3; will contain zero if you have a three of a kind
jnz no3XXX; if you dont jump here however you have a three of a kind
jz add300Coins
no3XXX: mov a, @r1; restore number of XXX
xrl a, #4; a will contain zero if 4 of a kind
jnz nextNumOfRegister; if you numOfXXX!=4 you can only continiue trying to find something in the next numof register
jz add777Coins; if you didnt jump above how ever you will have to add the 777 coins as you detected a 4 of a kind
nextNumOfRegister: inc r0; move pointer to the next numofregister
djnz b, analyseNumOfRegister; if you havent already analysed all numofregisters then continue
; if you have however you end up here so you will have to take a look at the numOfPairs
cjne r0, #1, tryIf2Pairs; test if you have 1 pair if not try if you have 2
jmp add100Coins; if you have 1 pair however add the 100 coins
tryIf2Pairs: cjne r0, #2, youMustHave0Pairs; test if you have 2 pairs if not you can be sure to have 0 of them
jmp add200Coins; if you have 2 pairs however add them
youMustHave0Pairs: ; add 10 coins
inc coinStackTens
mov a, coinStackTens
cjne a, #10d, howManyHearts ; if your tens digit isnt outta range continue with the calculation of the number of hearts
inc coinStackHundreds; if it is outta range do correct that
mov coinStackTens, #0
jmp howManyHearts;
add100Coins: inc coinStackHundreds; here the digit can not possibly have an invalid value...
jmp howManyHearts
add200Coins: mov a, coinStackHundreds
add a, #2
mov coinStackHundreds, a
jmp howManyHearts ; also here no invalid values possible
add300Coins: mov a, coinStackHundreds
add a, #3
mov coinStackHundreds, a
jmp howManyHearts ; same again
add777Coins: mov r0, #coinStackOnes
mov r2, #3
add7: mov a, r0
mov r1, a
mov a, @r0
add a, #7
mov b, a; b contains the possibly invalid version of the ones digit
da a; if you have an invalid value its lower nibble gets corrected this way
anl a, 0x0f; and the higher one gets corrected this way
xch a,b; a and b must be swapped in order to make subb work ie b contains now the corrected value and a has the maybe faulty value
subb a,b; returns zero if all the corrections had no effect therefor the next digit can be increased by 7
jz nextDigit
inc r1
inc @r1
nextDigit: inc r0
djnz r2, add7;
howManyHearts: mov numOfHeartsReceived, coinStackHundreds
loop_forever: sjmp loop_forever
END
Are we allowed to input the coin count as a float from 0 to 0.99? I'd guess not, but asking just in case. – Grimmy – 2019-08-20T16:25:41.357
1@Grimy No, only an integer (or a string representing this integer). Sorry for the late answer. – Arnauld – 2019-08-20T19:05:13.840