diff --git a/commander/src/main/java/module-info.java b/commander/src/main/java/module-info.java index 0a750cc2..dffe95c9 100644 --- a/commander/src/main/java/module-info.java +++ b/commander/src/main/java/module-info.java @@ -1,6 +1,7 @@ module hse.java.commander { requires javafx.controls; requires javafx.fxml; + requires static lombok; opens hse.java.commander to javafx.fxml; exports hse.java.commander; diff --git a/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java b/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java index 08f551e4..e6e5b1c6 100644 --- a/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java +++ b/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java @@ -32,14 +32,68 @@ public static Denomination fromInt(int value) { public Atm() { } - public void deposit(Map banknotes){} + public void deposit(Map banknotes) { + if (banknotes == null || banknotes.isEmpty()) { + throw new InvalidDepositException("Deposit is empty"); + } + + for (Map.Entry entry : banknotes.entrySet()) { + if (entry.getKey() == null) { + throw new InvalidDepositException("Invalid denomination"); + } + if (entry.getValue() == null || entry.getValue() <= 0) { + throw new InvalidDepositException("Invalid banknote count: " + entry.getValue()); + } + } + + for (Map.Entry entry : banknotes.entrySet()) { + this.banknotes.merge(entry.getKey(), entry.getValue(), Integer::sum); + } + } public Map withdraw(int amount) { - return Map.of(); + if (amount <= 0) { + throw new InvalidAmountException("Amount must be positive"); + } + int balance = getBalance(); + if (amount > balance) { + throw new InsufficientFundsException("Not enough money in ATM"); + } + + Map temp = new EnumMap<>(banknotes); + Map res = new EnumMap<>(Denomination.class); + + List denoms = new ArrayList<>(Arrays.asList(Denomination.values())); + denoms.sort((a, b) -> Integer.compare(b.value(), a.value())); + + int ost = amount; + + for (Denomination denom : denoms) { + int able = temp.getOrDefault(denom, 0); + int need = ost / denom.value(); + int take = Math.min(able, need); + + if (take > 0) { + res.put(denom, take); + ost -= take * denom.value(); + } + } + if (ost != 0) { + throw new CannotDispenseException("Not able to process"); + } + for (Map.Entry entry : res.entrySet()) { + banknotes.merge(entry.getKey(), -entry.getValue(), Integer::sum); + } + + return res; } public int getBalance() { - return 0; + int sum = 0; + for (Map.Entry entry : banknotes.entrySet()) { + sum += entry.getKey().value() * entry.getValue(); + } + return sum; } } diff --git a/src/main/java/hse/java/lectures/lecture3/tasks/html/HtmlDocument.java b/src/main/java/hse/java/lectures/lecture3/tasks/html/HtmlDocument.java index 1ddf27bf..cb841760 100644 --- a/src/main/java/hse/java/lectures/lecture3/tasks/html/HtmlDocument.java +++ b/src/main/java/hse/java/lectures/lecture3/tasks/html/HtmlDocument.java @@ -9,7 +9,6 @@ import java.util.Set; public class HtmlDocument { - public HtmlDocument(String filePath) { this(Path.of(filePath)); } @@ -27,6 +26,105 @@ private String readFile(Path filePath) { } } - private void validate(String content){} + private void validate(String content) { + Deque stack = new ArrayDeque<>(); + Set tags = Set.of("html", "head", "body", "div", "p"); + boolean opened = false; + boolean closed = false; + boolean head = false; + boolean body = false; + + int i = 0; + while (i < content.length()) { + if (content.charAt(i) == '<') { + int j = content.indexOf('>', i); + if (j == -1) { + throw new RuntimeException(); + } + + String tag = content.substring(i + 1, j).trim(); + + boolean closing_tag = tag.startsWith("/"); + String tag_name; + if (closing_tag) { + tag_name = tag.substring(1).trim().toLowerCase(); + } else { + String[] parts = tag.split("\\s+"); + tag_name = parts[0].toLowerCase(); + } + + if (!tags.contains(tag_name)) { + throw new UnsupportedTagException("Unsupported tag: " + tag_name); + } + + if (closing_tag) { + if (stack.isEmpty()) { + throw new UnexpectedClosingTagException("Unexpected closing tag: " + tag_name); + } + + String expected = stack.pop(); + if (!expected.equals(tag_name)) { + throw new MismatchedClosingTagException("Mismatched closing tag"); + } + + if (tag_name.equals("html")) { + closed = true; + } + + } else { + if (closed) { + throw new InvalidStructureException("Invalid structure"); + } -} + if (tag_name.equals("html")) { + if (opened) { + throw new InvalidStructureException("Invalid structure"); + } + if (!stack.isEmpty()) { + throw new InvalidStructureException("Invalid structure"); + } + opened = true; + } else { + if (!opened) { + throw new InvalidStructureException("Invalid structure"); + } + } + if (tag_name.equals("head") || tag_name.equals("body")) { + if (stack.isEmpty() || !stack.peek().equals("html")) { + throw new InvalidStructureException("Invalid structure"); + } + } + + if (tag_name.equals("head")) { + if (head) { + throw new InvalidStructureException("Invalid structure"); + } + if (body) { + throw new InvalidStructureException("Invalid structure"); + } + head = true; + } + + if (tag_name.equals("body")) { + if (body) { + throw new InvalidStructureException("Invalid structure"); + } + body = true; + } + stack.push(tag_name); + } + i = j + 1; + } else { + i++; + } + } + + if (!stack.isEmpty()) { + throw new UnclosedTagException("Unclosed tags"); + } + + if (!opened || !closed) { + throw new InvalidStructureException("Invalid structure"); + } + } +} \ No newline at end of file