using System.Collections.Generic;
private Dictionary<int, int> _amounts;
public AtmMachine(Dictionary<int, int> amounts)
public List<Tuple<int, int>> Withdraw(int amount)
Dictionary < int, int > resultsMap = new Dictionary < int, int > {};
for (int i = 0; i < _amounts.Count; ++i) {
moneyAvailable += _amounts.ElementAt(i).Key * _amounts[_amounts.ElementAt(i).Key];
if (moneyAvailable >= amount && amount > 0) {
for (int i = _amounts.Count() - 1; i >= 0;) {
if (_amounts.ElementAt(i).Key <= amount) {
if (resultsMap.ContainsKey(_amounts.ElementAt(i).Key)) {
resultsMap[_amounts.ElementAt(i).Key]++;
resultsMap.Add(_amounts.ElementAt(i).Key, 1);
amount -= _amounts.ElementAt(i).Key;
_amounts[_amounts.ElementAt(i).Key]--;
if (_amounts[_amounts.ElementAt(i).Key] == 0) {
_amounts.Remove(_amounts[_amounts.ElementAt(i).Key]);
List < Tuple < int, int >> list = new List < Tuple < int, int >> {};
for (int i = 0; i < resultsMap.Count; ++i) {
list.Add(new Tuple < int, int > (resultsMap.ElementAt(i).Key,
resultsMap[resultsMap.ElementAt(i).Key]));
public class VersionComparer
public int Compare(string versionOne, string versionTwo)
List < int > version1 = new List < int > {};
List < int > version2 = new List < int > {};
List < int > templist = new List < int > {};
string[] words1 = versionOne.Split(".");
for (int i = 0; i < words1.Count(); ++i) {
int temp = Int32.Parse(words1[i]);
if (temp == 0) templist.Add(0);
version1.AddRange(templist);
string[] words2 = versionTwo.Split(".");
for (int i = 0; i < words2.Count(); ++i) {
int temp = Int32.Parse(words2[i]);
if (temp == 0) templist.Add(0);
version2.AddRange(templist);
while (version1.Count < version2.Count) {
while (version2.Count < version1.Count) {
for (int i = 0; i < version1.Count; ++i) {
for (int i = 0; i < version1.Count; ++i) {
for (int i = 0; i < version1.Count; ++i) {
if (version1[i] < version2[i]) {
if (version1[i] > version2[i]) {
public static void Main()
private static void Run()
new AtmMachineTests().Start();
new VersionComparerTests().Start();
public class AtmMachineTests
Tests.Run($"{nameof(AtmMachine)} should", (it) =>
it.Should(() => NotProcessNegativeValues(), "Not process negative values");
it.Should(() => ReturnMultipleDenominationAmounts(), "Return multiple denomination amounts");
it.Should(() => NotProcessWithdrawalsWhenInventoryIsSmallerThanRequestedAmount(), "Not process witdrawals greater than inventory");
it.Should(() => ReturnAllAvailableMoney(), "Return all available money");
it.Should(() => KeepStateBetweenWithdrawals(), "Keep state between withdrawals");
it.Should(() => NotChangeStateIfWithdrawalIsntSuccessful(), "Not change state if withdrawal isn't successful");
private int CountMoney(List<Tuple<int, int>> amounts) => amounts.Aggregate(0, (a, i) => a + i.Item1 * i.Item2);
public void NotChangeStateIfWithdrawalIsntSuccessful()
var atm = new AtmMachine(new Dictionary<int, int> { { 1, 5 }, { 5, 5 }, { 10, 5 } });
var r1 = atm.Withdraw(50);
CountMoney(r1).ShouldBe(50);
var r2 = atm.Withdraw(50);
CountMoney(r2).ShouldBe(0);
var r3 = atm.Withdraw(20);
CountMoney(r3).ShouldBe(20);
public void NotProcessNegativeValues()
var atm = new AtmMachine(new Dictionary<int, int> { { 1, 5 } });
var result = atm.Withdraw(-5);
CountMoney(result).ShouldBe(0);
public void KeepStateBetweenWithdrawals()
var atm = new AtmMachine(new Dictionary<int, int> { { 1, 5 }, { 5, 5 } });
var r1 = atm.Withdraw(5);
CountMoney(r1).ShouldBe(5);
var r2 = atm.Withdraw(26);
CountMoney(r2).ShouldBe(0);
public void ReturnAllAvailableMoney()
var atm = new AtmMachine(new Dictionary<int, int> { { 1, 10 }, { 5, 10 }, { 10, 10 }, { 50, 10 }, { 100, 10 }, { 200, 10 }, { 500, 10 } });
var result = atm.Withdraw(8660);
var sum = CountMoney(result);
public void ReturnMultipleDenominationAmounts()
var atm = new AtmMachine(new Dictionary<int, int> { { 1, 10 }, { 5, 10 }, { 10, 10 } });
var result = atm.Withdraw(87);
CountMoney(result).ShouldBe(87);
public void NotProcessWithdrawalsWhenInventoryIsSmallerThanRequestedAmount()
var atm = new AtmMachine(new Dictionary<int, int> { { 1, 10 }, { 5, 10 }, { 10, 10 }, { 50, 10 }, { 100, 10 }, { 200, 10 }, { 500, 10 } });
var result = atm.Withdraw(8661);
CountMoney(result).ShouldBe(0);
public class VersionComparerTests
Tests.Run("VersionComparer should", (it) =>
it.Should(() => CompareEqualVersions(), "Compare equal versions");
it.Should(() => CompareDifferentVersions(), "Compare different versions");
public void CompareEqualVersions()
var comparer = new VersionComparer();
comparer.Compare("0", "0.0.0").ShouldBe(0);
comparer.Compare("0.01", "0.1").ShouldBe(0);
comparer.Compare("1.001", "1.1").ShouldBe(0);
comparer.Compare("7.015.84", "7.15.84").ShouldBe(0);
comparer.Compare("7.1", "7.1.0.0").ShouldBe(0);
public void CompareDifferentVersions()
var comparer = new VersionComparer();
comparer.Compare("01.0.1", "1.1.0").ShouldBe(-1);
comparer.Compare("33.1", "33.0.5").ShouldBe(1);
comparer.Compare("7.0105.84", "7.15.84").ShouldBe(-1);
public static void Run(string testGroup, Action<Tests> tests)
public static void StartTests(string testGroup)
Console.WriteLine("====================================================");
Console.WriteLine(testGroup);
Console.WriteLine("====================================================");
public void Should(Action test, string testName)
Console.WriteLine(testName);
Console.WriteLine(" Passed");
Console.WriteLine(" Failed");
Console.WriteLine(" " + e.Message);
public static void EndTests()