# Shenzhen I/O: Token-Based Payment Kiosk

You are into history or at least history reenactment? That is what this puzzle is about, but apparently we are to make a Token-based payment kiosk…. just like they had in the good old days. Let us not fight over historical details, but let us take a look at this fun problem.

Oh and just a side note, by this time in the game we finally got the gen instruction. So now we can use it without problem.

The overall machine takes in a price as well as three simple inputs signifying three coin types of 1, 5 and 12 in value. We are then going to keep accepting coins until the price is reached. After which we must ring a bell for 4 seconds as well as give back change in 5 and 1 with the least possible coins.

The solution signals for the 16￥problem looks like this

Where we input 2 12 coins and then get back a 5 coin and 3 1 coins.

## Structure of the Token-based Payment Kiosk

I found this a pretty difficult problem to solve, not least due to the shear amount of simple input and outputs. So I have tried to set up a structure with 2 MC6000 micro controllers and then hope that I can fit the programming into those. The structure makes use of the usual dx300 to boil down the coin inputs into an xbus input that can be handled.

The first micro controller is responsible for counting the input, sending the exceeding amount of money to the second micro controller and ringing the bell. The second micro controller is responsible for giving change.

## Coding the solution

The first micro controller is coded as

```st: mov x0 acc
lp: slp 1
mov x1 dat
teq dat 100
+ sub 12
teq dat 10
+ sub 5
teq dat 1
+ sub 1
tgt acc 0
+ jmp lp
mov acc x2
gen p1 4 0
```

The code starts by moving the target amount to the acc, then it runs in a loop where it counts down towards 0. Line 10 checks if we have reached the target amount. If we have, the change needed is the negative amount in acc that we can now send to the second micro controller, ring the bell and start over.

The second micro controller is coded like

```st: slx x1
mov x1 acc

loop: teq acc 0
+ jmp st
tlt acc -4
+ gen p1 1 1
- gen p0 1 1
jmp loop
```

First of all we sleep until we are ready to give change back. Then we keep track of the change we need to give back. In this case we can run it as a greedy algorithm. So if we need to give back more than 5 then we give a 5 coin otherwise give back a 1 coin and loops over it all again. Until we are done giving change.

This was the best I could come up with for a solution that gives a total of
Cost: 11￥
Energy: 481
Lines of code: 23

### Posted by Kristian

tongdd

tongdd

sry, I see the code in your picture is correct, but the copied code in the web page should be modified…

Kristian

Thanks for noticing. It should be fixed now.

Andy

Incredibly, I’ve been able to shave off some energy usage from your version. ‘Incredibly’, because I’m notoriously bad at this stuff.

https://bit.ly/2pIXwtn

I’m having the first chip count up the coin value, so that you don’t have to check each case via ‘teq’ every cycle. Though, I guess, your way may be more efficient, if more higher value coins were spent; my device would have to run through all these ‘tgt’ lines more frequently in that case.

Also, apparently, having two loops to go through for the change saved a bit of energy, too.

Have you tried anything with one of the memory modules for this device? I’ve noticed this was the first puzzle where both of them weren’t marked as ‘not recommended’ anymore.

You can improve this solution a lot by only passing the change to the second chip if change is necessary… saves power, and then you can trim a line of code in the second chip (the first jmp) and move the zero test to make the loop jmp conditional on further change being required. Now you have done the work in 9 lines you can replace the chip with a cheaper one – yay!

Got something similar, but with lower power consumption (yours are 481 and 417, mine is 370).
http://prntscr.com/lxgrik
I guess the main power saving is from not storing the price in a register, but always read from outside when needed to test if enough money (so I’m using just the acc register, while not needed to use the dat register).

Lilja Tamminen

I spent half a day getting down to 9¥, 325 power, 23 lines of code

Implementation here: https://prnt.sc/m78944

Antiarchitect

9¥, 324 power, 21 lines. It was a long journey…
https://imgur.com/a/nWnRrXy

Antiarchitect

9¥, 324 power, 21 lines
https://imgur.com/a/nWnRrXy

Cancodrillo

@Antiarchitect – Change the comand to in your MC6000 and your power usage decreases further. You did a great job !
@Lilja Tamminen – Your solution doesn’t work when there’s no change !

Cancodrillo

@Antiarchitect – My bad. The change is gen p1 4 0 to gen p1 4 1