First up, clone this git repo to your local environment
git clone https://github.com/pete-hotchkiss/cash-machine
Point your command line to the root folder you've cloned the git repos into and ensure all the npm dependencies are installed
npm install
Install all the bower dependencies
bower install
The app was built under TDD methodologies using Karma/Jasmine. TO view the tests at the command line enter
karma start tests/karma.conf.js --single-run
The app runs on a temporary local server via gulp. To start the app enter
gulp serve
This will run the default configuration of the app. If you want to switch out the algorithm to control how the cash machine prioritises how it returns the transaction then you should use an additional --withdrawal
flag
By default the application assumes you'd like it to run in 'least' mode - that is the transaction uses the smallest possible number of coins/notes. However, to return the most possible £20 notes spin up the server using
gulp serve -w denomination
This argument will only accept two values at present either least or denomination. The server start will fail if you try and pass an invalid argument
Additionally, if you want to override the value of the priority denomination ( which defaults to £20 ) then you can pass an additional --value
argument along with your desired denomination value. Note: The value must be one of the denominations available and be passed in single units - i.e. £10 = 1000. The cli will warn you if you try and pass an invalid value HandheldFriendly
gulp serve -w denomination --value 1000 // Will prioritise £10 notes in the resulting withdrawal
The application UI provides an additional toggle between these two states, enabling the user to switch between the modes at run time.
The starting state of the float is defined in a JSON
file found in ./app/data/float.json
. This contains details of all the possible denominations of currency including their type - i.e. coin or note. The "denomination" values should not be changed ( note all these are stored in single units so 1p = 1 and £1 = 100) but the amount value can be adjusted as desired
The algorithm's used internally within this application are distinctly different but intrinsically linked within their execution.
- When running in
least
mode the application is solving what is effectively a Knapsack Problem more commonly known as the Change Making Problem, and computationally similar to calculating ways a 9 dart finish could be completed in darts. Mathematically there are a number of approaches to tackle this, each of which vary in how intensive the process would be.
In this instance out float is made up of denominations that fall into a canonical currency system, meaning we can use a greedy method to calculate our transaction. The algorithm continually picks the largest denomination available (n
) reducing the target amount accordingly; and continues to do so until such a point that either all available instances of that denomination have been depleted or n > a
. In either instance it simply steps down to the next smallest denomination n-1
and repeats.
However, should the denomination system within the currency have arbitrary values it could result in this greedy approach returning no optimised results.
eg A system with coins/notes holding the values 1, 3, 4 attempting to withdraw 6 under the greedy method would return [ 4, 1, 1 ] for a total of 3 coins. However the optimal result would be [ 3, 3 ] or 2 coins
In instances where the application needs to support arbitrary currency systems then the ability to switch out the algorithm for a more intensive bottom-up dynamic approach would be required.
- The alternative
denomination
mode, where in the application will heavily favour a given denomination (m
) does run on the same greedy system as detailed above, however rather than starting with the largest possible denomination (n
) it begins the calculation loop with the denomination (m
) using as many instances of this denomination that the float will allow.