Skip to content

Commit e1c062c

Browse files
committed
Atm task: remove one solution, keep only which used loop. Remove extra classes & interface
1 parent edb51ef commit e1c062c

8 files changed

Lines changed: 93 additions & 195 deletions

File tree

src/main/java/by/andd3dfx/common/atm/AbstractAtm.java

Lines changed: 0 additions & 53 deletions
This file was deleted.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package by.andd3dfx.common.atm;
2+
3+
import java.util.Comparator;
4+
import java.util.HashMap;
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
/**
9+
* <pre>
10+
* Есть банкомат (ATM), который заряжают купюрами.
11+
* Надо реализовать метод withdraw() для выдачи заданной суммы amount имеющимися в банкомате купюрами.
12+
* Метод withdraw() - мутирующий, т.е. меняет состояние банкомата после вызова (кол-во купюр может уменьшиться):
13+
* Map<Integer, Integer> withdraw(int amount)
14+
* </pre>
15+
*
16+
* @see <a href="https://youtu.be/LDKZtDevRRI">Video solution 1</a> and <a href="https://youtu.be/0-BL-NO9-B8">Video solution 2</a>
17+
*/
18+
public class Atm {
19+
20+
private Map<Integer, Integer> state;
21+
private List<Integer> nominals;
22+
23+
public Atm(Map<Integer, Integer> state) {
24+
this.state = new HashMap<>(state);
25+
this.nominals = state.keySet().stream()
26+
.sorted(Comparator.reverseOrder()).toList();
27+
}
28+
29+
/**
30+
* Withdraw asked amount using banknotes of ATM
31+
*
32+
* @param amount sum asked to withdraw
33+
* @return map with solution - pairs {banknote nominal->quantity}
34+
*/
35+
public Map<Integer, Integer> withdraw(int amount) {
36+
// Try to make withdraw using banknote of highest nominal,
37+
// in case of fail - try to start from next nominal
38+
for (int i = 0; i < nominals.size(); i++) {
39+
try {
40+
return withdraw(amount, i);
41+
} catch (IllegalStateException ex) {
42+
// do nothing
43+
}
44+
}
45+
46+
throw new IllegalStateException("Could not perform withdraw!");
47+
}
48+
49+
private Map<Integer, Integer> withdraw(int amount, int nominalIndex) {
50+
var result = new HashMap<Integer, Integer>();
51+
52+
for (var index = nominalIndex; index < nominals.size(); index++) {
53+
var nominal = nominals.get(index);
54+
if (nominal > amount || state.get(nominal) == 0) {
55+
continue;
56+
}
57+
58+
int count = amount / nominal;
59+
count = Math.min(count, state.get(nominal));
60+
result.put(nominal, count);
61+
amount -= nominal * count;
62+
63+
if (amount == 0) {
64+
break;
65+
}
66+
}
67+
68+
if (amount > 0) {
69+
throw new IllegalStateException("Could not perform withdraw!");
70+
}
71+
72+
mutateAtm(result);
73+
return result;
74+
}
75+
76+
private void mutateAtm(Map<Integer, Integer> result) {
77+
for (var nominal : result.keySet()) {
78+
state.put(nominal, state.get(nominal) - result.get(nominal));
79+
}
80+
}
81+
}

src/main/java/by/andd3dfx/common/atm/AtmUsingLoop.java

Lines changed: 0 additions & 48 deletions
This file was deleted.

src/main/java/by/andd3dfx/common/atm/AtmUsingRecursion.java

Lines changed: 0 additions & 49 deletions
This file was deleted.

src/main/java/by/andd3dfx/common/atm/IAtm.java

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/test/java/by/andd3dfx/common/atm/AbstractAtmTest.java renamed to src/test/java/by/andd3dfx/common/atm/AtmTest.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
import static org.assertj.core.api.Assertions.assertThat;
1010
import static org.junit.Assert.assertThrows;
1111

12-
public abstract class AbstractAtmTest {
12+
public class AtmTest {
1313

14-
private IAtm atm;
15-
private IAtm atm2;
14+
private Atm atm;
15+
16+
protected Atm buildAtm(Map<Integer, Integer> state) {
17+
return new Atm(state);
18+
}
1619

1720
@Before
1821
public void setUp() throws Exception {
@@ -21,14 +24,8 @@ public void setUp() throws Exception {
2124
200, 3,
2225
50, 5
2326
));
24-
atm2 = buildAtm(Map.of(
25-
500, 3,
26-
200, 5
27-
));
2827
}
2928

30-
protected abstract IAtm buildAtm(Map<Integer, Integer> state);
31-
3229
@Test
3330
public void withdrawFor0() {
3431
var result = atm.withdraw(0);
@@ -88,7 +85,13 @@ public void withdrawForConsequentCalls() {
8885
@Ignore
8986
@Test
9087
public void withdraw_vsGreedyAlgorithm() {
88+
var atm2 = buildAtm(Map.of(
89+
500, 3,
90+
200, 5
91+
));
92+
9193
var result = atm2.withdraw(1100);
94+
9295
assertThat(result).isEqualTo(Map.of(
9396
500, 1,
9497
200, 3

src/test/java/by/andd3dfx/common/atm/AtmUsingLoopTest.java

Lines changed: 0 additions & 11 deletions
This file was deleted.

src/test/java/by/andd3dfx/common/atm/AtmUsingRecursionTest.java

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)