Skip to content

Commit f3a7578

Browse files
committed
parse sum or product
1 parent adcc850 commit f3a7578

File tree

5 files changed

+74
-19
lines changed

5 files changed

+74
-19
lines changed
Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
package io.polypen;
22

3+
import io.polypen.Parser.SignedString;
4+
35
import java.util.List;
46

57
public class Expressions {
6-
public sealed interface Expression permits Product {
8+
public sealed interface Expression permits Product, Sum {
79
String eval();
810
}
911

10-
public record Product(List<String> factors) implements Expression {
12+
public record Product(List<SignedString> factors) implements Expression {
1113
@Override
1214
public String eval() {
13-
List<Polynomial> polynomials = factors.stream().map(Polynomial::parse).toList();
15+
List<Polynomial> polynomials = factors.stream().map(SignedString::token).map(Polynomial::parse).toList();
1416
Polynomial result = Polynomial.ONE;
1517
for (Polynomial p : polynomials) {
1618
result = result.multiply(p);
1719
}
1820
return result.toString();
1921
}
2022
}
23+
24+
public record Sum(List<SignedString> factors) implements Expression {
25+
@Override
26+
public String eval() {
27+
List<Polynomial> polynomials = factors.stream().map(Polynomial::parse).toList();
28+
Polynomial result = Polynomial.ZERO;
29+
for (Polynomial p : polynomials) {
30+
result = result.add(p);
31+
}
32+
return result.toString();
33+
}
34+
}
2135
}

src/main/java/io/polypen/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public static void main(String[] args) {
1313
String line = in.nextLine();
1414
sb.append(line);
1515
}
16-
Expression expression = Parser.parseProduct(sb.toString());
16+
Expression expression = Parser.parse(sb.toString());
1717
System.out.println(expression.eval());
1818
}
1919
}

src/main/java/io/polypen/Parser.java

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.polypen.Expressions.Expression;
44
import io.polypen.Expressions.Product;
5+
import io.polypen.Expressions.Sum;
56
import org.apache.commons.numbers.fraction.Fraction;
67

78
import java.util.ArrayList;
@@ -12,9 +13,9 @@
1213
final class Parser {
1314

1415
static List<Fraction> parsePolynomial(String s) {
15-
List<SignedToken> strings = split(s.trim());
16+
List<SignedString> strings = split(s.trim());
1617
TreeMap<Integer, Fraction> cof = new TreeMap<>();
17-
for (SignedToken term : strings) {
18+
for (SignedString term : strings) {
1819
String[] tokens = term.token.split("[a-z]", 3);
1920
String coefficient = tokens[0].replace("*", "").trim();
2021
if (coefficient.isEmpty()) {
@@ -45,24 +46,44 @@ static List<Fraction> parsePolynomial(String s) {
4546
return result;
4647
}
4748

48-
static Expression parseProduct(String s) {
49-
List<String> result = new ArrayList<>();
49+
static Expression parse(String s) {
50+
List<SignedString> result = new ArrayList<>();
5051
StringBuilder sb = new StringBuilder();
5152
int nestingLevel = -1;
53+
Type outerop = Type.PRODUCT;
54+
Sign sign = Sign.PLUS;
5255
for (int i = 0; i < s.length(); i++) {
5356
char c = s.charAt(i);
5457
switch (c) {
5558
case '(' -> nestingLevel = Math.max(0, nestingLevel) + 1;
5659
case ')' -> {
5760
nestingLevel--;
5861
if (!sb.isEmpty() && nestingLevel == 0) {
59-
result.add(sb.toString());
62+
result.add(new SignedString(sign, sb.toString()));
6063
sb.setLength(0);
64+
sign = Sign.PLUS;
6165
}
6266
if (nestingLevel < 0) {
6367
throw new IllegalStateException("Illegal nesting");
6468
}
6569
}
70+
case '-' -> {
71+
if (nestingLevel == 0) {
72+
outerop = Type.SUM;
73+
}
74+
if (nestingLevel != 0) {
75+
sb.append(c);
76+
}
77+
sign = Sign.MINUS;
78+
}
79+
case '+' -> {
80+
if (nestingLevel == 0) {
81+
outerop = Type.SUM;
82+
}
83+
if (nestingLevel != 0) {
84+
sb.append(c);
85+
}
86+
}
6687
default -> {
6788
if (nestingLevel != 0) {
6889
sb.append(c);
@@ -74,9 +95,12 @@ static Expression parseProduct(String s) {
7495
throw new IllegalStateException("Illegal nesting");
7596
}
7697
if (!sb.isEmpty()) {
77-
result.add(sb.toString());
98+
result.add(new SignedString(sign, sb.toString()));
7899
}
79-
return new Product(result);
100+
return switch (outerop) {
101+
case PRODUCT -> new Product(result);
102+
case SUM -> new Sum(result);
103+
};
80104
}
81105

82106
static Type outerop(String s) {
@@ -119,26 +143,26 @@ enum Sign {
119143
}
120144
}
121145

122-
record SignedToken(Sign sign, String token) {
146+
public record SignedString(Sign sign, String token) {
123147
}
124148

125-
private static List<SignedToken> split(String s) {
126-
List<SignedToken> result = new ArrayList<>();
149+
private static List<SignedString> split(String s) {
150+
List<SignedString> result = new ArrayList<>();
127151
Sign sign = Sign.PLUS;
128152
int pos = -1;
129153
for (int i = 0; i < s.length(); i++) {
130154
if (s.charAt(i) == '-') {
131-
result.add(new SignedToken(sign, s.substring(pos + 1, i).trim()));
155+
result.add(new SignedString(sign, s.substring(pos + 1, i).trim()));
132156
sign = Sign.MINUS;
133157
pos = i;
134158
} else if (s.charAt(i) == '+') {
135-
result.add(new SignedToken(sign, s.substring(pos + 1, i).trim()));
159+
result.add(new SignedString(sign, s.substring(pos + 1, i).trim()));
136160
sign = Sign.PLUS;
137161
pos = i;
138162
}
139163
}
140164
if (pos < s.length() - 1) {
141-
result.add(new SignedToken(sign, s.substring(pos + 1).trim()));
165+
result.add(new SignedString(sign, s.substring(pos + 1).trim()));
142166
}
143167
return result;
144168
}

src/main/java/io/polypen/Polynomial.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.polypen;
22

3+
import io.polypen.Parser.SignedString;
34
import org.apache.commons.numbers.fraction.Fraction;
45

56
import java.util.ArrayList;
@@ -22,6 +23,14 @@ public static Polynomial parse(String s) {
2223
return new Polynomial(Parser.parsePolynomial(s));
2324
}
2425

26+
public static Polynomial parse(SignedString s) {
27+
Polynomial p = parse(s.token());
28+
return switch (s.sign()) {
29+
case PLUS -> p;
30+
case MINUS -> p.multiply(-1);
31+
};
32+
}
33+
2534
public Polynomial add(Polynomial other) {
2635
int degree = Math.max(degree(), other.degree());
2736
List<Fraction> r = new ArrayList<>(degree + 1);
@@ -45,6 +54,14 @@ public Polynomial multiply(Polynomial other) {
4554
return result;
4655
}
4756

57+
public Polynomial multiply(int factor) {
58+
ArrayList<Fraction> newCoefficients = new ArrayList<>();
59+
for (Fraction coefficient : coefficients) {
60+
newCoefficients.add(coefficient.multiply(factor));
61+
}
62+
return new Polynomial(newCoefficients);
63+
}
64+
4865
public Polynomial multiply(String s) {
4966
return multiply(parse(s));
5067
}

src/test/java/io/polypen/PolynomialTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ void monomialMultiplication() {
4141

4242
@Test
4343
void parseProduct() {
44-
Expression expression = Parser.parseProduct("(a + 1) * (a - 1)");
44+
Expression expression = Parser.parse("(a + 1) * (a - 1)");
4545
assertInstanceOf(Expressions.Product.class, expression);
4646
Expressions.Product product = (Expressions.Product) expression;
47-
assertEquals(List.of("a + 1", "a - 1"), product.factors());
47+
assertEquals(List.of("a + 1", "a - 1"), product.factors().stream().map(Parser.SignedString::token).toList());
4848
}
4949
}

0 commit comments

Comments
 (0)