From b9dbfb86ad1425b2ed4f65d9dc949f65caa513f8 Mon Sep 17 00:00:00 2001 From: Gleb Koval Date: Tue, 5 Nov 2024 17:05:23 +0000 Subject: [PATCH] Implement ReversePolishStack.evaluate() on current stack with push-back. Co-Authored-By: td1223 --- src/main/java/ic/doc/ReversePolishStack.java | 25 +++++++++++++++ .../java/ic/doc/ReversePolishStackTest.java | 31 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/main/java/ic/doc/ReversePolishStack.java b/src/main/java/ic/doc/ReversePolishStack.java index ff6f0f9..b74c5e1 100644 --- a/src/main/java/ic/doc/ReversePolishStack.java +++ b/src/main/java/ic/doc/ReversePolishStack.java @@ -12,4 +12,29 @@ public class ReversePolishStack { public void push(IntOperator intOperator) { stack.push(intOperator); } + + private int evaluateNext() { + if (stack.isEmpty()) { + throw new ArithmeticException("No operators to evaluate"); + } + + IntOperator intOperator = stack.pop(); + Stack args = new Stack<>(); + while (args.size() < intOperator.getOperands()) { + if (stack.isEmpty()) { + throw new ArithmeticException("Not enough arguments to evaluate operator"); + } + args.push(evaluateNext()); + } + return intOperator.evaluate(args); + } + + public int evaluate() { + int result = evaluateNext(); + if (!stack.isEmpty()) { + throw new ArithmeticException("Invalid notation, too many operators"); + } + stack.push(new IntOperator(0, args -> result)); + return result; + } } diff --git a/src/test/java/ic/doc/ReversePolishStackTest.java b/src/test/java/ic/doc/ReversePolishStackTest.java index ba2bca0..562e46e 100644 --- a/src/test/java/ic/doc/ReversePolishStackTest.java +++ b/src/test/java/ic/doc/ReversePolishStackTest.java @@ -4,6 +4,7 @@ import org.junit.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.Assert.fail; public class ReversePolishStackTest { final ReversePolishStack reversePolishStack = new ReversePolishStack(); @@ -20,4 +21,34 @@ public class ReversePolishStackTest { reversePolishStack.push(new IntOperator(0, args -> 2)); assertThat(reversePolishStack.getSize(), is(2)); } + + @Test + public void canEvaluateReversePolishStack() { + reversePolishStack.push(new IntOperator(0, args -> 10)); + reversePolishStack.push(new IntOperator(0, args -> 25)); + reversePolishStack.push(new IntOperator(2, args -> args.get(0) + args.get(1))); + assertThat(reversePolishStack.evaluate(), is(35)); + } + + @Test + public void evaluatePushesBack() { + reversePolishStack.push(new IntOperator(0, args -> 10)); + reversePolishStack.push(new IntOperator(0, args -> 25)); + reversePolishStack.push(new IntOperator(2, args -> args.get(0) + args.get(1))); + reversePolishStack.evaluate(); + assertThat(reversePolishStack.getSize(), is(1)); + assertThat(reversePolishStack.evaluate(), is(35)); + } + + @Test + public void evaluateThrowsOnInvalidNotation() { + reversePolishStack.push(new IntOperator(0, args -> 10)); + reversePolishStack.push(new IntOperator(0, args -> 25)); + try { + reversePolishStack.evaluate(); + fail("Expected ArithmeticException to be thrown when too many operators"); + } catch (ArithmeticException e) { + // good + } + } }