Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 61 additions & 7 deletions src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ public class Atm {
public enum Denomination {
D50(50),
D100(100),
D200(200),
D500(500),
D1000(1000),
D2000(2000),
D5000(5000);

private final int value;
Expand All @@ -16,12 +18,13 @@ public enum Denomination {
this.value = value;
}

int value() {
public int value() {
return value;
}

public static Denomination fromInt(int value) {
return Arrays.stream(values()).filter(v -> v.value == value)
return Arrays.stream(values())
.filter(v -> v.value == value)
.findFirst()
.orElse(null);
}
Expand All @@ -32,14 +35,65 @@ public static Denomination fromInt(int value) {
public Atm() {
}

public void deposit(Map<Denomination, Integer> banknotes){}
public void deposit(Map<Denomination, Integer> banknotes) {
for (Map.Entry<Denomination, Integer> entry : banknotes.entrySet()) {
Denomination denom = entry.getKey();
Integer count = entry.getValue();
if (denom == null || count == null || count <= 0) {
throw new InvalidDepositException("Invalid denomination or count");
}
}
for (Map.Entry<Denomination, Integer> entry : banknotes.entrySet()) {
Denomination denom = entry.getKey();
int count = entry.getValue();
this.banknotes.put(denom, this.banknotes.getOrDefault(denom, 0) + count);
}
}

public Map<Denomination, Integer> withdraw(int amount) {
return Map.of();
if (amount <= 0) {
throw new InvalidAmountException("Amount must be positive: " + amount);
}
if (amount > getBalance()) {
throw new InsufficientFundsException("Insufficient funds");
}

List<Denomination> sorted = new ArrayList<>(EnumSet.allOf(Denomination.class));
sorted.sort((a, b) -> Integer.compare(b.value(), a.value()));

Map<Denomination, Integer> result = new EnumMap<>(Denomination.class);
int remaining = amount;

for (Denomination denom : sorted) {
int available = banknotes.getOrDefault(denom, 0);
int need = remaining / denom.value();
int take = Math.min(need, available);
if (take > 0) {
result.put(denom, take);
remaining -= take * denom.value();
}
}

if (remaining != 0) {
throw new CannotDispenseException("Cannot dispense exact amount");
}

for (Map.Entry<Denomination, Integer> entry : result.entrySet()) {
Denomination denom = entry.getKey();
int newCount = banknotes.get(denom) - entry.getValue();
if (newCount == 0) {
banknotes.remove(denom);
} else {
banknotes.put(denom, newCount);
}
}

return result;
}

public int getBalance() {
return 0;
return banknotes.entrySet().stream()
.mapToInt(e -> e.getKey().value() * e.getValue())
.sum();
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.Set;

public class HtmlDocument {
private static final Set<String> ALLOWED_TAGS = Set.of("html", "head", "body", "div", "p");

public HtmlDocument(String filePath) {
this(Path.of(filePath));
Expand All @@ -27,6 +28,83 @@ private String readFile(Path filePath) {
}
}

private void validate(String content){}
private void validate(String content) {
Deque<String> stack = new ArrayDeque<>();
boolean hasHtml = false;
boolean hasHead = false;
boolean hasBody = false;

}
int i = 0;
int n = content.length();

while (i < n) {
int open = content.indexOf('<', i);
if (open == -1) break;

int close = content.indexOf('>', open);
if (close == -1) {
throw new RuntimeException("Malformed HTML: missing '>'");
}

String tagContent = content.substring(open + 1, close);
boolean isClosing = tagContent.startsWith("/");
String tagName;

if (isClosing) {
tagName = tagContent.substring(1).trim().split("\\s+")[0].toLowerCase();
} else {
tagName = tagContent.trim().split("\\s+")[0].toLowerCase();
if (tagName.endsWith("/")) {
tagName = tagName.substring(0, tagName.length() - 1);
}
}

if (!ALLOWED_TAGS.contains(tagName)) {
throw new UnsupportedTagException("Unsupported tag: " + tagName);
}

if (isClosing) {
if (stack.isEmpty()) {
throw new UnexpectedClosingTagException("Unexpected closing tag: </" + tagName + ">");
}
String top = stack.pop();
if (!top.equals(tagName)) {
throw new MismatchedClosingTagException("Expected </" + top + ">, but got </" + tagName + ">");
}
if (tagName.equals("html")) {
hasHtml = true;
}
} else {
if (tagName.equals("html")) {
if (hasHtml) {
throw new InvalidStructureException("Multiple <html> tags");
}
hasHtml = true;
} else if (tagName.equals("head")) {
if (hasHead) {
throw new InvalidStructureException("Multiple <head> tags");
}
if (hasBody) {
throw new InvalidStructureException("<head> after <body>");
}
hasHead = true;
} else if (tagName.equals("body")) {
if (hasBody) {
throw new InvalidStructureException("Multiple <body> tags");
}
hasBody = true;
}
stack.push(tagName);
}

i = close + 1;
}

if (!stack.isEmpty()) {
throw new UnclosedTagException("Unclosed tags: " + stack);
}
if (!hasHtml) {
throw new InvalidStructureException("No <html> root tag");
}
}
}
Loading