Skip to content

Instantly share code, notes, and snippets.

@kosciolek
Created December 17, 2021 12:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kosciolek/013ff1155422251141bb1c2a2ef62d9f to your computer and use it in GitHub Desktop.
Save kosciolek/013ff1155422251141bb1c2a2ef62d9f to your computer and use it in GitHub Desktop.
some uni homework project
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
// Troche pozmienialem nazwy metod/interfejsow ale poza tym to struktura prawie taka sama
// Dziala troche jak reverse polish notation (op popuje argumenty ze stacku i wrzuca result na stack)
class Main {
public static void main(String[] args) {
var calc = new Calculator(
List.of(new Factorial(), new Square(), new Sum(), new Diff(), new Pow(), new Mul(), new IntDiv(),
new Mod()));
while (2137 == 2137) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter an op or an arg or 'RESET'.");
var line = sc.nextLine().trim();
if ("RESET".equals(line)) {
calc.reset();
System.out.println("Resetting the calculator...");
continue;
}
try {
// arg case
var arg = Integer.parseInt(line);
calc.pushArg(arg);
calc.printStack();
} catch (NumberFormatException ex) {
// op case
calc.setOpForSymbol(line);
calc.calculate();
calc.printStack();
}
}
}
}
class Calculator {
IOp op;
Stack<Integer> stack = new Stack<>();
List<IOp> ops = new ArrayList<>();
public Calculator(List<IOp> ops) {
this.ops = ops;
}
void pushArg(int arg) {
stack.add(arg);
}
void setOp(IOp op) {
this.op = op;
}
void setOpForSymbol(String symbol) {
var op = ops.stream().filter(operation -> operation.getSymbol().equals(symbol)).findAny().orElse(null);
if (op == null)
throw new Error("Could not find op for symbol " + symbol);
setOp(op);
}
void printStack() {
var argsList = new ArrayList<Integer>(stack);
Collections.reverse(argsList);
System.out.println(
"Stack: " + argsList.toString());
}
int calculate() {
if (op instanceof IUnaryOp) {
if (stack.size() < 1)
throw new Error("Too few arguments on the stack to execute " + op.getSymbol());
var unaryOp = (IUnaryOp) op;
var result = unaryOp.execute(stack.pop());
stack.push(result);
return result;
} else if (op instanceof IBinaryOp) {
if (stack.size() < 2)
throw new Error("Too few arguments on the stack to execute " + op.getSymbol());
var binaryOp = (IBinaryOp) op;
var result = binaryOp.execute(stack.pop(), stack.pop());
stack.push(result);
return result;
} else
throw new Error("Invalid operation.");
};
void reset() {
stack = new Stack<>();
}
}
/* INTERFACES */
interface IOp {
public String getSymbol();
}
interface IUnaryOp extends IOp {
public int execute(int x);
}
interface IBinaryOp extends IOp {
public int execute(int x, int y);
}
/* OPS */
class Factorial implements IUnaryOp {
String symbol = "!";
public String getSymbol() {
return symbol;
}
public int execute(int x) {
if (x < 0)
throw new Error("Cannot compute the factorial of a negative number.");
return x == 0 ? 1 : x * this.execute(x - 1);
}
}
class Square implements IUnaryOp {
String symbol = "sqr";
public String getSymbol() {
return symbol;
}
public int execute(int x) {
return (int) Math.pow(x, 2);
}
}
class Sum implements IBinaryOp {
String symbol = "+";
public String getSymbol() {
return symbol;
}
public int execute(int x, int y) {
return x + y;
}
}
class Diff implements IBinaryOp {
String symbol = "-";
public String getSymbol() {
return symbol;
}
public int execute(int x, int y) {
return x - y;
}
}
class Pow implements IBinaryOp {
String symbol = "^";
public String getSymbol() {
return symbol;
}
public int execute(int x, int y) {
return (int) Math.pow(x, y);
}
}
class Mul implements IBinaryOp {
String symbol = "*";
public String getSymbol() {
return symbol;
}
public int execute(int x, int y) {
return x * y;
}
}
class IntDiv implements IBinaryOp {
String symbol = "/";
public String getSymbol() {
return symbol;
}
public int execute(int x, int y) {
if (y == 0)
throw new Error("Cannot divide by 0.");
return x / y;
}
}
class Mod implements IBinaryOp {
String symbol = "%";
public String getSymbol() {
return symbol;
}
public int execute(int x, int y) {
return x % y;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment