Skip to content

Commit 90cec73

Browse files
committed
automatic tests
1 parent b15f941 commit 90cec73

File tree

5 files changed

+129
-82
lines changed

5 files changed

+129
-82
lines changed

.github/workflows/gradle.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Java CI with Gradle
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build:
11+
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
- name: Set up JDK
17+
uses: actions/setup-java@v4
18+
with:
19+
distribution: 'temurin'
20+
java-version: 22
21+
cache: 'gradle'
22+
- name: Build with Gradle
23+
run: ./gradlew build
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package io.polypen;
2+
3+
import org.apache.commons.numbers.fraction.Fraction;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
import java.util.Map;
8+
import java.util.TreeMap;
9+
10+
final class Parser {
11+
12+
static List<Fraction> parse(String s) {
13+
List<SignedToken> strings = split(s.trim());
14+
TreeMap<Integer, Fraction> cof = new TreeMap<>();
15+
for (SignedToken term : strings) {
16+
String[] tokens = term.token.split("[a-z]", 3);
17+
String coefficient = tokens[0].replace("*", "").trim();
18+
if (coefficient.isEmpty()) {
19+
coefficient = "1";
20+
}
21+
if (tokens.length == 1) {
22+
cof.put(0, Fraction.parse(coefficient).multiply(term.sign.factor));
23+
} else {
24+
String rawExponent = tokens[1].replace("^", "").trim();
25+
if (rawExponent.isEmpty()) {
26+
cof.put(1, Fraction.parse(coefficient).multiply(term.sign.factor));
27+
} else {
28+
int exponent = Integer.parseInt(rawExponent);
29+
cof.put(exponent, Fraction.parse(coefficient).multiply(term.sign.factor));
30+
}
31+
}
32+
}
33+
Integer highestExponent = cof.lastKey();
34+
List<Fraction> result = new ArrayList<>(highestExponent);
35+
for (int i = 0; i <= highestExponent; i++) {
36+
result.add(Fraction.ZERO);
37+
}
38+
for (Map.Entry<Integer, Fraction> e : cof.entrySet()) {
39+
Integer exponent = e.getKey();
40+
Fraction coefficient = e.getValue();
41+
result.set(exponent, coefficient);
42+
}
43+
return result;
44+
}
45+
46+
enum Sign {
47+
PLUS(1), MINUS(-1);
48+
final int factor;
49+
50+
Sign(int factor) {
51+
this.factor = factor;
52+
}
53+
}
54+
55+
record SignedToken(Sign sign, String token) {
56+
}
57+
58+
private static List<SignedToken> split(String s) {
59+
List<SignedToken> result = new ArrayList<>();
60+
Sign sign = Sign.PLUS;
61+
int pos = -1;
62+
for (int i = 0; i < s.length(); i++) {
63+
if (s.charAt(i) == '-') {
64+
result.add(new SignedToken(sign, s.substring(pos + 1, i).trim()));
65+
sign = Sign.MINUS;
66+
pos = i;
67+
} else if (s.charAt(i) == '+') {
68+
result.add(new SignedToken(sign, s.substring(pos + 1, i).trim()));
69+
sign = Sign.PLUS;
70+
pos = i;
71+
}
72+
}
73+
if (pos < s.length() - 1) {
74+
result.add(new SignedToken(sign, s.substring(pos + 1).trim()));
75+
}
76+
return result;
77+
}
78+
}

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

Lines changed: 11 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
import java.util.ArrayList;
66
import java.util.List;
7-
import java.util.Map;
8-
import java.util.TreeMap;
7+
8+
import static io.polypen.Util.isAbsoluteOne;
99

1010
public final class Polynomial {
1111
private final List<Fraction> coefficients;
@@ -14,6 +14,10 @@ private Polynomial(List<Fraction> coefficients) {
1414
this.coefficients = coefficients;
1515
}
1616

17+
public static Polynomial parse(String s) {
18+
return new Polynomial(Parser.parse(s));
19+
}
20+
1721
@Override
1822
public String toString() {
1923
List<String> result = new ArrayList<>(coefficients.size());
@@ -23,87 +27,18 @@ public String toString() {
2327
continue;
2428
}
2529
String plus = (i == coefficients.size() - 1 && coefficient.compareTo(Fraction.ZERO) > 0) ? "" : "+ ";
26-
String prettyCoefficient = coefficient.compareTo(Fraction.ZERO) < 0 ? "- " : plus;
30+
String prettySign = coefficient.compareTo(Fraction.ZERO) < 0 ? "- " : plus;
2731
if (i == 0) {
28-
result.add(prettyCoefficient + coefficient.abs());
32+
result.add(prettySign + coefficient.abs());
2933
} else {
3034
String exponent = i == 1 ? "x" : "x^" + i;
31-
if (coefficient.isOne()) {
32-
result.add(plus + exponent);
33-
} else if (coefficient.equals(Fraction.ONE.negate())) {
34-
result.add("- " + exponent);
35+
if (isAbsoluteOne(coefficient)) {
36+
result.add(prettySign + exponent);
3537
} else {
36-
result.add(prettyCoefficient + coefficient.abs() + " " + "x^" + i);
38+
result.add(prettySign + coefficient.abs() + " " + "x^" + i);
3739
}
3840
}
3941
}
4042
return String.join(" ", result);
4143
}
42-
43-
public static Polynomial parse(String s) {
44-
List<SignedToken> strings = split(s.trim());
45-
TreeMap<Integer, Fraction> cof = new TreeMap<>();
46-
for (SignedToken term : strings) {
47-
String[] tokens = term.token.split("[a-z]", 3);
48-
String coefficient = tokens[0].replace("*", "").trim();
49-
if (coefficient.isEmpty()) {
50-
coefficient = "1";
51-
}
52-
if (tokens.length == 1) {
53-
cof.put(0, Fraction.parse(coefficient).multiply(term.sign.factor));
54-
} else {
55-
String rawExponent = tokens[1].replace("^", "").trim();
56-
if (rawExponent.isEmpty()) {
57-
cof.put(1, Fraction.parse(coefficient).multiply(term.sign.factor));
58-
} else {
59-
int exponent = Integer.parseInt(rawExponent);
60-
cof.put(exponent, Fraction.parse(coefficient).multiply(term.sign.factor));
61-
}
62-
}
63-
}
64-
Integer highestExponent = cof.lastKey();
65-
List<Fraction> result = new ArrayList<>(highestExponent);
66-
for (int i = 0; i <= highestExponent; i++) {
67-
result.add(Fraction.ZERO);
68-
}
69-
for (Map.Entry<Integer, Fraction> e : cof.entrySet()) {
70-
Integer exponent = e.getKey();
71-
Fraction coefficient = e.getValue();
72-
result.set(exponent, coefficient);
73-
}
74-
return new Polynomial(result);
75-
}
76-
77-
enum Sign {
78-
PLUS(1), MINUS(-1);
79-
final int factor;
80-
81-
Sign(int factor) {
82-
this.factor = factor;
83-
}
84-
}
85-
86-
record SignedToken(Sign sign, String token) {
87-
}
88-
89-
static List<SignedToken> split(String s) {
90-
List<SignedToken> result = new ArrayList<>();
91-
Sign sign = Sign.PLUS;
92-
int pos = -1;
93-
for (int i = 0; i < s.length(); i++) {
94-
if (s.charAt(i) == '-') {
95-
result.add(new SignedToken(sign, s.substring(pos + 1, i).trim()));
96-
sign = Sign.MINUS;
97-
pos = i;
98-
} else if (s.charAt(i) == '+') {
99-
result.add(new SignedToken(sign, s.substring(pos + 1, i).trim()));
100-
sign = Sign.PLUS;
101-
pos = i;
102-
}
103-
}
104-
if (pos < s.length() - 1) {
105-
result.add(new SignedToken(sign, s.substring(pos + 1).trim()));
106-
}
107-
return result;
108-
}
10944
}

src/main/java/io/polypen/Util.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.polypen;
2+
3+
import org.apache.commons.numbers.fraction.Fraction;
4+
5+
final class Util {
6+
private static final Fraction NEGATIVE_ONE = Fraction.ONE.negate();
7+
8+
static boolean isAbsoluteOne(Fraction fraction) {
9+
return fraction.isOne() || NEGATIVE_ONE.equals(fraction);
10+
}
11+
12+
private Util() {
13+
}
14+
}

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@
22

33
import org.junit.jupiter.api.Test;
44

5+
import static org.junit.jupiter.api.Assertions.assertEquals;
6+
57
class PolynomialTest {
68

79
@Test
810
void parse() {
9-
System.out.println(Polynomial.parse("x^5 - x - 1"));
10-
}
11-
12-
@Test
13-
void split() {
14-
System.out.println(Polynomial.split("1 + 2 - 3"));
11+
assertEquals("x^5 - x - 1", Polynomial.parse("-x + x^5 - 1").toString());
1512
}
1613
}

0 commit comments

Comments
 (0)