From b504830c72ffc3af534e9dd2ea00f237d2e020e5 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Tue, 18 Dec 2018 02:22:04 +0700 Subject: [PATCH 001/108] add junit to the project --- .idea/misc.xml | 2 +- .idea/project.iml | 2 ++ test/FirstTest.java | 9 +++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 test/FirstTest.java diff --git a/.idea/misc.xml b/.idea/misc.xml index a165cb3..cbb200f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.idea/project.iml b/.idea/project.iml index 47baa8c..742c56c 100644 --- a/.idea/project.iml +++ b/.idea/project.iml @@ -3,8 +3,10 @@ + + \ No newline at end of file diff --git a/test/FirstTest.java b/test/FirstTest.java new file mode 100644 index 0000000..974d3a4 --- /dev/null +++ b/test/FirstTest.java @@ -0,0 +1,9 @@ +import org.junit.Assert; +import org.junit.Test; + +public class FirstTest { + @Test + public void firstTest() { + Assert.assertTrue(true); + } +} From c43560872d0f7bd6414957f0eb26df73617a4d87 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Tue, 18 Dec 2018 23:21:42 +0700 Subject: [PATCH 002/108] create class Parameters --- .idea/project.iml | 9 +++++++++ src/solver/Parameters.java | 31 +++++++++++++++++++++++++++++++ test/FirstTest.java | 9 --------- test/ParametersTest.java | 24 ++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 src/solver/Parameters.java delete mode 100644 test/FirstTest.java create mode 100644 test/ParametersTest.java diff --git a/.idea/project.iml b/.idea/project.iml index 742c56c..e77ad25 100644 --- a/.idea/project.iml +++ b/.idea/project.iml @@ -8,5 +8,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/solver/Parameters.java b/src/solver/Parameters.java new file mode 100644 index 0000000..081f8d4 --- /dev/null +++ b/src/solver/Parameters.java @@ -0,0 +1,31 @@ +package solver; + +import org.jetbrains.annotations.NotNull; + +public class Parameters { + public final String in; + public final String out; + public Parameters(@NotNull String[] args) { + boolean needAssignedIn = true; + String inTemp = "input.txt"; + boolean needAssignedOut = true; + String outTemp = "output.txt"; + for (int i = 0; i < args.length; ++i) { + if (needAssignedIn && "-in".equals(args[i])) { + if (i < args.length - 1) { + inTemp = args[i+1]; + needAssignedIn = false; + ++i; + } + } else if (needAssignedOut && "-out".equals(args[i])) { + if (i < args.length - 1) { + outTemp = args[i+1]; + needAssignedOut = false; + ++i; + } + } + } + in = inTemp; + out = outTemp; + } +} diff --git a/test/FirstTest.java b/test/FirstTest.java deleted file mode 100644 index 974d3a4..0000000 --- a/test/FirstTest.java +++ /dev/null @@ -1,9 +0,0 @@ -import org.junit.Assert; -import org.junit.Test; - -public class FirstTest { - @Test - public void firstTest() { - Assert.assertTrue(true); - } -} diff --git a/test/ParametersTest.java b/test/ParametersTest.java new file mode 100644 index 0000000..09e77ec --- /dev/null +++ b/test/ParametersTest.java @@ -0,0 +1,24 @@ +import org.junit.Assert; +import org.junit.Test; +import solver.Parameters; + +public class ParametersTest { + @Test + public void defaultParameters() { + Parameters p = new Parameters(new String[]{}); + Assert.assertEquals("input.txt", p.in); + Assert.assertEquals("output.txt", p.out); + } + + @Test + public void in() { + Parameters p = new Parameters(new String[]{"-in", "in.txt"}); + Assert.assertEquals("in.txt", p.in); + } + + @Test + public void out() { + Parameters p = new Parameters(new String[]{"-out", "out2.txt"}); + Assert.assertEquals("out2.txt", p.out); + } +} From 3905e47cfb158cac1aa7aaba2bb966d1e07cc398 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Tue, 18 Dec 2018 23:31:52 +0700 Subject: [PATCH 003/108] add final to some variables --- test/ParametersTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/ParametersTest.java b/test/ParametersTest.java index 09e77ec..4cb77dc 100644 --- a/test/ParametersTest.java +++ b/test/ParametersTest.java @@ -5,20 +5,20 @@ public class ParametersTest { @Test public void defaultParameters() { - Parameters p = new Parameters(new String[]{}); + final Parameters p = new Parameters(new String[]{}); Assert.assertEquals("input.txt", p.in); Assert.assertEquals("output.txt", p.out); } @Test public void in() { - Parameters p = new Parameters(new String[]{"-in", "in.txt"}); + final Parameters p = new Parameters(new String[]{"-in", "in.txt"}); Assert.assertEquals("in.txt", p.in); } @Test public void out() { - Parameters p = new Parameters(new String[]{"-out", "out2.txt"}); + final Parameters p = new Parameters(new String[]{"-out", "out2.txt"}); Assert.assertEquals("out2.txt", p.out); } } From 4034a3616847a29e3ccd48d528d5c991b44a5ba0 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Tue, 18 Dec 2018 23:32:32 +0700 Subject: [PATCH 004/108] add class Solver --- src/solver/Solver.java | 20 ++++++++++++++++++++ test/SolverTest.java | 14 ++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/solver/Solver.java create mode 100644 test/SolverTest.java diff --git a/src/solver/Solver.java b/src/solver/Solver.java new file mode 100644 index 0000000..fad7888 --- /dev/null +++ b/src/solver/Solver.java @@ -0,0 +1,20 @@ +package solver; + +import java.util.Scanner; + +public class Solver { + private double matrix[][]; + public Solver(Scanner sc) { + final int n = sc.nextInt(); + matrix = new double[n][n+1]; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + matrix[i][j] = sc.nextDouble(); + } + } + } + + public int getSize() { + return matrix.length; + } +} diff --git a/test/SolverTest.java b/test/SolverTest.java new file mode 100644 index 0000000..7c66441 --- /dev/null +++ b/test/SolverTest.java @@ -0,0 +1,14 @@ +import org.junit.Assert; +import org.junit.Test; +import solver.Solver; + +import java.util.Scanner; + +public class SolverTest { + @Test + public void constructor() { + final Scanner sc = new Scanner("1\n1 2"); + final Solver p = new Solver(sc); + Assert.assertEquals(1, p.getSize()); + } +} From 0f75925c1e0b32c2a04cf2ccbbbcf4629fe88648 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Tue, 18 Dec 2018 23:49:49 +0700 Subject: [PATCH 005/108] add multiply row to constant manipulation --- src/solver/Solver.java | 30 ++++++++++++++++++++++++++++-- test/SolverTest.java | 8 ++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/solver/Solver.java b/src/solver/Solver.java index fad7888..2f9a291 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -3,18 +3,44 @@ import java.util.Scanner; public class Solver { - private double matrix[][]; + private double[][] matrix; + private double[] solution; public Solver(Scanner sc) { final int n = sc.nextInt(); matrix = new double[n][n+1]; for (int i = 0; i < n; ++i) { - for (int j = 0; j < n; ++j) { + for (int j = 0; j < n+1; ++j) { matrix[i][j] = sc.nextDouble(); } } + solution = new double[n]; } public int getSize() { return matrix.length; } + + private void multiplyRow(int row, double k) { + final int n = matrix[row].length; + for (int i = 0; i < n; ++i) { + matrix[row][i] *= k; + } + } + + public void solve() { + final int n = matrix.length; + for (int i = 0; i < n; ++i) { + if (matrix[i][i] != 1.0) { + final double k = 1.0 / matrix[i][i]; + multiplyRow(i, k); + } + } + for (int i = 0; i < n; ++i) { + solution[i] = matrix[i][n]; + } + } + + public double[] getSolution() { + return solution; + } } diff --git a/test/SolverTest.java b/test/SolverTest.java index 7c66441..d509b3d 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -11,4 +11,12 @@ public void constructor() { final Solver p = new Solver(sc); Assert.assertEquals(1, p.getSize()); } + + @Test + public void solve() { + final Scanner sc = new Scanner("1\n2 4"); + final Solver p = new Solver(sc); + p.solve(); + Assert.assertArrayEquals(new double[]{2.0}, p.getSolution(), 0.0000001); + } } From f3aa7549e7bdb929eb4989f5b5fd3552066b87aa Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Wed, 19 Dec 2018 00:03:55 +0700 Subject: [PATCH 006/108] add Subtract One row from another row manipulation --- src/solver/Solver.java | 17 +++++++++++++++++ test/SolverTest.java | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/solver/Solver.java b/src/solver/Solver.java index 2f9a291..60c2cac 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -27,6 +27,13 @@ private void multiplyRow(int row, double k) { } } + private void subtractKRow1FromRow2(double k, int row1, int row2) { + final int n = matrix[row1].length; + for (int i = 0; i < n; ++i) { + matrix[row2][i] -= k*matrix[row1][i]; + } + } + public void solve() { final int n = matrix.length; for (int i = 0; i < n; ++i) { @@ -34,6 +41,16 @@ public void solve() { final double k = 1.0 / matrix[i][i]; multiplyRow(i, k); } + for (int j = i + 1; j < n; ++j) { + final double k = matrix[j][i]; + subtractKRow1FromRow2(k, i, j); + } + } + for (int i = n-1; i >= 0; --i) { + for (int j = i - 1; j >= 0; --j) { + final double k = matrix[j][i]; + subtractKRow1FromRow2(k, i, j); + } } for (int i = 0; i < n; ++i) { solution[i] = matrix[i][n]; diff --git a/test/SolverTest.java b/test/SolverTest.java index d509b3d..10fb5e9 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -19,4 +19,28 @@ public void solve() { p.solve(); Assert.assertArrayEquals(new double[]{2.0}, p.getSolution(), 0.0000001); } + + @Test + public void solve2() { + final Scanner sc = new Scanner("2\n1 2 3\n4 5 6"); + final Solver p = new Solver(sc); + p.solve(); + Assert.assertArrayEquals(new double[]{-1.0, 2.0}, p.getSolution(), 0.0000001); + } + + @Test + public void solve3() { + final Scanner sc = new Scanner("2\n4 5 7\n3 9 9"); + final Solver p = new Solver(sc); + p.solve(); + Assert.assertArrayEquals(new double[]{0.85714, 0.71429}, p.getSolution(), 0.00001); + } + + @Test + public void solve4() { + final Scanner sc = new Scanner("3\n1 1 2 9\n2 4 -3 1\n3 6 -5 0"); + final Solver p = new Solver(sc); + p.solve(); + Assert.assertArrayEquals(new double[]{1.0, 2.0, 3.0}, p.getSolution(), 0.0000001); + } } From 3b1ad416b858b8ef9db8c1821d1e6fec58cc8170 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Wed, 19 Dec 2018 00:23:16 +0700 Subject: [PATCH 007/108] add verbose mode --- src/solver/Solver.java | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/solver/Solver.java b/src/solver/Solver.java index 60c2cac..f89d334 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -1,11 +1,18 @@ package solver; +import java.util.Arrays; import java.util.Scanner; public class Solver { private double[][] matrix; private double[] solution; - public Solver(Scanner sc) { + private boolean verbose; + + public Solver(Scanner sc){ + this(sc, false); + } + + public Solver(Scanner sc, boolean verbose) { final int n = sc.nextInt(); matrix = new double[n][n+1]; for (int i = 0; i < n; ++i) { @@ -14,6 +21,7 @@ public Solver(Scanner sc) { } } solution = new double[n]; + this.verbose = verbose; } public int getSize() { @@ -21,6 +29,9 @@ public int getSize() { } private void multiplyRow(int row, double k) { + if (verbose) { + System.out.printf("%f * R%d -> R%d\n", k, row+1, row+1); + } final int n = matrix[row].length; for (int i = 0; i < n; ++i) { matrix[row][i] *= k; @@ -28,13 +39,18 @@ private void multiplyRow(int row, double k) { } private void subtractKRow1FromRow2(double k, int row1, int row2) { + if (verbose) { + System.out.printf("%f * R%d +R%d -> R%d\n", k, row1+1, row2+1, row2+1); + } final int n = matrix[row1].length; for (int i = 0; i < n; ++i) { - matrix[row2][i] -= k*matrix[row1][i]; + matrix[row2][i] += k*matrix[row1][i]; } } public void solve() { + System.out.println("Start solving the equation."); + System.out.println("Rows manipulation:"); final int n = matrix.length; for (int i = 0; i < n; ++i) { if (matrix[i][i] != 1.0) { @@ -42,19 +58,22 @@ public void solve() { multiplyRow(i, k); } for (int j = i + 1; j < n; ++j) { - final double k = matrix[j][i]; + final double k = -matrix[j][i]; subtractKRow1FromRow2(k, i, j); } } for (int i = n-1; i >= 0; --i) { for (int j = i - 1; j >= 0; --j) { - final double k = matrix[j][i]; + final double k = -matrix[j][i]; subtractKRow1FromRow2(k, i, j); } } for (int i = 0; i < n; ++i) { solution[i] = matrix[i][n]; } + if (verbose) { + System.out.println("The solution is: " + Arrays.toString(solution)); + } } public double[] getSolution() { From d63824f441d73ea1204d4e17ae5da05418c0b4b9 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Wed, 19 Dec 2018 00:34:21 +0700 Subject: [PATCH 008/108] refactoring --- src/solver/Solver.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/solver/Solver.java b/src/solver/Solver.java index f89d334..108f40a 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -38,7 +38,7 @@ private void multiplyRow(int row, double k) { } } - private void subtractKRow1FromRow2(double k, int row1, int row2) { + private void addKRow1ToRow2(double k, int row1, int row2) { if (verbose) { System.out.printf("%f * R%d +R%d -> R%d\n", k, row1+1, row2+1, row2+1); } @@ -59,13 +59,13 @@ public void solve() { } for (int j = i + 1; j < n; ++j) { final double k = -matrix[j][i]; - subtractKRow1FromRow2(k, i, j); + addKRow1ToRow2(k, i, j); } } for (int i = n-1; i >= 0; --i) { for (int j = i - 1; j >= 0; --j) { final double k = -matrix[j][i]; - subtractKRow1FromRow2(k, i, j); + addKRow1ToRow2(k, i, j); } } for (int i = 0; i < n; ++i) { From c6fa7ef829766b97cdb3b3df846fafa4fe4d424f Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Wed, 19 Dec 2018 00:38:10 +0700 Subject: [PATCH 009/108] add verbose to Parameters --- src/solver/Parameters.java | 5 +++++ test/ParametersTest.java | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/src/solver/Parameters.java b/src/solver/Parameters.java index 081f8d4..95fff77 100644 --- a/src/solver/Parameters.java +++ b/src/solver/Parameters.java @@ -5,11 +5,13 @@ public class Parameters { public final String in; public final String out; + public final boolean verbose; public Parameters(@NotNull String[] args) { boolean needAssignedIn = true; String inTemp = "input.txt"; boolean needAssignedOut = true; String outTemp = "output.txt"; + boolean verboseTemp = false; for (int i = 0; i < args.length; ++i) { if (needAssignedIn && "-in".equals(args[i])) { if (i < args.length - 1) { @@ -23,9 +25,12 @@ public Parameters(@NotNull String[] args) { needAssignedOut = false; ++i; } + } else if (!verboseTemp && "-verbose".equals(args[i])) { + verboseTemp = true; } } in = inTemp; out = outTemp; + verbose = verboseTemp; } } diff --git a/test/ParametersTest.java b/test/ParametersTest.java index 4cb77dc..d29cfa9 100644 --- a/test/ParametersTest.java +++ b/test/ParametersTest.java @@ -8,6 +8,7 @@ public void defaultParameters() { final Parameters p = new Parameters(new String[]{}); Assert.assertEquals("input.txt", p.in); Assert.assertEquals("output.txt", p.out); + Assert.assertEquals(false, p.verbose); } @Test @@ -21,4 +22,10 @@ public void out() { final Parameters p = new Parameters(new String[]{"-out", "out2.txt"}); Assert.assertEquals("out2.txt", p.out); } + + @Test + public void verbose() { + final Parameters p = new Parameters(new String[]{"-verbose"}); + Assert.assertEquals(true, p.verbose); + } } From 280fba15900f623563d0235b17a5c55021245e3a Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Wed, 19 Dec 2018 01:48:58 +0700 Subject: [PATCH 010/108] add acceptance test and Main class --- acceptance tests/in.txt | 4 ++++ acceptance tests/out.txt | 1 + acceptance tests/tests.ps1 | 9 +++++++++ src/solver/Main.java | 11 ++++++++++- src/solver/Solver.java | 28 +++++++++++++++++++++++++--- 5 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 acceptance tests/in.txt create mode 100644 acceptance tests/out.txt create mode 100644 acceptance tests/tests.ps1 diff --git a/acceptance tests/in.txt b/acceptance tests/in.txt new file mode 100644 index 0000000..c36dd4b --- /dev/null +++ b/acceptance tests/in.txt @@ -0,0 +1,4 @@ +3 +1 1 2 9 +2 4 -3 1 +3 6 -5 0 \ No newline at end of file diff --git a/acceptance tests/out.txt b/acceptance tests/out.txt new file mode 100644 index 0000000..c887286 --- /dev/null +++ b/acceptance tests/out.txt @@ -0,0 +1 @@ +(1,000000, 2,000000, 3,000000) diff --git a/acceptance tests/tests.ps1 b/acceptance tests/tests.ps1 new file mode 100644 index 0000000..93734fd --- /dev/null +++ b/acceptance tests/tests.ps1 @@ -0,0 +1,9 @@ +Describe JavaAcceptanceTests { + It 'shoud solve linear equations1' { + Remove-Item out.txt -ErrorAction SilentlyContinue + Start-Process -FilePath "java.exe" -argumentlist '-classpath "..\out\production\project" solver.Main -in in.txt -out out.txt' -NoNewWindow -Wait + [String[]]$lines = [System.IO.File]::ReadLines("out.txt") + $lines.Count | Should Be 1 + $lines[0] | Should Be "(1,000000, 2,000000, 3,000000)" + } +} \ No newline at end of file diff --git a/src/solver/Main.java b/src/solver/Main.java index 4404714..d31d1a5 100644 --- a/src/solver/Main.java +++ b/src/solver/Main.java @@ -1,7 +1,16 @@ package solver; +import java.io.FileNotFoundException; + public class Main { public static void main(String[] args) { - System.out.print("Hello world!"); + try { + Parameters p = new Parameters(args); + Solver s = new Solver(p.in, p.verbose); + s.solve(); + s.writeSolutionToFile(p.out); + } catch (FileNotFoundException e) { + System.out.printf("An exception occurs %s", e.getMessage()); + } } } \ No newline at end of file diff --git a/src/solver/Solver.java b/src/solver/Solver.java index 108f40a..a0e3654 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -1,5 +1,10 @@ package solver; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; import java.util.Arrays; import java.util.Scanner; @@ -12,7 +17,7 @@ public Solver(Scanner sc){ this(sc, false); } - public Solver(Scanner sc, boolean verbose) { + public Solver(@NotNull Scanner sc, boolean verbose) { final int n = sc.nextInt(); matrix = new double[n][n+1]; for (int i = 0; i < n; ++i) { @@ -24,6 +29,10 @@ public Solver(Scanner sc, boolean verbose) { this.verbose = verbose; } + public Solver(String in, boolean verbose) throws FileNotFoundException { + this(new Scanner(new File(in)), verbose); + } + public int getSize() { return matrix.length; } @@ -49,8 +58,10 @@ private void addKRow1ToRow2(double k, int row1, int row2) { } public void solve() { - System.out.println("Start solving the equation."); - System.out.println("Rows manipulation:"); + if (verbose) { + System.out.println("Start solving the equation."); + System.out.println("Rows manipulation:"); + } final int n = matrix.length; for (int i = 0; i < n; ++i) { if (matrix[i][i] != 1.0) { @@ -79,4 +90,15 @@ public void solve() { public double[] getSolution() { return solution; } + + public void writeSolutionToFile(String out) throws FileNotFoundException { + File file = new File(out); + PrintWriter printWriter = new PrintWriter(file); + printWriter.printf("(%f", solution[0]); + for (int i = 1; i < solution.length; ++i) { + printWriter.printf(", %f", solution[i]); + } + printWriter.println(")"); + printWriter.close(); + } } From d9fe37240bfc5106c65826ad6e07dbbab8f2d5dc Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Thu, 20 Dec 2018 11:25:22 +0700 Subject: [PATCH 011/108] refactoring --- src/solver/Solver.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/solver/Solver.java b/src/solver/Solver.java index a0e3654..b670232 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -5,12 +5,13 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; -import java.util.Arrays; import java.util.Scanner; +import java.util.stream.IntStream; public class Solver { private double[][] matrix; private double[] solution; + private int[] soltionIndexes; private boolean verbose; public Solver(Scanner sc){ @@ -26,6 +27,7 @@ public Solver(@NotNull Scanner sc, boolean verbose) { } } solution = new double[n]; + soltionIndexes = IntStream.range(0, n).toArray(); this.verbose = verbose; } @@ -83,7 +85,12 @@ public void solve() { solution[i] = matrix[i][n]; } if (verbose) { - System.out.println("The solution is: " + Arrays.toString(solution)); + System.out.print("The solution is: "); + System.out.printf("(%f", solution[soltionIndexes[0]]); + for (int i = 1; i < solution.length; ++i) { + System.out.printf(", %f", solution[soltionIndexes[i]]); + } + System.out.println(")"); } } @@ -94,9 +101,9 @@ public double[] getSolution() { public void writeSolutionToFile(String out) throws FileNotFoundException { File file = new File(out); PrintWriter printWriter = new PrintWriter(file); - printWriter.printf("(%f", solution[0]); + printWriter.printf("(%f", solution[soltionIndexes[0]]); for (int i = 1; i < solution.length; ++i) { - printWriter.printf(", %f", solution[i]); + printWriter.printf(", %f", solution[soltionIndexes[i]]); } printWriter.println(")"); printWriter.close(); From 90bf8409e383d07a4a86c09b2e771498a25e62b0 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Thu, 20 Dec 2018 14:10:29 +0700 Subject: [PATCH 012/108] handle most special cases --- acceptance tests/in.txt | 2 +- acceptance tests/in1.txt | 5 ++ acceptance tests/out1.txt | 1 + acceptance tests/tests.ps1 | 12 ++- src/solver/NumberSolutions.java | 7 ++ src/solver/Solver.java | 149 ++++++++++++++++++++++++++------ test/SolverTest.java | 62 +++++++++++-- 7 files changed, 201 insertions(+), 37 deletions(-) create mode 100644 acceptance tests/in1.txt create mode 100644 acceptance tests/out1.txt create mode 100644 src/solver/NumberSolutions.java diff --git a/acceptance tests/in.txt b/acceptance tests/in.txt index c36dd4b..e12cca9 100644 --- a/acceptance tests/in.txt +++ b/acceptance tests/in.txt @@ -1,4 +1,4 @@ -3 +3 3 1 1 2 9 2 4 -3 1 3 6 -5 0 \ No newline at end of file diff --git a/acceptance tests/in1.txt b/acceptance tests/in1.txt new file mode 100644 index 0000000..112d10d --- /dev/null +++ b/acceptance tests/in1.txt @@ -0,0 +1,5 @@ +3 4 +0 1 2 9 +0 1 3 1 +1 0 6 0 +2 0 2 0 \ No newline at end of file diff --git a/acceptance tests/out1.txt b/acceptance tests/out1.txt new file mode 100644 index 0000000..4a011fc --- /dev/null +++ b/acceptance tests/out1.txt @@ -0,0 +1 @@ +There are no solutions diff --git a/acceptance tests/tests.ps1 b/acceptance tests/tests.ps1 index 93734fd..28ea897 100644 --- a/acceptance tests/tests.ps1 +++ b/acceptance tests/tests.ps1 @@ -1,9 +1,17 @@ Describe JavaAcceptanceTests { - It 'shoud solve linear equations1' { + It 'single solution' { Remove-Item out.txt -ErrorAction SilentlyContinue Start-Process -FilePath "java.exe" -argumentlist '-classpath "..\out\production\project" solver.Main -in in.txt -out out.txt' -NoNewWindow -Wait [String[]]$lines = [System.IO.File]::ReadLines("out.txt") $lines.Count | Should Be 1 $lines[0] | Should Be "(1,000000, 2,000000, 3,000000)" - } + } + + It 'no solution' { + Remove-Item out1.txt -ErrorAction SilentlyContinue + Start-Process -FilePath "java.exe" -argumentlist '-classpath "..\out\production\project" solver.Main -in in1.txt -out out1.txt' -NoNewWindow -Wait + [String[]]$lines = [System.IO.File]::ReadLines("out1.txt") + $lines.Count | Should Be 1 + $lines[0] | Should Be "There are no solutions" + } } \ No newline at end of file diff --git a/src/solver/NumberSolutions.java b/src/solver/NumberSolutions.java new file mode 100644 index 0000000..7513a64 --- /dev/null +++ b/src/solver/NumberSolutions.java @@ -0,0 +1,7 @@ +package solver; + +public enum NumberSolutions { + NONE, + ONE, + MANY +} diff --git a/src/solver/Solver.java b/src/solver/Solver.java index b670232..6b7a7ec 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -9,25 +9,32 @@ import java.util.stream.IntStream; public class Solver { + private static final double epsilon = 0.0000001; + + private int numberEquations; + private int numberVariables; private double[][] matrix; private double[] solution; - private int[] soltionIndexes; + private int[] solutionIndexes; private boolean verbose; + private NumberSolutions numberSolutions = NumberSolutions.ONE; public Solver(Scanner sc){ this(sc, false); } public Solver(@NotNull Scanner sc, boolean verbose) { - final int n = sc.nextInt(); - matrix = new double[n][n+1]; - for (int i = 0; i < n; ++i) { - for (int j = 0; j < n+1; ++j) { + numberVariables = sc.nextInt(); + final int realNumberEquations = sc.nextInt(); + numberEquations = (realNumberEquations < numberVariables) ? numberVariables : realNumberEquations; + matrix = new double[numberEquations][numberVariables +1]; + for (int i = 0; i < realNumberEquations; ++i) { + for (int j = 0; j < numberVariables +1; ++j) { matrix[i][j] = sc.nextDouble(); } } - solution = new double[n]; - soltionIndexes = IntStream.range(0, n).toArray(); + solution = new double[numberVariables]; + solutionIndexes = IntStream.range(0, numberVariables).toArray(); this.verbose = verbose; } @@ -53,59 +60,145 @@ private void addKRow1ToRow2(double k, int row1, int row2) { if (verbose) { System.out.printf("%f * R%d +R%d -> R%d\n", k, row1+1, row2+1, row2+1); } - final int n = matrix[row1].length; - for (int i = 0; i < n; ++i) { + for (int i = 0; i < numberVariables +1; ++i) { matrix[row2][i] += k*matrix[row1][i]; } } + private void swapRows(int row1, int row2) { + if (verbose) { + System.out.printf("R%d <-> R%d\n", row1+1, row2+1); + } + for (int i = 0; i < numberVariables +1; ++i) { + final double temp = matrix[row1][i]; + matrix[row1][i] = matrix[row2][i]; + matrix[row2][i] = temp; + } + } + + public void solve() { if (verbose) { System.out.println("Start solving the equation."); System.out.println("Rows manipulation:"); } - final int n = matrix.length; - for (int i = 0; i < n; ++i) { - if (matrix[i][i] != 1.0) { + for (int i = 0; i < numberVariables; ++i) { + if (Math.abs(matrix[i][i]) < epsilon) { + boolean notFound = true; + for (int j = i+1; j < numberEquations; ++j) { + if (Math.abs(matrix[j][i]) > epsilon) { + swapRows(i, j); + notFound = false; + break; + } + } + if (notFound) { + for (int j = i+1; j < numberEquations; ++j) { + if (Math.abs(matrix[i][j]) > epsilon) { + swapColumns(i, j); + notFound = false; + break; + } + } + } + if (notFound) { + if (Math.abs(matrix[i][numberEquations]) < epsilon) { + numberSolutions = NumberSolutions.MANY; + continue; + } else { + numberSolutions = NumberSolutions.NONE; + printSolution(); + return; + } + } + } + + if (Math.abs(matrix[i][i] - 1.0) > epsilon) { final double k = 1.0 / matrix[i][i]; multiplyRow(i, k); } - for (int j = i + 1; j < n; ++j) { + for (int j = i + 1; j < numberEquations && j < numberVariables; ++j) { final double k = -matrix[j][i]; - addKRow1ToRow2(k, i, j); + if (Math.abs(k) >= epsilon) { + addKRow1ToRow2(k, i, j); + } } } - for (int i = n-1; i >= 0; --i) { + for (int i = numberVariables - 1; i >= 0; --i) { for (int j = i - 1; j >= 0; --j) { final double k = -matrix[j][i]; - addKRow1ToRow2(k, i, j); + if (Math.abs(k) >= epsilon) { + addKRow1ToRow2(k, i, j); + } } } - for (int i = 0; i < n; ++i) { - solution[i] = matrix[i][n]; + for (int i = 0; i < numberEquations && i < numberVariables; ++i) { + solution[solutionIndexes[i]] = matrix[i][numberVariables]; } + for (int i = numberVariables; i < numberEquations; ++i) { + double sum = 0.0; + for (int j = 0; j < numberVariables; ++j) { + sum += solution[solutionIndexes[j]] * matrix[i][solutionIndexes[j]]; + } + if (Math.abs(sum - matrix[i][numberVariables]) >= epsilon) { + numberSolutions = NumberSolutions.NONE; + printSolution(); + return; + } + } + + printSolution(); + } + + private void printSolution() { if (verbose) { - System.out.print("The solution is: "); - System.out.printf("(%f", solution[soltionIndexes[0]]); + printSolutionInternal(new PrintWriter(System.out)); + } + } + + private void printSolutionInternal(PrintWriter printWriter) { + if (numberSolutions == NumberSolutions.NONE) { + printWriter.println("There are no solutions"); + } else { + printWriter.printf("(%f", solution[solutionIndexes[0]]); for (int i = 1; i < solution.length; ++i) { - System.out.printf(", %f", solution[soltionIndexes[i]]); + printWriter.printf(", %f", solution[solutionIndexes[i]]); } - System.out.println(")"); + printWriter.println(")"); + } + printWriter.flush(); + printWriter.close(); + } + + private void swapColumns(int column1, int column2) { + if (verbose) { + System.out.printf("C%d <-> C%d\n", column1+1, column2+1); } + final int n = matrix.length; + for (int i = 0; i < n; ++i) { + final double temp = matrix[i][column1]; + matrix[i][column1] = matrix[i][column2]; + matrix[i][column2] = temp; + } + final int temp = solutionIndexes[column1]; + solutionIndexes[column1] = solutionIndexes[column2]; + solutionIndexes[column2] = temp; } public double[] getSolution() { + if (numberSolutions == NumberSolutions.NONE) { + return null; + } return solution; } + public NumberSolutions getNumberSolutions() { + return numberSolutions; + } + public void writeSolutionToFile(String out) throws FileNotFoundException { File file = new File(out); PrintWriter printWriter = new PrintWriter(file); - printWriter.printf("(%f", solution[soltionIndexes[0]]); - for (int i = 1; i < solution.length; ++i) { - printWriter.printf(", %f", solution[soltionIndexes[i]]); - } - printWriter.println(")"); - printWriter.close(); + printSolutionInternal(printWriter); } } diff --git a/test/SolverTest.java b/test/SolverTest.java index 10fb5e9..6d8960c 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -1,5 +1,6 @@ import org.junit.Assert; import org.junit.Test; +import solver.NumberSolutions; import solver.Solver; import java.util.Scanner; @@ -7,40 +8,89 @@ public class SolverTest { @Test public void constructor() { - final Scanner sc = new Scanner("1\n1 2"); + final Scanner sc = new Scanner("1 1\n1 2"); final Solver p = new Solver(sc); Assert.assertEquals(1, p.getSize()); } @Test - public void solve() { - final Scanner sc = new Scanner("1\n2 4"); + public void solve1() { + final Scanner sc = new Scanner("1 1\n2 4"); final Solver p = new Solver(sc); p.solve(); + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); Assert.assertArrayEquals(new double[]{2.0}, p.getSolution(), 0.0000001); } @Test public void solve2() { - final Scanner sc = new Scanner("2\n1 2 3\n4 5 6"); + final Scanner sc = new Scanner("2 2\n1 2 3\n4 5 6"); final Solver p = new Solver(sc); p.solve(); + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); Assert.assertArrayEquals(new double[]{-1.0, 2.0}, p.getSolution(), 0.0000001); } @Test public void solve3() { - final Scanner sc = new Scanner("2\n4 5 7\n3 9 9"); + final Scanner sc = new Scanner("2 2\n4 5 7\n3 9 9"); final Solver p = new Solver(sc); p.solve(); + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); Assert.assertArrayEquals(new double[]{0.85714, 0.71429}, p.getSolution(), 0.00001); } @Test public void solve4() { - final Scanner sc = new Scanner("3\n1 1 2 9\n2 4 -3 1\n3 6 -5 0"); + final Scanner sc = new Scanner("3 3\n1 1 2 9\n2 4 -3 1\n3 6 -5 0"); final Solver p = new Solver(sc); p.solve(); + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); Assert.assertArrayEquals(new double[]{1.0, 2.0, 3.0}, p.getSolution(), 0.0000001); } + + @Test + public void solve5() { + final Scanner sc = new Scanner("2 2\n0 1 1\n1 0 1"); + final Solver p = new Solver(sc); + p.solve(); + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); + Assert.assertArrayEquals(new double[]{1.0, 1.0}, p.getSolution(), 0.0000001); + } + + @Test + public void solve6() { + final Scanner sc = new Scanner("2 2\n0 1 1\n0 2 2"); + final Solver p = new Solver(sc); + p.solve(); + Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); + Assert.assertArrayEquals(new double[]{0.0, 1.0}, p.getSolution(), 0.0000001); + } + + @Test + public void solve7() { + final Scanner sc = new Scanner("2 2\n0 1 1\n0 2 3"); + final Solver p = new Solver(sc); + p.solve(); + Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); + Assert.assertArrayEquals(null, p.getSolution(), 0.0000001); + } + + @Test + public void solve8() { + final Scanner sc = new Scanner("3 4\n0 1 2 9\n0 1 3 1\n1 0 6 0\n2 0 2 0"); + final Solver p = new Solver(sc); + p.solve(); + Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); + Assert.assertArrayEquals(null, p.getSolution(), 0.0000001); + } + + @Test + public void solve9() { + final Scanner sc = new Scanner("3 1\n1 1 2 9"); + final Solver p = new Solver(sc); + p.solve(); + Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); + Assert.assertArrayEquals(new double[]{9.0, 0.0, 0.0}, p.getSolution(), 0.0000001); + } } From b26b7e23806b434a88e3c636729ebf1423aa8e8c Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Thu, 20 Dec 2018 19:42:34 +0700 Subject: [PATCH 013/108] add general solution --- acceptance tests/in.txt | 2 +- acceptance tests/in2.txt | 5 ++++ acceptance tests/out2.txt | 1 + acceptance tests/tests.ps1 | 8 ++++++ src/solver/Solver.java | 58 ++++++++++++++++++++++++++++++++------ test/SolverTest.java | 47 ++++++++++++++++++++++++------ 6 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 acceptance tests/in2.txt create mode 100644 acceptance tests/out2.txt diff --git a/acceptance tests/in.txt b/acceptance tests/in.txt index e12cca9..b1db2cf 100644 --- a/acceptance tests/in.txt +++ b/acceptance tests/in.txt @@ -1,4 +1,4 @@ 3 3 1 1 2 9 2 4 -3 1 -3 6 -5 0 \ No newline at end of file +3 6 -5 0 diff --git a/acceptance tests/in2.txt b/acceptance tests/in2.txt new file mode 100644 index 0000000..512957d --- /dev/null +++ b/acceptance tests/in2.txt @@ -0,0 +1,5 @@ +4 4 +1 0 0 5 0 +0 0 0 0 0 +0 0 1 4 6 +0 0 5 5 5 \ No newline at end of file diff --git a/acceptance tests/out2.txt b/acceptance tests/out2.txt new file mode 100644 index 0000000..580aa58 --- /dev/null +++ b/acceptance tests/out2.txt @@ -0,0 +1 @@ +(-8,3333, x2, -0,6667, 1,6667) diff --git a/acceptance tests/tests.ps1 b/acceptance tests/tests.ps1 index 28ea897..8459dd3 100644 --- a/acceptance tests/tests.ps1 +++ b/acceptance tests/tests.ps1 @@ -7,6 +7,14 @@ Describe JavaAcceptanceTests { $lines[0] | Should Be "(1,000000, 2,000000, 3,000000)" } + It 'many solutions' { + Remove-Item out2.txt -ErrorAction SilentlyContinue + Start-Process -FilePath "java.exe" -argumentlist '-classpath "..\out\production\project" solver.Main -in in2.txt -out out2.txt' -NoNewWindow -Wait + [String[]]$lines = [System.IO.File]::ReadLines("out2.txt") + $lines.Count | Should Be 1 + $lines[0] | Should Be "(-8,3333, x2, -0,6667, 1,6667)" + } + It 'no solution' { Remove-Item out1.txt -ErrorAction SilentlyContinue Start-Process -FilePath "java.exe" -argumentlist '-classpath "..\out\production\project" solver.Main -in in1.txt -out out1.txt' -NoNewWindow -Wait diff --git a/src/solver/Solver.java b/src/solver/Solver.java index 6b7a7ec..576b3a3 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -5,6 +5,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; +import java.util.Arrays; import java.util.Scanner; import java.util.stream.IntStream; @@ -15,6 +16,7 @@ public class Solver { private int numberVariables; private double[][] matrix; private double[] solution; + private String[] solutionGeneral; private int[] solutionIndexes; private boolean verbose; private NumberSolutions numberSolutions = NumberSolutions.ONE; @@ -34,6 +36,7 @@ public Solver(@NotNull Scanner sc, boolean verbose) { } } solution = new double[numberVariables]; + solutionGeneral = new String[numberVariables]; solutionIndexes = IntStream.range(0, numberVariables).toArray(); this.verbose = verbose; } @@ -88,7 +91,6 @@ public void solve() { for (int j = i+1; j < numberEquations; ++j) { if (Math.abs(matrix[j][i]) > epsilon) { swapRows(i, j); - notFound = false; break; } } @@ -101,6 +103,20 @@ public void solve() { } } } + + if (notFound) { + for (int k = i+1; notFound && k < numberVariables; ++k) { + for (int j = i+1; j < numberEquations; ++j) { + if (Math.abs(matrix[j][k]) > epsilon) { + swapColumns(k, i); + swapRows(j, i); + notFound = false; + break; + } + } + } + } + if (notFound) { if (Math.abs(matrix[i][numberEquations]) < epsilon) { numberSolutions = NumberSolutions.MANY; @@ -134,6 +150,17 @@ public void solve() { } for (int i = 0; i < numberEquations && i < numberVariables; ++i) { solution[solutionIndexes[i]] = matrix[i][numberVariables]; + if (Math.abs(matrix[i][i]) < epsilon ) { + solutionGeneral[solutionIndexes[i]] = "x" + (solutionIndexes[i]+1); + } else { + solutionGeneral[solutionIndexes[i]] = String.format("%.4f", matrix[i][numberVariables]); + for (int j = i + 1; j < numberVariables; ++j) { + if (Math.abs(matrix[i][j]) > epsilon) { + solutionGeneral[solutionIndexes[i]] = solutionGeneral[solutionIndexes[i]] + " - x" + + (solutionIndexes[j]+1) + " * (" + String.format("%.4f",matrix[i][j]) + ")" ; + } + } + } } for (int i = numberVariables; i < numberEquations; ++i) { double sum = 0.0; @@ -152,22 +179,30 @@ public void solve() { private void printSolution() { if (verbose) { - printSolutionInternal(new PrintWriter(System.out)); + printSolutionInternal(new PrintWriter(System.out), false); } } - private void printSolutionInternal(PrintWriter printWriter) { + private void printSolutionInternal(PrintWriter printWriter, boolean shouldClose) { if (numberSolutions == NumberSolutions.NONE) { printWriter.println("There are no solutions"); + } else if (numberSolutions == NumberSolutions.ONE){ + printWriter.printf("(%f", solution[0]); + for (int i = 1; i < solution.length; ++i) { + printWriter.printf(", %f", solution[i]); + } + printWriter.println(")"); } else { - printWriter.printf("(%f", solution[solutionIndexes[0]]); + printWriter.printf("(%s", solutionGeneral[0]); for (int i = 1; i < solution.length; ++i) { - printWriter.printf(", %f", solution[solutionIndexes[i]]); + printWriter.printf(", %s", solutionGeneral[i]); } printWriter.println(")"); } printWriter.flush(); - printWriter.close(); + if (shouldClose) { + printWriter.close(); + } } private void swapColumns(int column1, int column2) { @@ -185,7 +220,7 @@ private void swapColumns(int column1, int column2) { solutionIndexes[column2] = temp; } - public double[] getSolution() { + public double[] getParticularSolution() { if (numberSolutions == NumberSolutions.NONE) { return null; } @@ -199,6 +234,13 @@ public NumberSolutions getNumberSolutions() { public void writeSolutionToFile(String out) throws FileNotFoundException { File file = new File(out); PrintWriter printWriter = new PrintWriter(file); - printSolutionInternal(printWriter); + printSolutionInternal(printWriter, true); + } + + public String[] getGeneralSolution() { + if (numberSolutions != NumberSolutions.MANY) { + return null; + } + return solutionGeneral; } } diff --git a/test/SolverTest.java b/test/SolverTest.java index 6d8960c..be9a724 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -19,7 +19,8 @@ public void solve1() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{2.0}, p.getSolution(), 0.0000001); + Assert.assertArrayEquals(new double[]{2.0}, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(null, p.getGeneralSolution()); } @Test @@ -28,7 +29,8 @@ public void solve2() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{-1.0, 2.0}, p.getSolution(), 0.0000001); + Assert.assertArrayEquals(new double[]{-1.0, 2.0}, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(null, p.getGeneralSolution()); } @Test @@ -37,7 +39,8 @@ public void solve3() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{0.85714, 0.71429}, p.getSolution(), 0.00001); + Assert.assertArrayEquals(new double[]{0.85714, 0.71429}, p.getParticularSolution(), 0.00001); + Assert.assertArrayEquals(null, p.getGeneralSolution()); } @Test @@ -46,7 +49,8 @@ public void solve4() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{1.0, 2.0, 3.0}, p.getSolution(), 0.0000001); + Assert.assertArrayEquals(new double[]{1.0, 2.0, 3.0}, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(null, p.getGeneralSolution()); } @Test @@ -55,7 +59,8 @@ public void solve5() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{1.0, 1.0}, p.getSolution(), 0.0000001); + Assert.assertArrayEquals(new double[]{1.0, 1.0}, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(null, p.getGeneralSolution()); } @Test @@ -64,7 +69,8 @@ public void solve6() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{0.0, 1.0}, p.getSolution(), 0.0000001); + Assert.assertArrayEquals(new double[]{0.0, 1.0}, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(new String[]{"x1", "1,0000"}, p.getGeneralSolution()); } @Test @@ -73,7 +79,8 @@ public void solve7() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); - Assert.assertArrayEquals(null, p.getSolution(), 0.0000001); + Assert.assertArrayEquals(null, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(null, p.getGeneralSolution()); } @Test @@ -82,7 +89,8 @@ public void solve8() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); - Assert.assertArrayEquals(null, p.getSolution(), 0.0000001); + Assert.assertArrayEquals(null, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(null, p.getGeneralSolution()); } @Test @@ -91,6 +99,27 @@ public void solve9() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{9.0, 0.0, 0.0}, p.getSolution(), 0.0000001); + Assert.assertArrayEquals(new double[]{9.0, 0.0, 0.0}, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(new String[]{"9,0000 - x2 * (1,0000) - x3 * (2,0000)", "x2", "x3"}, p.getGeneralSolution()); + } + + @Test + public void solve10() { + final Scanner sc = new Scanner("4 4\n1 0 0 5 0\n0 0 0 0 0\n0 0 1 4 6\n0 0 5 5 5"); + final Solver p = new Solver(sc); + p.solve(); + Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); + Assert.assertArrayEquals(new double[]{-8.3333333, 0.0, -0.6666667, 1.6666667}, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(new String[]{"-8,3333", "x2", "-0,6667", "1,6667"}, p.getGeneralSolution()); + } + + @Test + public void solve11() { + final Scanner sc = new Scanner("4 4\n2 3 -1 1 1\n8 12 -9 8 3\n4 6 3 -2 3\n2 3 9 -7 3"); + final Solver p = new Solver(sc); + p.solve(); + Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); + Assert.assertArrayEquals(new double[]{0.6, 0.0, 0.2, 0.0}, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(new String[]{"0,6000 - x2 * (1,5000) - x4 * (0,1000)", "x2", "0,2000 - x4 * (-0,8000)", "x4"}, p.getGeneralSolution()); } } From aac53e08e90e3de6f4dcdf7a4b6141f5afffefe9 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Thu, 20 Dec 2018 19:53:32 +0700 Subject: [PATCH 014/108] refactoring --- src/solver/Solver.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/solver/Solver.java b/src/solver/Solver.java index 576b3a3..e922023 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -5,7 +5,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; -import java.util.Arrays; import java.util.Scanner; import java.util.stream.IntStream; @@ -179,11 +178,11 @@ public void solve() { private void printSolution() { if (verbose) { - printSolutionInternal(new PrintWriter(System.out), false); + printSolutionInternal(new PrintWriter(System.out, true)); } } - private void printSolutionInternal(PrintWriter printWriter, boolean shouldClose) { + private void printSolutionInternal(PrintWriter printWriter) { if (numberSolutions == NumberSolutions.NONE) { printWriter.println("There are no solutions"); } else if (numberSolutions == NumberSolutions.ONE){ @@ -200,9 +199,6 @@ private void printSolutionInternal(PrintWriter printWriter, boolean shouldClose) printWriter.println(")"); } printWriter.flush(); - if (shouldClose) { - printWriter.close(); - } } private void swapColumns(int column1, int column2) { @@ -234,7 +230,11 @@ public NumberSolutions getNumberSolutions() { public void writeSolutionToFile(String out) throws FileNotFoundException { File file = new File(out); PrintWriter printWriter = new PrintWriter(file); - printSolutionInternal(printWriter, true); + printSolutionInternal(printWriter); + printWriter.close(); + if (verbose) { + System.out.printf("Saved to file %s", out); + } } public String[] getGeneralSolution() { From 8f718a816e34b76269ab990eb5db8434c6af6ae5 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 04:08:55 +0700 Subject: [PATCH 015/108] add complex numbers --- acceptance tests/in3.txt | 4 ++ acceptance tests/out.txt | 2 +- acceptance tests/out2.txt | 2 +- acceptance tests/out3.txt | 1 + acceptance tests/tests.ps1 | 12 +++- src/solver/Complex.java | 114 +++++++++++++++++++++++++++++++++ src/solver/Solver.java | 78 ++++++++++++----------- test/ComplexTest.java | 125 +++++++++++++++++++++++++++++++++++++ test/SolverTest.java | 42 ++++++++----- 9 files changed, 325 insertions(+), 55 deletions(-) create mode 100644 acceptance tests/in3.txt create mode 100644 acceptance tests/out3.txt create mode 100644 src/solver/Complex.java create mode 100644 test/ComplexTest.java diff --git a/acceptance tests/in3.txt b/acceptance tests/in3.txt new file mode 100644 index 0000000..3b20f11 --- /dev/null +++ b/acceptance tests/in3.txt @@ -0,0 +1,4 @@ +3 3 +1+2i -1.5-1.1i 2.12 91+5i +-1+3i 1.2+3.5i -3.3 1+15i +12.31 1.3-5i 12.3i -78.3i \ No newline at end of file diff --git a/acceptance tests/out.txt b/acceptance tests/out.txt index c887286..fcb8c89 100644 --- a/acceptance tests/out.txt +++ b/acceptance tests/out.txt @@ -1 +1 @@ -(1,000000, 2,000000, 3,000000) +(1, 2, 3) diff --git a/acceptance tests/out2.txt b/acceptance tests/out2.txt index 580aa58..fec4b4c 100644 --- a/acceptance tests/out2.txt +++ b/acceptance tests/out2.txt @@ -1 +1 @@ -(-8,3333, x2, -0,6667, 1,6667) +(-8.3333, x2, -0.6667, 1.6667) diff --git a/acceptance tests/out3.txt b/acceptance tests/out3.txt new file mode 100644 index 0000000..2f10760 --- /dev/null +++ b/acceptance tests/out3.txt @@ -0,0 +1 @@ +(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i) diff --git a/acceptance tests/tests.ps1 b/acceptance tests/tests.ps1 index 8459dd3..2cc81e8 100644 --- a/acceptance tests/tests.ps1 +++ b/acceptance tests/tests.ps1 @@ -4,7 +4,7 @@ Describe JavaAcceptanceTests { Start-Process -FilePath "java.exe" -argumentlist '-classpath "..\out\production\project" solver.Main -in in.txt -out out.txt' -NoNewWindow -Wait [String[]]$lines = [System.IO.File]::ReadLines("out.txt") $lines.Count | Should Be 1 - $lines[0] | Should Be "(1,000000, 2,000000, 3,000000)" + $lines[0] | Should Be "(1, 2, 3)" } It 'many solutions' { @@ -12,7 +12,7 @@ Describe JavaAcceptanceTests { Start-Process -FilePath "java.exe" -argumentlist '-classpath "..\out\production\project" solver.Main -in in2.txt -out out2.txt' -NoNewWindow -Wait [String[]]$lines = [System.IO.File]::ReadLines("out2.txt") $lines.Count | Should Be 1 - $lines[0] | Should Be "(-8,3333, x2, -0,6667, 1,6667)" + $lines[0] | Should Be "(-8.3333, x2, -0.6667, 1.6667)" } It 'no solution' { @@ -22,4 +22,12 @@ Describe JavaAcceptanceTests { $lines.Count | Should Be 1 $lines[0] | Should Be "There are no solutions" } + + It 'single solution complex numbers' { + Remove-Item out3.txt -ErrorAction SilentlyContinue + Start-Process -FilePath "java.exe" -argumentlist '-classpath "..\out\production\project" solver.Main -in in3.txt -out out3.txt' -NoNewWindow -Wait + [String[]]$lines = [System.IO.File]::ReadLines("out3.txt") + $lines.Count | Should Be 1 + $lines[0] | Should Be "(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i)" + } } \ No newline at end of file diff --git a/src/solver/Complex.java b/src/solver/Complex.java new file mode 100644 index 0000000..3a13f32 --- /dev/null +++ b/src/solver/Complex.java @@ -0,0 +1,114 @@ +package solver; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; + +public class Complex { + private static final double epsilon = 0.00001; + private double real; + private double imag; + + public Complex(double real, double imag) { + this.real = real; + this.imag = imag; + } + + public Complex() { + this(0.0, 0.0); + } + + @Override + public String toString() { + final DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US); + final DecimalFormat realFormat = new DecimalFormat("0.####", symbols); + final DecimalFormat imagFormat = new DecimalFormat("0.####i", symbols); + if (Math.abs(imag) < epsilon) { + return realFormat.format(real); + } + if (Math.abs(real) < epsilon) { + return imagFormat.format(imag); + } + imagFormat.setPositivePrefix("+"); + return String.format("%s%s",realFormat.format(real), imagFormat.format(imag)); + } + + @Contract(value = "null -> false", pure = true) + @Override + public boolean equals(Object other) { + if (other == null) { + return false; + } + Complex o = (Complex)other; + if (Math.abs(o.imag - imag) < epsilon && Math.abs(o.real - real) < epsilon) { + return true; + } + return false; + } + + @NotNull + @Contract("_, _ -> new") + public static Complex add(@NotNull Complex a, @NotNull Complex b) { + return new Complex(a.real + b.real, a.imag + b.imag); + } + + @NotNull + @Contract("_, _ -> new") + public static Complex multiply(@NotNull Complex a, @NotNull Complex b) { + return new Complex(a.real * b.real -a.imag*b.imag, a.real*b.imag+a.imag*b.real); + } + + @NotNull + @Contract("_, _ -> new") + public static Complex divide(@NotNull Complex a, @NotNull Complex b) { + final Complex bConjugate = b.conjugate(); + final Complex a1 = Complex.multiply(a, bConjugate); + final Complex b1 = Complex.multiply(b, bConjugate); + assert (Math.abs(b1.imag) < 0.00001); + return new Complex(a1.real/b1.real, a1.imag/b1.real); + } + + @NotNull + @Contract("_ -> new") + private String[] parse(@NotNull String s) { + String realString = "0"; + String imagString = "0"; + int i = 1; + for (; i < s.length(); ++i) { + if (s.charAt(i) == '+' || s.charAt(i) == '-') { + realString = s.substring(0, i); + imagString = s.substring(i, s.length()-1); + break; + } + if (s.charAt(i) == 'i') { + imagString = s.substring(0, i); + break; + } + } + if (i == s.length()) { + realString = s; + } + return new String[]{realString, imagString}; + } + + public Complex(String s) { + String[] strs = parse(s); + this.real = Double.parseDouble(strs[0]); + this.imag = Double.parseDouble(strs[1]);; + } + + public double getReal() { + return real; + } + + public double getImag() { + return imag; + } + + public Complex conjugate() { + return new Complex(real, -imag); + } +} diff --git a/src/solver/Solver.java b/src/solver/Solver.java index e922023..6274531 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -10,11 +10,13 @@ public class Solver { private static final double epsilon = 0.0000001; + private static final Complex one = new Complex(1.0, 0.0); + private static final Complex minusOne = new Complex(-1.0, 0.0); private int numberEquations; private int numberVariables; - private double[][] matrix; - private double[] solution; + private Complex[][] matrix; + private Complex[] solution; private String[] solutionGeneral; private int[] solutionIndexes; private boolean verbose; @@ -28,13 +30,18 @@ public Solver(@NotNull Scanner sc, boolean verbose) { numberVariables = sc.nextInt(); final int realNumberEquations = sc.nextInt(); numberEquations = (realNumberEquations < numberVariables) ? numberVariables : realNumberEquations; - matrix = new double[numberEquations][numberVariables +1]; + matrix = new Complex[numberEquations][numberVariables +1]; for (int i = 0; i < realNumberEquations; ++i) { for (int j = 0; j < numberVariables +1; ++j) { - matrix[i][j] = sc.nextDouble(); + matrix[i][j] = new Complex(sc.next()); } } - solution = new double[numberVariables]; + for (int i = realNumberEquations; i < numberEquations; ++i) { + for (int j = 0; j < numberVariables +1; ++j) { + matrix[i][j] = new Complex(); + } + } + solution = new Complex[numberVariables]; solutionGeneral = new String[numberVariables]; solutionIndexes = IntStream.range(0, numberVariables).toArray(); this.verbose = verbose; @@ -48,22 +55,23 @@ public int getSize() { return matrix.length; } - private void multiplyRow(int row, double k) { + private void divideRow(int row, @NotNull Complex k) { if (verbose) { - System.out.printf("%f * R%d -> R%d\n", k, row+1, row+1); + System.out.printf("R%d / %s -> R%d\n", row+1, k.toString(), row+1); } final int n = matrix[row].length; for (int i = 0; i < n; ++i) { - matrix[row][i] *= k; + matrix[row][i] = Complex.divide(matrix[row][i], k); } } - private void addKRow1ToRow2(double k, int row1, int row2) { + private void addKRow1ToRow2(@NotNull Complex k, int row1, int row2) { if (verbose) { - System.out.printf("%f * R%d +R%d -> R%d\n", k, row1+1, row2+1, row2+1); + System.out.printf("%s * R%d +R%d -> R%d\n", k.toString(), row1+1, row2+1, row2+1); } for (int i = 0; i < numberVariables +1; ++i) { - matrix[row2][i] += k*matrix[row1][i]; + final Complex temp = Complex.multiply(k, matrix[row1][i]); + matrix[row2][i] = Complex.add(temp, matrix[row2][i]); } } @@ -72,7 +80,7 @@ private void swapRows(int row1, int row2) { System.out.printf("R%d <-> R%d\n", row1+1, row2+1); } for (int i = 0; i < numberVariables +1; ++i) { - final double temp = matrix[row1][i]; + final Complex temp = matrix[row1][i]; matrix[row1][i] = matrix[row2][i]; matrix[row2][i] = temp; } @@ -85,17 +93,17 @@ public void solve() { System.out.println("Rows manipulation:"); } for (int i = 0; i < numberVariables; ++i) { - if (Math.abs(matrix[i][i]) < epsilon) { + if (Math.abs(matrix[i][i].getReal()) < epsilon && Math.abs(matrix[i][i].getImag()) < epsilon) { boolean notFound = true; for (int j = i+1; j < numberEquations; ++j) { - if (Math.abs(matrix[j][i]) > epsilon) { + if (Math.abs(matrix[j][i].getReal()) > epsilon || Math.abs(matrix[j][i].getImag()) > epsilon) { swapRows(i, j); break; } } if (notFound) { for (int j = i+1; j < numberEquations; ++j) { - if (Math.abs(matrix[i][j]) > epsilon) { + if (Math.abs(matrix[i][j].getReal()) > epsilon || Math.abs(matrix[i][j].getImag()) > epsilon) { swapColumns(i, j); notFound = false; break; @@ -106,7 +114,7 @@ public void solve() { if (notFound) { for (int k = i+1; notFound && k < numberVariables; ++k) { for (int j = i+1; j < numberEquations; ++j) { - if (Math.abs(matrix[j][k]) > epsilon) { + if (Math.abs(matrix[j][k].getReal()) > epsilon || Math.abs(matrix[j][k].getImag()) > epsilon) { swapColumns(k, i); swapRows(j, i); notFound = false; @@ -117,7 +125,7 @@ public void solve() { } if (notFound) { - if (Math.abs(matrix[i][numberEquations]) < epsilon) { + if (Math.abs(matrix[i][numberEquations].getReal()) < epsilon && Math.abs(matrix[i][numberEquations].getImag()) < epsilon) { numberSolutions = NumberSolutions.MANY; continue; } else { @@ -128,45 +136,45 @@ public void solve() { } } - if (Math.abs(matrix[i][i] - 1.0) > epsilon) { - final double k = 1.0 / matrix[i][i]; - multiplyRow(i, k); + if (Math.abs(matrix[i][i].getImag()) > epsilon || Math.abs(matrix[i][i].getReal() - 1.0) > epsilon) { + divideRow(i, matrix[i][i]); } for (int j = i + 1; j < numberEquations && j < numberVariables; ++j) { - final double k = -matrix[j][i]; - if (Math.abs(k) >= epsilon) { + final Complex k = Complex.multiply(minusOne,matrix[j][i]); + if (Math.abs(k.getReal()) >= epsilon || Math.abs(k.getImag()) >= epsilon) { addKRow1ToRow2(k, i, j); } } } for (int i = numberVariables - 1; i >= 0; --i) { for (int j = i - 1; j >= 0; --j) { - final double k = -matrix[j][i]; - if (Math.abs(k) >= epsilon) { + final Complex k = Complex.multiply(minusOne,matrix[j][i]); + if (Math.abs(k.getReal()) >= epsilon || Math.abs(k.getImag()) >= epsilon) { addKRow1ToRow2(k, i, j); } } } for (int i = 0; i < numberEquations && i < numberVariables; ++i) { solution[solutionIndexes[i]] = matrix[i][numberVariables]; - if (Math.abs(matrix[i][i]) < epsilon ) { + if (Math.abs(matrix[i][i].getReal()) < epsilon && Math.abs(matrix[i][i].getImag()) < epsilon) { solutionGeneral[solutionIndexes[i]] = "x" + (solutionIndexes[i]+1); } else { - solutionGeneral[solutionIndexes[i]] = String.format("%.4f", matrix[i][numberVariables]); + solutionGeneral[solutionIndexes[i]] = matrix[i][numberVariables].toString(); for (int j = i + 1; j < numberVariables; ++j) { - if (Math.abs(matrix[i][j]) > epsilon) { + if (Math.abs(matrix[i][j].getReal()) > epsilon || Math.abs(matrix[i][j].getImag()) > epsilon ) { solutionGeneral[solutionIndexes[i]] = solutionGeneral[solutionIndexes[i]] + " - x" + - (solutionIndexes[j]+1) + " * (" + String.format("%.4f",matrix[i][j]) + ")" ; + (solutionIndexes[j]+1) + " * (" + matrix[i][j].toString() + ")" ; } } } } for (int i = numberVariables; i < numberEquations; ++i) { - double sum = 0.0; + Complex sum = new Complex(0.0, 0.0); for (int j = 0; j < numberVariables; ++j) { - sum += solution[solutionIndexes[j]] * matrix[i][solutionIndexes[j]]; + Complex temp = Complex.multiply(solution[solutionIndexes[j]], matrix[i][solutionIndexes[j]]); + sum = Complex.add(sum, temp); } - if (Math.abs(sum - matrix[i][numberVariables]) >= epsilon) { + if (!sum.equals(matrix[i][numberVariables])) { numberSolutions = NumberSolutions.NONE; printSolution(); return; @@ -186,9 +194,9 @@ private void printSolutionInternal(PrintWriter printWriter) { if (numberSolutions == NumberSolutions.NONE) { printWriter.println("There are no solutions"); } else if (numberSolutions == NumberSolutions.ONE){ - printWriter.printf("(%f", solution[0]); + printWriter.printf("(%s", solution[0].toString()); for (int i = 1; i < solution.length; ++i) { - printWriter.printf(", %f", solution[i]); + printWriter.printf(", %s", solution[i].toString()); } printWriter.println(")"); } else { @@ -207,7 +215,7 @@ private void swapColumns(int column1, int column2) { } final int n = matrix.length; for (int i = 0; i < n; ++i) { - final double temp = matrix[i][column1]; + final Complex temp = matrix[i][column1]; matrix[i][column1] = matrix[i][column2]; matrix[i][column2] = temp; } @@ -216,7 +224,7 @@ private void swapColumns(int column1, int column2) { solutionIndexes[column2] = temp; } - public double[] getParticularSolution() { + public Complex[] getParticularSolution() { if (numberSolutions == NumberSolutions.NONE) { return null; } diff --git a/test/ComplexTest.java b/test/ComplexTest.java new file mode 100644 index 0000000..1a4ec37 --- /dev/null +++ b/test/ComplexTest.java @@ -0,0 +1,125 @@ +import org.junit.Assert; +import org.junit.Test; +import solver.Complex; + +public class ComplexTest { + private final static double epsilon = 0.000001; + + @Test + public void equals() { + final Complex a = new Complex(1.0, 2.0); + final Complex b = new Complex(1.0, 2.0); + Assert.assertTrue(a.equals(b)); + } + + @Test + public void toString1() { + final Complex a = new Complex(1.0, 0.0); + Assert.assertEquals("1", a.toString()); + } + + @Test + public void toString2() { + final Complex a = new Complex(0.0, 1.0); + Assert.assertEquals("1i", a.toString()); + } + + @Test + public void toString3() { + final Complex a = new Complex(-2.4, 1.5); + Assert.assertEquals("-2.4+1.5i", a.toString()); + } + + @Test + public void toString4() { + final Complex a = new Complex(2.4, -1.5); + Assert.assertEquals("2.4-1.5i", a.toString()); + } + + @Test + public void toString5() { + final Complex a = new Complex(0, 0); + Assert.assertEquals("0", a.toString()); + } + + @Test + public void constructor() { + final Complex c = new Complex(1.0, 0.0); + Assert.assertEquals(1.0, c.getReal(), epsilon); + Assert.assertEquals(0.0, c.getImag(), epsilon); + } + + @Test + public void defaultConstructor() { + final Complex c = new Complex(); + Assert.assertEquals(0.0, c.getReal(), epsilon); + Assert.assertEquals(0.0, c.getImag(), epsilon); + } + + @Test + public void add() { + final Complex a = new Complex(3.0, -5.0); + final Complex b = new Complex(4.0, 2.0); + final Complex c = Complex.add(a,b); + Assert.assertEquals(7.0, c.getReal(), epsilon); + Assert.assertEquals(-3.0, c.getImag(), epsilon); + } + + @Test + public void multiply() { + final Complex a = new Complex(3.0, 2.0); + final Complex b = new Complex(1.0, 7.0); + final Complex c = Complex.multiply(a,b); + Assert.assertEquals(-11.0, c.getReal(), epsilon); + Assert.assertEquals(23.0, c.getImag(), epsilon); + } + + @Test + public void conjugate() { + final Complex a = new Complex(3.0, 2.0); + final Complex c = a.conjugate(); + Assert.assertEquals(3.0, c.getReal(), epsilon); + Assert.assertEquals(-2.0, c.getImag(), epsilon); + } + + @Test + public void divide() { + final Complex a = new Complex(2.0, 3.0); + final Complex b = new Complex(4.0, -5.0); + final Complex c = Complex.divide(a,b); + Assert.assertEquals(-7.0/41.0, c.getReal(), epsilon); + Assert.assertEquals(22.0/41.0, c.getImag(), epsilon); + } + + @Test + public void parseComplex1() { + final String s = "-1.3"; + final Complex c = new Complex(s); + Assert.assertEquals(-1.3, c.getReal(), epsilon); + Assert.assertEquals(0.0, c.getImag(), epsilon); + } + + @Test + public void parseComplex2() { + final String s = "2.5i"; + final Complex c = new Complex(s); + Assert.assertEquals(0.0, c.getReal(), epsilon); + Assert.assertEquals(2.5, c.getImag(), epsilon); + } + + @Test + public void parseComplex3() { + final String s = "1.3-2.5i"; + final Complex c = new Complex(s); + Assert.assertEquals(1.3, c.getReal(), epsilon); + Assert.assertEquals(-2.5, c.getImag(), epsilon); + } + + @Test + public void parseComplex4() { + final String s = "1"; + final Complex c = new Complex(s); + Assert.assertEquals(1.0, c.getReal(), epsilon); + Assert.assertEquals(0.0, c.getImag(), epsilon); + } +} diff --git a/test/SolverTest.java b/test/SolverTest.java index be9a724..f40ac3c 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -1,5 +1,6 @@ import org.junit.Assert; import org.junit.Test; +import solver.Complex; import solver.NumberSolutions; import solver.Solver; @@ -19,7 +20,7 @@ public void solve1() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{2.0}, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(new Complex[]{new Complex(2.0, 0)}, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } @@ -29,7 +30,7 @@ public void solve2() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{-1.0, 2.0}, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(new Complex[]{new Complex(-1.0,0), new Complex(2.0,0)}, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } @@ -39,7 +40,7 @@ public void solve3() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{0.85714, 0.71429}, p.getParticularSolution(), 0.00001); + Assert.assertArrayEquals(new Complex[]{new Complex(0.85714,0), new Complex(0.71429,0)}, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } @@ -49,17 +50,16 @@ public void solve4() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{1.0, 2.0, 3.0}, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(new Complex[]{new Complex(1.0,0), new Complex(2.0,0),new Complex(3.0,0)}, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } - @Test public void solve5() { final Scanner sc = new Scanner("2 2\n0 1 1\n1 0 1"); final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{1.0, 1.0}, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(new Complex[]{new Complex(1.0,0),new Complex( 1.0,0)}, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } @@ -69,8 +69,8 @@ public void solve6() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{0.0, 1.0}, p.getParticularSolution(), 0.0000001); - Assert.assertArrayEquals(new String[]{"x1", "1,0000"}, p.getGeneralSolution()); + Assert.assertArrayEquals(new Complex[]{new Complex(0.0,0), new Complex(1.0,0)}, p.getParticularSolution()); + Assert.assertArrayEquals(new String[]{"x1", "1"}, p.getGeneralSolution()); } @Test @@ -79,7 +79,7 @@ public void solve7() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); - Assert.assertArrayEquals(null, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(null, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } @@ -89,7 +89,7 @@ public void solve8() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); - Assert.assertArrayEquals(null, p.getParticularSolution(), 0.0000001); + Assert.assertArrayEquals(null, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } @@ -99,8 +99,8 @@ public void solve9() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{9.0, 0.0, 0.0}, p.getParticularSolution(), 0.0000001); - Assert.assertArrayEquals(new String[]{"9,0000 - x2 * (1,0000) - x3 * (2,0000)", "x2", "x3"}, p.getGeneralSolution()); + Assert.assertArrayEquals(new Complex[]{new Complex(9.0,0),new Complex(0,0),new Complex(0,0)}, p.getParticularSolution()); + Assert.assertArrayEquals(new String[]{"9 - x2 * (1) - x3 * (2)", "x2", "x3"}, p.getGeneralSolution()); } @Test @@ -109,8 +109,8 @@ public void solve10() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{-8.3333333, 0.0, -0.6666667, 1.6666667}, p.getParticularSolution(), 0.0000001); - Assert.assertArrayEquals(new String[]{"-8,3333", "x2", "-0,6667", "1,6667"}, p.getGeneralSolution()); + Assert.assertArrayEquals(new Complex[]{new Complex(-8.3333333,0), new Complex(0,0),new Complex(-0.6666667,0),new Complex(1.6666667, 0)}, p.getParticularSolution()); + Assert.assertArrayEquals(new String[]{"-8.3333", "x2", "-0.6667", "1.6667"}, p.getGeneralSolution()); } @Test @@ -119,7 +119,17 @@ public void solve11() { final Solver p = new Solver(sc); p.solve(); Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(new double[]{0.6, 0.0, 0.2, 0.0}, p.getParticularSolution(), 0.0000001); - Assert.assertArrayEquals(new String[]{"0,6000 - x2 * (1,5000) - x4 * (0,1000)", "x2", "0,2000 - x4 * (-0,8000)", "x4"}, p.getGeneralSolution()); + Assert.assertArrayEquals(new Complex[]{new Complex(0.6,0), new Complex(0,0), new Complex(0.2,0), new Complex(0,0)}, p.getParticularSolution()); + Assert.assertArrayEquals(new String[]{"0.6 - x2 * (1.5) - x4 * (0.1)", "x2", "0.2 - x4 * (-0.8)", "x4"}, p.getGeneralSolution()); + } + + @Test + public void solve12() { + final Scanner sc = new Scanner("3 3\n1+2i -1.5-1.1i 2.12 91+5i\n-1+3i 1.2+3.5i -3.3 1+15i\n12.31 1.3-5i 12.3i -78.3i"); + final Solver p = new Solver(sc); + p.solve(); + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); + Assert.assertArrayEquals(new Complex[]{new Complex(6.73335286,-22.99754223), new Complex(-1.7976071,2.08404919), new Complex(15.69938581,7.3960106)}, p.getParticularSolution()); + Assert.assertArrayEquals(null, p.getGeneralSolution()); } } From 4175cf08d9786be06342a9dc66b98338e24fe6c0 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 04:23:02 +0700 Subject: [PATCH 016/108] refactoring --- src/solver/Main.java | 4 ++-- src/solver/Solver.java | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/solver/Main.java b/src/solver/Main.java index d31d1a5..0d30ec4 100644 --- a/src/solver/Main.java +++ b/src/solver/Main.java @@ -5,8 +5,8 @@ public class Main { public static void main(String[] args) { try { - Parameters p = new Parameters(args); - Solver s = new Solver(p.in, p.verbose); + final Parameters p = new Parameters(args); + final Solver s = new Solver(p.in, p.verbose); s.solve(); s.writeSolutionToFile(p.out); } catch (FileNotFoundException e) { diff --git a/src/solver/Solver.java b/src/solver/Solver.java index 6274531..430e442 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -86,7 +86,6 @@ private void swapRows(int row1, int row2) { } } - public void solve() { if (verbose) { System.out.println("Start solving the equation."); From b19895fd50e61cc845483747ff2f7a5055196c24 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 04:30:26 +0700 Subject: [PATCH 017/108] rename a method --- src/solver/Complex.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/solver/Complex.java b/src/solver/Complex.java index 3a13f32..a6618c1 100644 --- a/src/solver/Complex.java +++ b/src/solver/Complex.java @@ -73,7 +73,7 @@ public static Complex divide(@NotNull Complex a, @NotNull Complex b) { @NotNull @Contract("_ -> new") - private String[] parse(@NotNull String s) { + private String[] split(@NotNull String s) { String realString = "0"; String imagString = "0"; int i = 1; @@ -95,7 +95,7 @@ private String[] parse(@NotNull String s) { } public Complex(String s) { - String[] strs = parse(s); + String[] strs = split(s); this.real = Double.parseDouble(strs[0]); this.imag = Double.parseDouble(strs[1]);; } From 0d15262eb208ed078b7ae9e9cf41e58d757e57a1 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 05:03:16 +0700 Subject: [PATCH 018/108] replace epsilon comparations with equals method --- src/solver/Solver.java | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/solver/Solver.java b/src/solver/Solver.java index 430e442..59f439d 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -9,7 +9,7 @@ import java.util.stream.IntStream; public class Solver { - private static final double epsilon = 0.0000001; + private static final Complex zero = new Complex(0.0, 0.0); private static final Complex one = new Complex(1.0, 0.0); private static final Complex minusOne = new Complex(-1.0, 0.0); @@ -92,17 +92,17 @@ public void solve() { System.out.println("Rows manipulation:"); } for (int i = 0; i < numberVariables; ++i) { - if (Math.abs(matrix[i][i].getReal()) < epsilon && Math.abs(matrix[i][i].getImag()) < epsilon) { + if (matrix[i][i].equals(zero)) { boolean notFound = true; for (int j = i+1; j < numberEquations; ++j) { - if (Math.abs(matrix[j][i].getReal()) > epsilon || Math.abs(matrix[j][i].getImag()) > epsilon) { + if (!matrix[j][i].equals(zero)) { swapRows(i, j); break; } } if (notFound) { for (int j = i+1; j < numberEquations; ++j) { - if (Math.abs(matrix[i][j].getReal()) > epsilon || Math.abs(matrix[i][j].getImag()) > epsilon) { + if (!matrix[i][j].equals(zero)) { swapColumns(i, j); notFound = false; break; @@ -113,7 +113,7 @@ public void solve() { if (notFound) { for (int k = i+1; notFound && k < numberVariables; ++k) { for (int j = i+1; j < numberEquations; ++j) { - if (Math.abs(matrix[j][k].getReal()) > epsilon || Math.abs(matrix[j][k].getImag()) > epsilon) { + if (!matrix[j][k].equals(zero)) { swapColumns(k, i); swapRows(j, i); notFound = false; @@ -124,7 +124,7 @@ public void solve() { } if (notFound) { - if (Math.abs(matrix[i][numberEquations].getReal()) < epsilon && Math.abs(matrix[i][numberEquations].getImag()) < epsilon) { + if (matrix[i][numberEquations].equals(zero)) { numberSolutions = NumberSolutions.MANY; continue; } else { @@ -135,12 +135,12 @@ public void solve() { } } - if (Math.abs(matrix[i][i].getImag()) > epsilon || Math.abs(matrix[i][i].getReal() - 1.0) > epsilon) { + if (!matrix[i][i].equals(one)) { divideRow(i, matrix[i][i]); } for (int j = i + 1; j < numberEquations && j < numberVariables; ++j) { final Complex k = Complex.multiply(minusOne,matrix[j][i]); - if (Math.abs(k.getReal()) >= epsilon || Math.abs(k.getImag()) >= epsilon) { + if (!k.equals(zero)) { addKRow1ToRow2(k, i, j); } } @@ -148,19 +148,19 @@ public void solve() { for (int i = numberVariables - 1; i >= 0; --i) { for (int j = i - 1; j >= 0; --j) { final Complex k = Complex.multiply(minusOne,matrix[j][i]); - if (Math.abs(k.getReal()) >= epsilon || Math.abs(k.getImag()) >= epsilon) { + if (!k.equals(zero)) { addKRow1ToRow2(k, i, j); } } } for (int i = 0; i < numberEquations && i < numberVariables; ++i) { solution[solutionIndexes[i]] = matrix[i][numberVariables]; - if (Math.abs(matrix[i][i].getReal()) < epsilon && Math.abs(matrix[i][i].getImag()) < epsilon) { + if (matrix[i][i].equals(zero)) { solutionGeneral[solutionIndexes[i]] = "x" + (solutionIndexes[i]+1); } else { solutionGeneral[solutionIndexes[i]] = matrix[i][numberVariables].toString(); for (int j = i + 1; j < numberVariables; ++j) { - if (Math.abs(matrix[i][j].getReal()) > epsilon || Math.abs(matrix[i][j].getImag()) > epsilon ) { + if (!matrix[i][j].equals(zero)) { solutionGeneral[solutionIndexes[i]] = solutionGeneral[solutionIndexes[i]] + " - x" + (solutionIndexes[j]+1) + " * (" + matrix[i][j].toString() + ")" ; } From 73b0c25d69da8fe86324909b963f30d2d5ee9d22 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 05:14:12 +0700 Subject: [PATCH 019/108] reduced length of very long lines in some tests --- test/SolverTest.java | 75 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/test/SolverTest.java b/test/SolverTest.java index f40ac3c..45ae149 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -11,6 +11,7 @@ public class SolverTest { public void constructor() { final Scanner sc = new Scanner("1 1\n1 2"); final Solver p = new Solver(sc); + Assert.assertEquals(1, p.getSize()); } @@ -19,8 +20,11 @@ public void solve1() { final Scanner sc = new Scanner("1 1\n2 4"); final Solver p = new Solver(sc); p.solve(); + + final Complex[] expectedParticialSolution = new Complex[]{new Complex(2.0, 0)}; + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new Complex[]{new Complex(2.0, 0)}, p.getParticularSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } @@ -29,8 +33,12 @@ public void solve2() { final Scanner sc = new Scanner("2 2\n1 2 3\n4 5 6"); final Solver p = new Solver(sc); p.solve(); + + final Complex[] expectedParticialSolution = new Complex[]{new Complex(-1.0,0), + new Complex(2.0,0)}; + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new Complex[]{new Complex(-1.0,0), new Complex(2.0,0)}, p.getParticularSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } @@ -39,8 +47,12 @@ public void solve3() { final Scanner sc = new Scanner("2 2\n4 5 7\n3 9 9"); final Solver p = new Solver(sc); p.solve(); + + final Complex[] expectedParticialSolution = new Complex[]{new Complex(0.85714,0), + new Complex(0.71429,0)}; + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new Complex[]{new Complex(0.85714,0), new Complex(0.71429,0)}, p.getParticularSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } @@ -49,8 +61,12 @@ public void solve4() { final Scanner sc = new Scanner("3 3\n1 1 2 9\n2 4 -3 1\n3 6 -5 0"); final Solver p = new Solver(sc); p.solve(); + + final Complex[] expectedParticialSolution = new Complex[]{new Complex(1.0,0), + new Complex(2.0,0),new Complex(3.0,0)}; + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new Complex[]{new Complex(1.0,0), new Complex(2.0,0),new Complex(3.0,0)}, p.getParticularSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } @Test @@ -58,8 +74,12 @@ public void solve5() { final Scanner sc = new Scanner("2 2\n0 1 1\n1 0 1"); final Solver p = new Solver(sc); p.solve(); + + final Complex[] expectedParticialSolution = new Complex[]{new Complex(1.0,0), + new Complex( 1.0,0)}; + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new Complex[]{new Complex(1.0,0),new Complex( 1.0,0)}, p.getParticularSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } @@ -68,9 +88,14 @@ public void solve6() { final Scanner sc = new Scanner("2 2\n0 1 1\n0 2 2"); final Solver p = new Solver(sc); p.solve(); + + final Complex[] expectedParticialSolution = new Complex[]{new Complex(0.0,0), + new Complex(1.0,0)}; + final String[] expectedGeneralSolution = new String[]{"x1", "1"}; + Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(new Complex[]{new Complex(0.0,0), new Complex(1.0,0)}, p.getParticularSolution()); - Assert.assertArrayEquals(new String[]{"x1", "1"}, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); + Assert.assertArrayEquals(expectedGeneralSolution, p.getGeneralSolution()); } @Test @@ -78,6 +103,7 @@ public void solve7() { final Scanner sc = new Scanner("2 2\n0 1 1\n0 2 3"); final Solver p = new Solver(sc); p.solve(); + Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); Assert.assertArrayEquals(null, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); @@ -88,6 +114,7 @@ public void solve8() { final Scanner sc = new Scanner("3 4\n0 1 2 9\n0 1 3 1\n1 0 6 0\n2 0 2 0"); final Solver p = new Solver(sc); p.solve(); + Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); Assert.assertArrayEquals(null, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); @@ -98,9 +125,14 @@ public void solve9() { final Scanner sc = new Scanner("3 1\n1 1 2 9"); final Solver p = new Solver(sc); p.solve(); + + final Complex[] expectedParticialSolution = new Complex[]{new Complex(9.0,0), + new Complex(0,0),new Complex(0,0)}; + final String[] expectedGeneralSolution = new String[]{"9 - x2 * (1) - x3 * (2)", "x2", "x3"}; + Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(new Complex[]{new Complex(9.0,0),new Complex(0,0),new Complex(0,0)}, p.getParticularSolution()); - Assert.assertArrayEquals(new String[]{"9 - x2 * (1) - x3 * (2)", "x2", "x3"}, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); + Assert.assertArrayEquals(expectedGeneralSolution, p.getGeneralSolution()); } @Test @@ -108,9 +140,14 @@ public void solve10() { final Scanner sc = new Scanner("4 4\n1 0 0 5 0\n0 0 0 0 0\n0 0 1 4 6\n0 0 5 5 5"); final Solver p = new Solver(sc); p.solve(); + + final Complex[] expectedParticialSolution = new Complex[]{new Complex(-8.3333333,0), + new Complex(0,0),new Complex(-0.6666667,0),new Complex(1.6666667, 0)}; + final String[] expectedGeneralSolution = new String[]{"-8.3333", "x2", "-0.6667", "1.6667"}; + Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(new Complex[]{new Complex(-8.3333333,0), new Complex(0,0),new Complex(-0.6666667,0),new Complex(1.6666667, 0)}, p.getParticularSolution()); - Assert.assertArrayEquals(new String[]{"-8.3333", "x2", "-0.6667", "1.6667"}, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); + Assert.assertArrayEquals(expectedGeneralSolution, p.getGeneralSolution()); } @Test @@ -118,9 +155,15 @@ public void solve11() { final Scanner sc = new Scanner("4 4\n2 3 -1 1 1\n8 12 -9 8 3\n4 6 3 -2 3\n2 3 9 -7 3"); final Solver p = new Solver(sc); p.solve(); + + final Complex[] expectedParticialSolution = new Complex[]{new Complex(0.6,0), + new Complex(0,0), new Complex(0.2,0), new Complex(0,0)}; + final String[] expectedGeneralSolution = new String[]{"0.6 - x2 * (1.5) - x4 * (0.1)", "x2", + "0.2 - x4 * (-0.8)", "x4"}; + Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(new Complex[]{new Complex(0.6,0), new Complex(0,0), new Complex(0.2,0), new Complex(0,0)}, p.getParticularSolution()); - Assert.assertArrayEquals(new String[]{"0.6 - x2 * (1.5) - x4 * (0.1)", "x2", "0.2 - x4 * (-0.8)", "x4"}, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); + Assert.assertArrayEquals(expectedGeneralSolution, p.getGeneralSolution()); } @Test @@ -128,8 +171,12 @@ public void solve12() { final Scanner sc = new Scanner("3 3\n1+2i -1.5-1.1i 2.12 91+5i\n-1+3i 1.2+3.5i -3.3 1+15i\n12.31 1.3-5i 12.3i -78.3i"); final Solver p = new Solver(sc); p.solve(); + + final Complex[] expectedParticialSolution = new Complex[]{new Complex(6.73335286,-22.99754223), + new Complex(-1.7976071,2.08404919), new Complex(15.69938581,7.3960106)}; + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(new Complex[]{new Complex(6.73335286,-22.99754223), new Complex(-1.7976071,2.08404919), new Complex(15.69938581,7.3960106)}, p.getParticularSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } } From 79b15c0baa6c5e789e52ecf50e7a7dbee070a6ef Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 05:17:53 +0700 Subject: [PATCH 020/108] refactoring --- src/solver/Complex.java | 18 +++++++++--------- src/solver/Solver.java | 38 +++++++++++++++++++------------------- test/ComplexTest.java | 10 +++++----- test/SolverTest.java | 39 ++++++++++++++++++++------------------- 4 files changed, 53 insertions(+), 52 deletions(-) diff --git a/src/solver/Complex.java b/src/solver/Complex.java index a6618c1..96ef891 100644 --- a/src/solver/Complex.java +++ b/src/solver/Complex.java @@ -33,7 +33,7 @@ public String toString() { return imagFormat.format(imag); } imagFormat.setPositivePrefix("+"); - return String.format("%s%s",realFormat.format(real), imagFormat.format(imag)); + return String.format("%s%s", realFormat.format(real), imagFormat.format(imag)); } @Contract(value = "null -> false", pure = true) @@ -42,7 +42,7 @@ public boolean equals(Object other) { if (other == null) { return false; } - Complex o = (Complex)other; + Complex o = (Complex) other; if (Math.abs(o.imag - imag) < epsilon && Math.abs(o.real - real) < epsilon) { return true; } @@ -58,7 +58,7 @@ public static Complex add(@NotNull Complex a, @NotNull Complex b) { @NotNull @Contract("_, _ -> new") public static Complex multiply(@NotNull Complex a, @NotNull Complex b) { - return new Complex(a.real * b.real -a.imag*b.imag, a.real*b.imag+a.imag*b.real); + return new Complex(a.real * b.real - a.imag * b.imag, a.real * b.imag + a.imag * b.real); } @NotNull @@ -67,8 +67,8 @@ public static Complex divide(@NotNull Complex a, @NotNull Complex b) { final Complex bConjugate = b.conjugate(); final Complex a1 = Complex.multiply(a, bConjugate); final Complex b1 = Complex.multiply(b, bConjugate); - assert (Math.abs(b1.imag) < 0.00001); - return new Complex(a1.real/b1.real, a1.imag/b1.real); + assert (Math.abs(b1.imag) < epsilon); + return new Complex(a1.real / b1.real, a1.imag / b1.real); } @NotNull @@ -80,7 +80,7 @@ private String[] split(@NotNull String s) { for (; i < s.length(); ++i) { if (s.charAt(i) == '+' || s.charAt(i) == '-') { realString = s.substring(0, i); - imagString = s.substring(i, s.length()-1); + imagString = s.substring(i, s.length() - 1); break; } if (s.charAt(i) == 'i') { @@ -95,9 +95,9 @@ private String[] split(@NotNull String s) { } public Complex(String s) { - String[] strs = split(s); - this.real = Double.parseDouble(strs[0]); - this.imag = Double.parseDouble(strs[1]);; + final String[] strs = split(s); + real = Double.parseDouble(strs[0]); + imag = Double.parseDouble(strs[1]); } public double getReal() { diff --git a/src/solver/Solver.java b/src/solver/Solver.java index 59f439d..f819c00 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -22,7 +22,7 @@ public class Solver { private boolean verbose; private NumberSolutions numberSolutions = NumberSolutions.ONE; - public Solver(Scanner sc){ + public Solver(Scanner sc) { this(sc, false); } @@ -30,14 +30,14 @@ public Solver(@NotNull Scanner sc, boolean verbose) { numberVariables = sc.nextInt(); final int realNumberEquations = sc.nextInt(); numberEquations = (realNumberEquations < numberVariables) ? numberVariables : realNumberEquations; - matrix = new Complex[numberEquations][numberVariables +1]; + matrix = new Complex[numberEquations][numberVariables + 1]; for (int i = 0; i < realNumberEquations; ++i) { - for (int j = 0; j < numberVariables +1; ++j) { + for (int j = 0; j < numberVariables + 1; ++j) { matrix[i][j] = new Complex(sc.next()); } } for (int i = realNumberEquations; i < numberEquations; ++i) { - for (int j = 0; j < numberVariables +1; ++j) { + for (int j = 0; j < numberVariables + 1; ++j) { matrix[i][j] = new Complex(); } } @@ -57,7 +57,7 @@ public int getSize() { private void divideRow(int row, @NotNull Complex k) { if (verbose) { - System.out.printf("R%d / %s -> R%d\n", row+1, k.toString(), row+1); + System.out.printf("R%d / %s -> R%d\n", row + 1, k.toString(), row + 1); } final int n = matrix[row].length; for (int i = 0; i < n; ++i) { @@ -67,9 +67,9 @@ private void divideRow(int row, @NotNull Complex k) { private void addKRow1ToRow2(@NotNull Complex k, int row1, int row2) { if (verbose) { - System.out.printf("%s * R%d +R%d -> R%d\n", k.toString(), row1+1, row2+1, row2+1); + System.out.printf("%s * R%d +R%d -> R%d\n", k.toString(), row1 + 1, row2 + 1, row2 + 1); } - for (int i = 0; i < numberVariables +1; ++i) { + for (int i = 0; i < numberVariables + 1; ++i) { final Complex temp = Complex.multiply(k, matrix[row1][i]); matrix[row2][i] = Complex.add(temp, matrix[row2][i]); } @@ -77,9 +77,9 @@ private void addKRow1ToRow2(@NotNull Complex k, int row1, int row2) { private void swapRows(int row1, int row2) { if (verbose) { - System.out.printf("R%d <-> R%d\n", row1+1, row2+1); + System.out.printf("R%d <-> R%d\n", row1 + 1, row2 + 1); } - for (int i = 0; i < numberVariables +1; ++i) { + for (int i = 0; i < numberVariables + 1; ++i) { final Complex temp = matrix[row1][i]; matrix[row1][i] = matrix[row2][i]; matrix[row2][i] = temp; @@ -94,14 +94,14 @@ public void solve() { for (int i = 0; i < numberVariables; ++i) { if (matrix[i][i].equals(zero)) { boolean notFound = true; - for (int j = i+1; j < numberEquations; ++j) { + for (int j = i + 1; j < numberEquations; ++j) { if (!matrix[j][i].equals(zero)) { swapRows(i, j); break; } } if (notFound) { - for (int j = i+1; j < numberEquations; ++j) { + for (int j = i + 1; j < numberEquations; ++j) { if (!matrix[i][j].equals(zero)) { swapColumns(i, j); notFound = false; @@ -111,8 +111,8 @@ public void solve() { } if (notFound) { - for (int k = i+1; notFound && k < numberVariables; ++k) { - for (int j = i+1; j < numberEquations; ++j) { + for (int k = i + 1; notFound && k < numberVariables; ++k) { + for (int j = i + 1; j < numberEquations; ++j) { if (!matrix[j][k].equals(zero)) { swapColumns(k, i); swapRows(j, i); @@ -139,7 +139,7 @@ public void solve() { divideRow(i, matrix[i][i]); } for (int j = i + 1; j < numberEquations && j < numberVariables; ++j) { - final Complex k = Complex.multiply(minusOne,matrix[j][i]); + final Complex k = Complex.multiply(minusOne, matrix[j][i]); if (!k.equals(zero)) { addKRow1ToRow2(k, i, j); } @@ -147,7 +147,7 @@ public void solve() { } for (int i = numberVariables - 1; i >= 0; --i) { for (int j = i - 1; j >= 0; --j) { - final Complex k = Complex.multiply(minusOne,matrix[j][i]); + final Complex k = Complex.multiply(minusOne, matrix[j][i]); if (!k.equals(zero)) { addKRow1ToRow2(k, i, j); } @@ -156,13 +156,13 @@ public void solve() { for (int i = 0; i < numberEquations && i < numberVariables; ++i) { solution[solutionIndexes[i]] = matrix[i][numberVariables]; if (matrix[i][i].equals(zero)) { - solutionGeneral[solutionIndexes[i]] = "x" + (solutionIndexes[i]+1); + solutionGeneral[solutionIndexes[i]] = "x" + (solutionIndexes[i] + 1); } else { solutionGeneral[solutionIndexes[i]] = matrix[i][numberVariables].toString(); for (int j = i + 1; j < numberVariables; ++j) { if (!matrix[i][j].equals(zero)) { solutionGeneral[solutionIndexes[i]] = solutionGeneral[solutionIndexes[i]] + " - x" + - (solutionIndexes[j]+1) + " * (" + matrix[i][j].toString() + ")" ; + (solutionIndexes[j] + 1) + " * (" + matrix[i][j].toString() + ")"; } } } @@ -192,7 +192,7 @@ private void printSolution() { private void printSolutionInternal(PrintWriter printWriter) { if (numberSolutions == NumberSolutions.NONE) { printWriter.println("There are no solutions"); - } else if (numberSolutions == NumberSolutions.ONE){ + } else if (numberSolutions == NumberSolutions.ONE) { printWriter.printf("(%s", solution[0].toString()); for (int i = 1; i < solution.length; ++i) { printWriter.printf(", %s", solution[i].toString()); @@ -210,7 +210,7 @@ private void printSolutionInternal(PrintWriter printWriter) { private void swapColumns(int column1, int column2) { if (verbose) { - System.out.printf("C%d <-> C%d\n", column1+1, column2+1); + System.out.printf("C%d <-> C%d\n", column1 + 1, column2 + 1); } final int n = matrix.length; for (int i = 0; i < n; ++i) { diff --git a/test/ComplexTest.java b/test/ComplexTest.java index 1a4ec37..587e485 100644 --- a/test/ComplexTest.java +++ b/test/ComplexTest.java @@ -60,7 +60,7 @@ public void defaultConstructor() { public void add() { final Complex a = new Complex(3.0, -5.0); final Complex b = new Complex(4.0, 2.0); - final Complex c = Complex.add(a,b); + final Complex c = Complex.add(a, b); Assert.assertEquals(7.0, c.getReal(), epsilon); Assert.assertEquals(-3.0, c.getImag(), epsilon); } @@ -69,7 +69,7 @@ public void add() { public void multiply() { final Complex a = new Complex(3.0, 2.0); final Complex b = new Complex(1.0, 7.0); - final Complex c = Complex.multiply(a,b); + final Complex c = Complex.multiply(a, b); Assert.assertEquals(-11.0, c.getReal(), epsilon); Assert.assertEquals(23.0, c.getImag(), epsilon); } @@ -86,9 +86,9 @@ public void conjugate() { public void divide() { final Complex a = new Complex(2.0, 3.0); final Complex b = new Complex(4.0, -5.0); - final Complex c = Complex.divide(a,b); - Assert.assertEquals(-7.0/41.0, c.getReal(), epsilon); - Assert.assertEquals(22.0/41.0, c.getImag(), epsilon); + final Complex c = Complex.divide(a, b); + Assert.assertEquals(-7.0 / 41.0, c.getReal(), epsilon); + Assert.assertEquals(22.0 / 41.0, c.getImag(), epsilon); } @Test diff --git a/test/SolverTest.java b/test/SolverTest.java index 45ae149..aa2234f 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -34,8 +34,8 @@ public void solve2() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(-1.0,0), - new Complex(2.0,0)}; + final Complex[] expectedParticialSolution = new Complex[]{new Complex(-1.0, 0), + new Complex(2.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); @@ -48,8 +48,8 @@ public void solve3() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(0.85714,0), - new Complex(0.71429,0)}; + final Complex[] expectedParticialSolution = new Complex[]{new Complex(0.85714, 0), + new Complex(0.71429, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); @@ -62,21 +62,22 @@ public void solve4() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(1.0,0), - new Complex(2.0,0),new Complex(3.0,0)}; + final Complex[] expectedParticialSolution = new Complex[]{new Complex(1.0, 0), + new Complex(2.0, 0), new Complex(3.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); Assert.assertArrayEquals(null, p.getGeneralSolution()); } + @Test public void solve5() { final Scanner sc = new Scanner("2 2\n0 1 1\n1 0 1"); final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(1.0,0), - new Complex( 1.0,0)}; + final Complex[] expectedParticialSolution = new Complex[]{new Complex(1.0, 0), + new Complex(1.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); @@ -89,8 +90,8 @@ public void solve6() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(0.0,0), - new Complex(1.0,0)}; + final Complex[] expectedParticialSolution = new Complex[]{new Complex(0.0, 0), + new Complex(1.0, 0)}; final String[] expectedGeneralSolution = new String[]{"x1", "1"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); @@ -126,8 +127,8 @@ public void solve9() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(9.0,0), - new Complex(0,0),new Complex(0,0)}; + final Complex[] expectedParticialSolution = new Complex[]{new Complex(9.0, 0), + new Complex(0, 0), new Complex(0, 0)}; final String[] expectedGeneralSolution = new String[]{"9 - x2 * (1) - x3 * (2)", "x2", "x3"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); @@ -141,9 +142,9 @@ public void solve10() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(-8.3333333,0), - new Complex(0,0),new Complex(-0.6666667,0),new Complex(1.6666667, 0)}; - final String[] expectedGeneralSolution = new String[]{"-8.3333", "x2", "-0.6667", "1.6667"}; + final Complex[] expectedParticialSolution = new Complex[]{new Complex(-8.3333333, 0), + new Complex(0, 0), new Complex(-0.6666667, 0), new Complex(1.6666667, 0)}; + final String[] expectedGeneralSolution = new String[]{"-8.3333", "x2", "-0.6667", "1.6667"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); @@ -156,8 +157,8 @@ public void solve11() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(0.6,0), - new Complex(0,0), new Complex(0.2,0), new Complex(0,0)}; + final Complex[] expectedParticialSolution = new Complex[]{new Complex(0.6, 0), + new Complex(0, 0), new Complex(0.2, 0), new Complex(0, 0)}; final String[] expectedGeneralSolution = new String[]{"0.6 - x2 * (1.5) - x4 * (0.1)", "x2", "0.2 - x4 * (-0.8)", "x4"}; @@ -172,8 +173,8 @@ public void solve12() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(6.73335286,-22.99754223), - new Complex(-1.7976071,2.08404919), new Complex(15.69938581,7.3960106)}; + final Complex[] expectedParticialSolution = new Complex[]{new Complex(6.73335286, -22.99754223), + new Complex(-1.7976071, 2.08404919), new Complex(15.69938581, 7.3960106)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); From 88b515afc1a37f6a3cc1681e616295897a9f6b03 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 05:35:01 +0700 Subject: [PATCH 021/108] reduced length of very long lines in some tests --- test/SolverTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/SolverTest.java b/test/SolverTest.java index aa2234f..930e7a0 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -169,7 +169,8 @@ public void solve11() { @Test public void solve12() { - final Scanner sc = new Scanner("3 3\n1+2i -1.5-1.1i 2.12 91+5i\n-1+3i 1.2+3.5i -3.3 1+15i\n12.31 1.3-5i 12.3i -78.3i"); + final String source = "3 3\n1+2i -1.5-1.1i 2.12 91+5i\n-1+3i 1.2+3.5i -3.3 1+15i\n12.31 1.3-5i 12.3i -78.3i"; + final Scanner sc = new Scanner(source); final Solver p = new Solver(sc); p.solve(); From b2ae010cc4722771c20a8bd1468802482b771c82 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 05:48:38 +0700 Subject: [PATCH 022/108] fix Complex::equals method --- src/solver/Complex.java | 5 +++++ test/ComplexTest.java | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/solver/Complex.java b/src/solver/Complex.java index 96ef891..385a4dc 100644 --- a/src/solver/Complex.java +++ b/src/solver/Complex.java @@ -42,6 +42,11 @@ public boolean equals(Object other) { if (other == null) { return false; } + + if (!(other instanceof Complex)) { + return false; + } + Complex o = (Complex) other; if (Math.abs(o.imag - imag) < epsilon && Math.abs(o.real - real) < epsilon) { return true; diff --git a/test/ComplexTest.java b/test/ComplexTest.java index 587e485..499182d 100644 --- a/test/ComplexTest.java +++ b/test/ComplexTest.java @@ -6,12 +6,19 @@ public class ComplexTest { private final static double epsilon = 0.000001; @Test - public void equals() { + public void equals1() { final Complex a = new Complex(1.0, 2.0); final Complex b = new Complex(1.0, 2.0); Assert.assertTrue(a.equals(b)); } + @Test + public void equals2() { + final Complex a = new Complex(1.0, 2.0); + Assert.assertFalse(a.equals("Hello")); + } + + @Test public void toString1() { final Complex a = new Complex(1.0, 0.0); From ad30134173c48cc33b87b6466c1070fa1e437a11 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 06:10:25 +0700 Subject: [PATCH 023/108] refactor Solver::solve method --- src/solver/Solver.java | 66 +++++++++++++++++++++++++----------------- test/SolverTest.java | 48 +++++++++++++++--------------- 2 files changed, 64 insertions(+), 50 deletions(-) diff --git a/src/solver/Solver.java b/src/solver/Solver.java index f819c00..a4af1e9 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -16,7 +16,7 @@ public class Solver { private int numberEquations; private int numberVariables; private Complex[][] matrix; - private Complex[] solution; + private Complex[] solutionParticular; private String[] solutionGeneral; private int[] solutionIndexes; private boolean verbose; @@ -41,7 +41,7 @@ public Solver(@NotNull Scanner sc, boolean verbose) { matrix[i][j] = new Complex(); } } - solution = new Complex[numberVariables]; + solutionParticular = new Complex[numberVariables]; solutionGeneral = new String[numberVariables]; solutionIndexes = IntStream.range(0, numberVariables).toArray(); this.verbose = verbose; @@ -86,11 +86,7 @@ private void swapRows(int row1, int row2) { } } - public void solve() { - if (verbose) { - System.out.println("Start solving the equation."); - System.out.println("Rows manipulation:"); - } + private void gausFirstStep() { for (int i = 0; i < numberVariables; ++i) { if (matrix[i][i].equals(zero)) { boolean notFound = true; @@ -145,6 +141,9 @@ public void solve() { } } } + } + + private void gausSecondStep() { for (int i = numberVariables - 1; i >= 0; --i) { for (int j = i - 1; j >= 0; --j) { final Complex k = Complex.multiply(minusOne, matrix[j][i]); @@ -153,8 +152,11 @@ public void solve() { } } } + } + + private void generateSolutions() { for (int i = 0; i < numberEquations && i < numberVariables; ++i) { - solution[solutionIndexes[i]] = matrix[i][numberVariables]; + solutionParticular[solutionIndexes[i]] = matrix[i][numberVariables]; if (matrix[i][i].equals(zero)) { solutionGeneral[solutionIndexes[i]] = "x" + (solutionIndexes[i] + 1); } else { @@ -167,19 +169,31 @@ public void solve() { } } } + } + + private void checkThatSolutionIsSane() { for (int i = numberVariables; i < numberEquations; ++i) { Complex sum = new Complex(0.0, 0.0); for (int j = 0; j < numberVariables; ++j) { - Complex temp = Complex.multiply(solution[solutionIndexes[j]], matrix[i][solutionIndexes[j]]); + Complex temp = Complex.multiply(solutionParticular[solutionIndexes[j]], matrix[i][solutionIndexes[j]]); sum = Complex.add(sum, temp); } if (!sum.equals(matrix[i][numberVariables])) { numberSolutions = NumberSolutions.NONE; - printSolution(); return; } } + } + public void solve() { + if (verbose) { + System.out.println("Start solving the equation."); + System.out.println("Rows manipulation:"); + } + gausFirstStep(); + gausSecondStep(); + generateSolutions(); + checkThatSolutionIsSane(); printSolution(); } @@ -193,14 +207,14 @@ private void printSolutionInternal(PrintWriter printWriter) { if (numberSolutions == NumberSolutions.NONE) { printWriter.println("There are no solutions"); } else if (numberSolutions == NumberSolutions.ONE) { - printWriter.printf("(%s", solution[0].toString()); - for (int i = 1; i < solution.length; ++i) { - printWriter.printf(", %s", solution[i].toString()); + printWriter.printf("(%s", solutionParticular[0].toString()); + for (int i = 1; i < solutionParticular.length; ++i) { + printWriter.printf(", %s", solutionParticular[i].toString()); } printWriter.println(")"); } else { printWriter.printf("(%s", solutionGeneral[0]); - for (int i = 1; i < solution.length; ++i) { + for (int i = 1; i < solutionParticular.length; ++i) { printWriter.printf(", %s", solutionGeneral[i]); } printWriter.println(")"); @@ -223,17 +237,6 @@ private void swapColumns(int column1, int column2) { solutionIndexes[column2] = temp; } - public Complex[] getParticularSolution() { - if (numberSolutions == NumberSolutions.NONE) { - return null; - } - return solution; - } - - public NumberSolutions getNumberSolutions() { - return numberSolutions; - } - public void writeSolutionToFile(String out) throws FileNotFoundException { File file = new File(out); PrintWriter printWriter = new PrintWriter(file); @@ -244,7 +247,18 @@ public void writeSolutionToFile(String out) throws FileNotFoundException { } } - public String[] getGeneralSolution() { + public Complex[] getSolutionParticular() { + if (numberSolutions == NumberSolutions.NONE) { + return null; + } + return solutionParticular; + } + + public NumberSolutions getNumberSolutions() { + return numberSolutions; + } + + public String[] getSolutionGeneral() { if (numberSolutions != NumberSolutions.MANY) { return null; } diff --git a/test/SolverTest.java b/test/SolverTest.java index 930e7a0..0d29672 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -24,8 +24,8 @@ public void solve1() { final Complex[] expectedParticialSolution = new Complex[]{new Complex(2.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); - Assert.assertArrayEquals(null, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @Test @@ -38,8 +38,8 @@ public void solve2() { new Complex(2.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); - Assert.assertArrayEquals(null, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @Test @@ -52,8 +52,8 @@ public void solve3() { new Complex(0.71429, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); - Assert.assertArrayEquals(null, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @Test @@ -66,8 +66,8 @@ public void solve4() { new Complex(2.0, 0), new Complex(3.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); - Assert.assertArrayEquals(null, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @Test @@ -80,8 +80,8 @@ public void solve5() { new Complex(1.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); - Assert.assertArrayEquals(null, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @Test @@ -95,8 +95,8 @@ public void solve6() { final String[] expectedGeneralSolution = new String[]{"x1", "1"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); - Assert.assertArrayEquals(expectedGeneralSolution, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedGeneralSolution, p.getSolutionGeneral()); } @Test @@ -106,8 +106,8 @@ public void solve7() { p.solve(); Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); - Assert.assertArrayEquals(null, p.getParticularSolution()); - Assert.assertArrayEquals(null, p.getGeneralSolution()); + Assert.assertArrayEquals(null, p.getSolutionParticular()); + Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @Test @@ -117,8 +117,8 @@ public void solve8() { p.solve(); Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); - Assert.assertArrayEquals(null, p.getParticularSolution()); - Assert.assertArrayEquals(null, p.getGeneralSolution()); + Assert.assertArrayEquals(null, p.getSolutionParticular()); + Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @Test @@ -132,8 +132,8 @@ public void solve9() { final String[] expectedGeneralSolution = new String[]{"9 - x2 * (1) - x3 * (2)", "x2", "x3"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); - Assert.assertArrayEquals(expectedGeneralSolution, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedGeneralSolution, p.getSolutionGeneral()); } @Test @@ -147,8 +147,8 @@ public void solve10() { final String[] expectedGeneralSolution = new String[]{"-8.3333", "x2", "-0.6667", "1.6667"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); - Assert.assertArrayEquals(expectedGeneralSolution, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedGeneralSolution, p.getSolutionGeneral()); } @Test @@ -163,8 +163,8 @@ public void solve11() { "0.2 - x4 * (-0.8)", "x4"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); - Assert.assertArrayEquals(expectedGeneralSolution, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedGeneralSolution, p.getSolutionGeneral()); } @Test @@ -178,7 +178,7 @@ public void solve12() { new Complex(-1.7976071, 2.08404919), new Complex(15.69938581, 7.3960106)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getParticularSolution()); - Assert.assertArrayEquals(null, p.getGeneralSolution()); + Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(null, p.getSolutionGeneral()); } } From e56b94d76fadd22672798526c80fef8b64116c71 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 06:16:49 +0700 Subject: [PATCH 024/108] fix solution after refactoring --- src/solver/Solver.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/solver/Solver.java b/src/solver/Solver.java index a4af1e9..1e02ab3 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -125,7 +125,6 @@ private void gausFirstStep() { continue; } else { numberSolutions = NumberSolutions.NONE; - printSolution(); return; } } @@ -191,9 +190,11 @@ public void solve() { System.out.println("Rows manipulation:"); } gausFirstStep(); - gausSecondStep(); - generateSolutions(); - checkThatSolutionIsSane(); + if (numberSolutions != NumberSolutions.NONE) { + gausSecondStep(); + generateSolutions(); + checkThatSolutionIsSane(); + } printSolution(); } From fa90fca766132447f4039a2fc11757cfe6e47020 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 06:27:25 +0700 Subject: [PATCH 025/108] refactor printSolutionInternal method --- src/solver/Solver.java | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/solver/Solver.java b/src/solver/Solver.java index 1e02ab3..4bc548f 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -205,20 +205,27 @@ private void printSolution() { } private void printSolutionInternal(PrintWriter printWriter) { - if (numberSolutions == NumberSolutions.NONE) { - printWriter.println("There are no solutions"); - } else if (numberSolutions == NumberSolutions.ONE) { - printWriter.printf("(%s", solutionParticular[0].toString()); - for (int i = 1; i < solutionParticular.length; ++i) { - printWriter.printf(", %s", solutionParticular[i].toString()); - } - printWriter.println(")"); - } else { - printWriter.printf("(%s", solutionGeneral[0]); - for (int i = 1; i < solutionParticular.length; ++i) { - printWriter.printf(", %s", solutionGeneral[i]); - } - printWriter.println(")"); + switch(numberSolutions) { + case NONE: + printWriter.println("There are no solutions"); + break; + case ONE: + printWriter.printf("(%s", solutionParticular[0].toString()); + for (int i = 1; i < solutionParticular.length; ++i) { + printWriter.printf(", %s", solutionParticular[i].toString()); + } + printWriter.println(")"); + break; + case MANY: + printWriter.printf("(%s", solutionGeneral[0]); + for (int i = 1; i < solutionParticular.length; ++i) { + printWriter.printf(", %s", solutionGeneral[i]); + } + printWriter.println(")"); + break; + default: + assert (false); + break; } printWriter.flush(); } From 2eb69b8476ec0096a8fac755332744d7eb489bf5 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 06:32:07 +0700 Subject: [PATCH 026/108] add final to some variables --- src/solver/Solver.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/solver/Solver.java b/src/solver/Solver.java index 4bc548f..a877000 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -246,8 +246,8 @@ private void swapColumns(int column1, int column2) { } public void writeSolutionToFile(String out) throws FileNotFoundException { - File file = new File(out); - PrintWriter printWriter = new PrintWriter(file); + final File file = new File(out); + final PrintWriter printWriter = new PrintWriter(file); printSolutionInternal(printWriter); printWriter.close(); if (verbose) { From 1a83bc3a428925fe921cfbed19da6b5a5a51501e Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 07:56:59 +0700 Subject: [PATCH 027/108] acceptance tests checks the program stdout too --- acceptance tests/out4.txt | 1 + acceptance tests/stdout.txt | Bin 0 -> 460 bytes acceptance tests/stdout1.txt | Bin 0 -> 508 bytes acceptance tests/stdout2.txt | Bin 0 -> 446 bytes acceptance tests/stdout3.txt | Bin 0 -> 710 bytes acceptance tests/stdout4.txt | 0 acceptance tests/tests.ps1 | 77 +++++++++++++++++++++++++++++------ 7 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 acceptance tests/out4.txt create mode 100644 acceptance tests/stdout.txt create mode 100644 acceptance tests/stdout1.txt create mode 100644 acceptance tests/stdout2.txt create mode 100644 acceptance tests/stdout3.txt create mode 100644 acceptance tests/stdout4.txt diff --git a/acceptance tests/out4.txt b/acceptance tests/out4.txt new file mode 100644 index 0000000..fcb8c89 --- /dev/null +++ b/acceptance tests/out4.txt @@ -0,0 +1 @@ +(1, 2, 3) diff --git a/acceptance tests/stdout.txt b/acceptance tests/stdout.txt new file mode 100644 index 0000000000000000000000000000000000000000..fa91df995e062c04430baafa347883f23629b07a GIT binary patch literal 460 zcmaKpNe;p=3`PGMi92M;RG^L6u;38w36Lm*RGI>zaC+c7gG9x!u#?!&W1f!!7HgcT z6)rHS(Bgm^JH9RUD0!AR;Y!NVW9XZrj~;T~Z;Vkm(pS^hkgDFerQ;H0WJZ)6DfO7A zSQ4z9Een+9t4oO`QaaR>$Qk8-2JuRrZyCfU84}Dn$->=yC%%RbR^N-zzdDvGT}tMQ y9j9R~v3V+X^+^r5nF+bfX^o+aEx5~;+uzV*xow3lw_LeDG2FFfrxtgL{KpH&PBz*A literal 0 HcmV?d00001 diff --git a/acceptance tests/stdout1.txt b/acceptance tests/stdout1.txt new file mode 100644 index 0000000000000000000000000000000000000000..f1a443aa674922958a1a68b8f73170c5a5ed914e GIT binary patch literal 508 zcmZ{hO%8%U429p?#5=IofPzsIW8829@B${{PlBK@pr=<~J76Hh#mqqa^-VkP^NwL~ zK*8NXi5w|vT#@0-e}fAWo(UePNEv2w<~)osLd5SUYaHB|%b2^9N;}-9;e0Y%xY+TG zu+V6TZZvG7kw$0aR$Og`uN5vC2NTth+9|by4iz+%#QK!fwOaOeSMRZu@S-)OY)rbD zb7r4Ct*{lf;PI3!MFeDl_)>gPwPlgE7dn$(em VQSL-fQmxDBjNt?x_ZOG=_XSlhKj#1d literal 0 HcmV?d00001 diff --git a/acceptance tests/stdout2.txt b/acceptance tests/stdout2.txt new file mode 100644 index 0000000000000000000000000000000000000000..f49821c7fc91d606fe73932bc0563214b907c6e4 GIT binary patch literal 446 zcmYjOTMmLS5S(ul@6b}vDU3oH}-r~ikd#<78S=TkE6~~ZJvB<7_0CaOS;ui#YUGw zrwmoto%P(_s|cAzzjeZTYf;wehLdM+HJ^ufTQNgBrtTiLfhlu(z}JOY?3u9ve2)EM H+5G$h>H<-o literal 0 HcmV?d00001 diff --git a/acceptance tests/stdout4.txt b/acceptance tests/stdout4.txt new file mode 100644 index 0000000..e69de29 diff --git a/acceptance tests/tests.ps1 b/acceptance tests/tests.ps1 index 2cc81e8..98373b0 100644 --- a/acceptance tests/tests.ps1 +++ b/acceptance tests/tests.ps1 @@ -1,33 +1,86 @@ Describe JavaAcceptanceTests { It 'single solution' { Remove-Item out.txt -ErrorAction SilentlyContinue - Start-Process -FilePath "java.exe" -argumentlist '-classpath "..\out\production\project" solver.Main -in in.txt -out out.txt' -NoNewWindow -Wait - [String[]]$lines = [System.IO.File]::ReadLines("out.txt") + Remove-Item stdout.txt -ErrorAction SilentlyContinue + + java -classpath "..\out\production\project" solver.Main -in in.txt -out out.txt -verbose > stdout.txt + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout.txt") + [String[]]$expectedOutput = [String[]]("Start solving the equation.", + "Rows manipulation:", "-2 * R1 +R2 -> R2", "-3 * R1 +R3 -> R3", + "R2 / 2 -> R2", "-3 * R2 +R3 -> R3", "R3 / -0.5 -> R3", + "3.5 * R3 +R2 -> R2", "-2 * R3 +R1 -> R1", "-1 * R2 +R1 -> R1", + "(1, 2, 3)", "Saved to file out.txt") + $areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + $areEqual | Should Be $true + } + + It 'no solution' { + Remove-Item out1.txt -ErrorAction SilentlyContinue + Remove-Item stdout1.txt -ErrorAction SilentlyContinue + + java -classpath "..\out\production\project" solver.Main -in in1.txt -out out1.txt -verbose > stdout1.txt + + [String[]]$lines = [System.IO.File]::ReadLines("out1.txt") $lines.Count | Should Be 1 - $lines[0] | Should Be "(1, 2, 3)" + $lines[0] | Should Be "There are no solutions" + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout1.txt") + [String[]]$expectedOutput = [String[]]("Start solving the equation.", + "Rows manipulation:", "R1 <-> R3", "C1 <-> C3", "R1 / 6 -> R1", + "-3 * R1 +R2 -> R2", "-2 * R1 +R3 -> R3", "-1 * R2 +R3 -> R3", + "R3 / 0.1667 -> R3", "0.5 * R3 +R2 -> R2", "-0.1667 * R3 +R1 -> R1", + "There are no solutions", "Saved to file out1.txt") + $areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + $areEqual | Should Be $true } It 'many solutions' { Remove-Item out2.txt -ErrorAction SilentlyContinue - Start-Process -FilePath "java.exe" -argumentlist '-classpath "..\out\production\project" solver.Main -in in2.txt -out out2.txt' -NoNewWindow -Wait + Remove-Item stdout2.txt -ErrorAction SilentlyContinue + + java -classpath "..\out\production\project" solver.Main -in in2.txt -out out2.txt -verbose > stdout2.txt + [String[]]$lines = [System.IO.File]::ReadLines("out2.txt") $lines.Count | Should Be 1 $lines[0] | Should Be "(-8.3333, x2, -0.6667, 1.6667)" - } - It 'no solution' { - Remove-Item out1.txt -ErrorAction SilentlyContinue - Start-Process -FilePath "java.exe" -argumentlist '-classpath "..\out\production\project" solver.Main -in in1.txt -out out1.txt' -NoNewWindow -Wait - [String[]]$lines = [System.IO.File]::ReadLines("out1.txt") - $lines.Count | Should Be 1 - $lines[0] | Should Be "There are no solutions" + [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout2.txt") + [String[]]$expectedOutput = [String[]]("Start solving the equation.", + "Rows manipulation:", "C3 <-> C2", "R3 <-> R2", "-5 * R2 +R4 -> R4", + "C4 <-> C3", "R4 <-> R3", "R3 / -15 -> R3", "-4 * R3 +R2 -> R2", + "-5 * R3 +R1 -> R1", "(-8.3333, x2, -0.6667, 1.6667)","Saved to file out2.txt") + $areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + $areEqual | Should Be $true } It 'single solution complex numbers' { Remove-Item out3.txt -ErrorAction SilentlyContinue - Start-Process -FilePath "java.exe" -argumentlist '-classpath "..\out\production\project" solver.Main -in in3.txt -out out3.txt' -NoNewWindow -Wait + Remove-Item stdout3.txt -ErrorAction SilentlyContinue + + java -classpath "..\out\production\project" solver.Main -in in3.txt -out out3.txt -verbose > stdout3.txt + [String[]]$lines = [System.IO.File]::ReadLines("out3.txt") $lines.Count | Should Be 1 $lines[0] | Should Be "(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i)" + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout3.txt") + [String[]]$expectedOutput = [String[]]("Start solving the equation.", + "Rows manipulation:", "R1 / 1+2i -> R1", "1-3i * R1 +R2 -> R2", "-12.31 * R1 +R3 -> R3", + "R2 / 1.6+6.1i -> R2", "-10.4094+9.6778i * R2 +R3 -> R3", "R3 / -6.7848+9.7158i -> R3", + "0.5432-0.746i * R3 +R2 -> R2", "-0.424+0.848i * R3 +R1 -> R1", "0.74-0.38i * R2 +R1 -> R1", + "(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i)", "Saved to file out3.txt") + $areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + $areEqual | Should Be $true + } + + It 'no output without -verbose' { + Remove-Item out4.txt -ErrorAction SilentlyContinue + Remove-Item stdout4.txt -ErrorAction SilentlyContinue + + java -classpath "..\out\production\project" solver.Main -in in.txt -out out4.txt > stdout4.txt + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout4.txt") + $stdoutLines.Count | Should Be 0 } } \ No newline at end of file From f76be5fe64e5e4146034ede654b336b460b1fc50 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 16:01:18 +0700 Subject: [PATCH 028/108] refactoring --- src/solver/Complex.java | 2 +- src/solver/Solver.java | 7 +++++-- test/SolverTest.java | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/solver/Complex.java b/src/solver/Complex.java index 385a4dc..8afb20c 100644 --- a/src/solver/Complex.java +++ b/src/solver/Complex.java @@ -99,7 +99,7 @@ private String[] split(@NotNull String s) { return new String[]{realString, imagString}; } - public Complex(String s) { + public Complex(@NotNull String s) { final String[] strs = split(s); real = Double.parseDouble(strs[0]); imag = Double.parseDouble(strs[1]); diff --git a/src/solver/Solver.java b/src/solver/Solver.java index a877000..a686865 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -22,7 +22,7 @@ public class Solver { private boolean verbose; private NumberSolutions numberSolutions = NumberSolutions.ONE; - public Solver(Scanner sc) { + public Solver(@NotNull Scanner sc) { this(sc, false); } @@ -161,7 +161,10 @@ private void generateSolutions() { } else { solutionGeneral[solutionIndexes[i]] = matrix[i][numberVariables].toString(); for (int j = i + 1; j < numberVariables; ++j) { - if (!matrix[i][j].equals(zero)) { + if (matrix[i][j].equals(one)) { + solutionGeneral[solutionIndexes[i]] = solutionGeneral[solutionIndexes[i]] + " - x" + + (solutionIndexes[j] + 1); + } else if (!matrix[i][j].equals(zero)) { solutionGeneral[solutionIndexes[i]] = solutionGeneral[solutionIndexes[i]] + " - x" + (solutionIndexes[j] + 1) + " * (" + matrix[i][j].toString() + ")"; } diff --git a/test/SolverTest.java b/test/SolverTest.java index 0d29672..a8c4513 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -129,7 +129,7 @@ public void solve9() { final Complex[] expectedParticialSolution = new Complex[]{new Complex(9.0, 0), new Complex(0, 0), new Complex(0, 0)}; - final String[] expectedGeneralSolution = new String[]{"9 - x2 * (1) - x3 * (2)", "x2", "x3"}; + final String[] expectedGeneralSolution = new String[]{"9 - x2 - x3 * (2)", "x2", "x3"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); From b60afc480de1df13975da9996c0ac875f28e8910 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 16:19:01 +0700 Subject: [PATCH 029/108] refactoring --- src/solver/Complex.java | 2 +- src/solver/Main.java | 4 +--- src/solver/Solver.java | 4 ++-- test/ComplexTest.java | 13 ++++++++++++- test/SolverTest.java | 14 +++++++++++++- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/solver/Complex.java b/src/solver/Complex.java index 8afb20c..81a413d 100644 --- a/src/solver/Complex.java +++ b/src/solver/Complex.java @@ -99,7 +99,7 @@ private String[] split(@NotNull String s) { return new String[]{realString, imagString}; } - public Complex(@NotNull String s) { + public Complex(@NotNull String s) throws NumberFormatException { final String[] strs = split(s); real = Double.parseDouble(strs[0]); imag = Double.parseDouble(strs[1]); diff --git a/src/solver/Main.java b/src/solver/Main.java index 0d30ec4..310da85 100644 --- a/src/solver/Main.java +++ b/src/solver/Main.java @@ -1,7 +1,5 @@ package solver; -import java.io.FileNotFoundException; - public class Main { public static void main(String[] args) { try { @@ -9,7 +7,7 @@ public static void main(String[] args) { final Solver s = new Solver(p.in, p.verbose); s.solve(); s.writeSolutionToFile(p.out); - } catch (FileNotFoundException e) { + } catch (Exception e) { System.out.printf("An exception occurs %s", e.getMessage()); } } diff --git a/src/solver/Solver.java b/src/solver/Solver.java index a686865..da4953e 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -22,11 +22,11 @@ public class Solver { private boolean verbose; private NumberSolutions numberSolutions = NumberSolutions.ONE; - public Solver(@NotNull Scanner sc) { + public Solver(@NotNull Scanner sc) throws NumberFormatException { this(sc, false); } - public Solver(@NotNull Scanner sc, boolean verbose) { + public Solver(@NotNull Scanner sc, boolean verbose) throws NumberFormatException { numberVariables = sc.nextInt(); final int realNumberEquations = sc.nextInt(); numberEquations = (realNumberEquations < numberVariables) ? numberVariables : realNumberEquations; diff --git a/test/ComplexTest.java b/test/ComplexTest.java index 499182d..50a159e 100644 --- a/test/ComplexTest.java +++ b/test/ComplexTest.java @@ -50,12 +50,23 @@ public void toString5() { } @Test - public void constructor() { + public void constructor1() { final Complex c = new Complex(1.0, 0.0); Assert.assertEquals(1.0, c.getReal(), epsilon); Assert.assertEquals(0.0, c.getImag(), epsilon); } + @Test + public void constructor2() { + boolean ok = false; + try { + final Complex c = new Complex("gbc"); + } catch (Exception e) { + ok = true; + } + Assert.assertTrue(ok); + } + @Test public void defaultConstructor() { final Complex c = new Complex(); diff --git a/test/SolverTest.java b/test/SolverTest.java index a8c4513..061a5d7 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -8,13 +8,25 @@ public class SolverTest { @Test - public void constructor() { + public void constructor1() { final Scanner sc = new Scanner("1 1\n1 2"); final Solver p = new Solver(sc); Assert.assertEquals(1, p.getSize()); } + @Test + public void constructor2() { + boolean ok = false; + try { + final Scanner sc = new Scanner("1 1\nab 2"); + final Solver p = new Solver(sc); + } catch (Exception e) { + ok = true; + } + Assert.assertTrue(ok); + } + @Test public void solve1() { final Scanner sc = new Scanner("1 1\n2 4"); From be69c6010f88cc6d1029e2ce7b36533b124eec3b Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 16:35:42 +0700 Subject: [PATCH 030/108] add explicit type for 'areEqual' variable --- acceptance tests/tests.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acceptance tests/tests.ps1 b/acceptance tests/tests.ps1 index 98373b0..d254417 100644 --- a/acceptance tests/tests.ps1 +++ b/acceptance tests/tests.ps1 @@ -11,7 +11,7 @@ Describe JavaAcceptanceTests { "R2 / 2 -> R2", "-3 * R2 +R3 -> R3", "R3 / -0.5 -> R3", "3.5 * R3 +R2 -> R2", "-2 * R3 +R1 -> R1", "-1 * R2 +R1 -> R1", "(1, 2, 3)", "Saved to file out.txt") - $areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 $areEqual | Should Be $true } @@ -31,7 +31,7 @@ Describe JavaAcceptanceTests { "-3 * R1 +R2 -> R2", "-2 * R1 +R3 -> R3", "-1 * R2 +R3 -> R3", "R3 / 0.1667 -> R3", "0.5 * R3 +R2 -> R2", "-0.1667 * R3 +R1 -> R1", "There are no solutions", "Saved to file out1.txt") - $areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 $areEqual | Should Be $true } @@ -50,7 +50,7 @@ Describe JavaAcceptanceTests { "Rows manipulation:", "C3 <-> C2", "R3 <-> R2", "-5 * R2 +R4 -> R4", "C4 <-> C3", "R4 <-> R3", "R3 / -15 -> R3", "-4 * R3 +R2 -> R2", "-5 * R3 +R1 -> R1", "(-8.3333, x2, -0.6667, 1.6667)","Saved to file out2.txt") - $areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 $areEqual | Should Be $true } @@ -70,7 +70,7 @@ Describe JavaAcceptanceTests { "R2 / 1.6+6.1i -> R2", "-10.4094+9.6778i * R2 +R3 -> R3", "R3 / -6.7848+9.7158i -> R3", "0.5432-0.746i * R3 +R2 -> R2", "-0.424+0.848i * R3 +R1 -> R1", "0.74-0.38i * R2 +R1 -> R1", "(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i)", "Saved to file out3.txt") - $areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 $areEqual | Should Be $true } From c1dc06cd77bf726e80635c980a1c9efe1b41b02a Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 29 Dec 2018 12:18:43 -0500 Subject: [PATCH 031/108] add ability run acceptance tests on Linux --- acceptance tests/tests.ps1 | 173 +++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 86 deletions(-) mode change 100644 => 100755 acceptance tests/tests.ps1 diff --git a/acceptance tests/tests.ps1 b/acceptance tests/tests.ps1 old mode 100644 new mode 100755 index d254417..f0131f5 --- a/acceptance tests/tests.ps1 +++ b/acceptance tests/tests.ps1 @@ -1,86 +1,87 @@ -Describe JavaAcceptanceTests { - It 'single solution' { - Remove-Item out.txt -ErrorAction SilentlyContinue - Remove-Item stdout.txt -ErrorAction SilentlyContinue - - java -classpath "..\out\production\project" solver.Main -in in.txt -out out.txt -verbose > stdout.txt - - [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout.txt") - [String[]]$expectedOutput = [String[]]("Start solving the equation.", - "Rows manipulation:", "-2 * R1 +R2 -> R2", "-3 * R1 +R3 -> R3", - "R2 / 2 -> R2", "-3 * R2 +R3 -> R3", "R3 / -0.5 -> R3", - "3.5 * R3 +R2 -> R2", "-2 * R3 +R1 -> R1", "-1 * R2 +R1 -> R1", - "(1, 2, 3)", "Saved to file out.txt") - [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 - $areEqual | Should Be $true - } - - It 'no solution' { - Remove-Item out1.txt -ErrorAction SilentlyContinue - Remove-Item stdout1.txt -ErrorAction SilentlyContinue - - java -classpath "..\out\production\project" solver.Main -in in1.txt -out out1.txt -verbose > stdout1.txt - - [String[]]$lines = [System.IO.File]::ReadLines("out1.txt") - $lines.Count | Should Be 1 - $lines[0] | Should Be "There are no solutions" - - [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout1.txt") - [String[]]$expectedOutput = [String[]]("Start solving the equation.", - "Rows manipulation:", "R1 <-> R3", "C1 <-> C3", "R1 / 6 -> R1", - "-3 * R1 +R2 -> R2", "-2 * R1 +R3 -> R3", "-1 * R2 +R3 -> R3", - "R3 / 0.1667 -> R3", "0.5 * R3 +R2 -> R2", "-0.1667 * R3 +R1 -> R1", - "There are no solutions", "Saved to file out1.txt") - [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 - $areEqual | Should Be $true - } - - It 'many solutions' { - Remove-Item out2.txt -ErrorAction SilentlyContinue - Remove-Item stdout2.txt -ErrorAction SilentlyContinue - - java -classpath "..\out\production\project" solver.Main -in in2.txt -out out2.txt -verbose > stdout2.txt - - [String[]]$lines = [System.IO.File]::ReadLines("out2.txt") - $lines.Count | Should Be 1 - $lines[0] | Should Be "(-8.3333, x2, -0.6667, 1.6667)" - - [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout2.txt") - [String[]]$expectedOutput = [String[]]("Start solving the equation.", - "Rows manipulation:", "C3 <-> C2", "R3 <-> R2", "-5 * R2 +R4 -> R4", - "C4 <-> C3", "R4 <-> R3", "R3 / -15 -> R3", "-4 * R3 +R2 -> R2", - "-5 * R3 +R1 -> R1", "(-8.3333, x2, -0.6667, 1.6667)","Saved to file out2.txt") - [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 - $areEqual | Should Be $true - } - - It 'single solution complex numbers' { - Remove-Item out3.txt -ErrorAction SilentlyContinue - Remove-Item stdout3.txt -ErrorAction SilentlyContinue - - java -classpath "..\out\production\project" solver.Main -in in3.txt -out out3.txt -verbose > stdout3.txt - - [String[]]$lines = [System.IO.File]::ReadLines("out3.txt") - $lines.Count | Should Be 1 - $lines[0] | Should Be "(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i)" - - [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout3.txt") - [String[]]$expectedOutput = [String[]]("Start solving the equation.", - "Rows manipulation:", "R1 / 1+2i -> R1", "1-3i * R1 +R2 -> R2", "-12.31 * R1 +R3 -> R3", - "R2 / 1.6+6.1i -> R2", "-10.4094+9.6778i * R2 +R3 -> R3", "R3 / -6.7848+9.7158i -> R3", - "0.5432-0.746i * R3 +R2 -> R2", "-0.424+0.848i * R3 +R1 -> R1", "0.74-0.38i * R2 +R1 -> R1", - "(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i)", "Saved to file out3.txt") - [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 - $areEqual | Should Be $true - } - - It 'no output without -verbose' { - Remove-Item out4.txt -ErrorAction SilentlyContinue - Remove-Item stdout4.txt -ErrorAction SilentlyContinue - - java -classpath "..\out\production\project" solver.Main -in in.txt -out out4.txt > stdout4.txt - - [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout4.txt") - $stdoutLines.Count | Should Be 0 - } -} \ No newline at end of file +#!/usr/bin/env pwsh +Describe JavaAcceptanceTests { + It 'single solution' { + Remove-Item out.txt -ErrorAction SilentlyContinue + Remove-Item stdout.txt -ErrorAction SilentlyContinue + + java -classpath "../out/production/project" solver.Main -in in.txt -out out.txt -verbose > stdout.txt + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout.txt") + [String[]]$expectedOutput = [String[]]("Start solving the equation.", + "Rows manipulation:", "-2 * R1 +R2 -> R2", "-3 * R1 +R3 -> R3", + "R2 / 2 -> R2", "-3 * R2 +R3 -> R3", "R3 / -0.5 -> R3", + "3.5 * R3 +R2 -> R2", "-2 * R3 +R1 -> R1", "-1 * R2 +R1 -> R1", + "(1, 2, 3)", "Saved to file out.txt") + [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + $areEqual | Should Be $true + } + + It 'no solution' { + Remove-Item out1.txt -ErrorAction SilentlyContinue + Remove-Item stdout1.txt -ErrorAction SilentlyContinue + + java -classpath "../out/production/project" solver.Main -in in1.txt -out out1.txt -verbose > stdout1.txt + + [String[]]$lines = [System.IO.File]::ReadLines("out1.txt") + $lines.Count | Should Be 1 + $lines[0] | Should Be "There are no solutions" + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout1.txt") + [String[]]$expectedOutput = [String[]]("Start solving the equation.", + "Rows manipulation:", "R1 <-> R3", "C1 <-> C3", "R1 / 6 -> R1", + "-3 * R1 +R2 -> R2", "-2 * R1 +R3 -> R3", "-1 * R2 +R3 -> R3", + "R3 / 0.1667 -> R3", "0.5 * R3 +R2 -> R2", "-0.1667 * R3 +R1 -> R1", + "There are no solutions", "Saved to file out1.txt") + [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + $areEqual | Should Be $true + } + + It 'many solutions' { + Remove-Item out2.txt -ErrorAction SilentlyContinue + Remove-Item stdout2.txt -ErrorAction SilentlyContinue + + java -classpath "../out/production/project" solver.Main -in in2.txt -out out2.txt -verbose > stdout2.txt + + [String[]]$lines = [System.IO.File]::ReadLines("out2.txt") + $lines.Count | Should Be 1 + $lines[0] | Should Be "(-8.3333, x2, -0.6667, 1.6667)" + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout2.txt") + [String[]]$expectedOutput = [String[]]("Start solving the equation.", + "Rows manipulation:", "C3 <-> C2", "R3 <-> R2", "-5 * R2 +R4 -> R4", + "C4 <-> C3", "R4 <-> R3", "R3 / -15 -> R3", "-4 * R3 +R2 -> R2", + "-5 * R3 +R1 -> R1", "(-8.3333, x2, -0.6667, 1.6667)","Saved to file out2.txt") + [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + $areEqual | Should Be $true + } + + It 'single solution complex numbers' { + Remove-Item out3.txt -ErrorAction SilentlyContinue + Remove-Item stdout3.txt -ErrorAction SilentlyContinue + + java -classpath "../out/production/project" solver.Main -in in3.txt -out out3.txt -verbose > stdout3.txt + + [String[]]$lines = [System.IO.File]::ReadLines("out3.txt") + $lines.Count | Should Be 1 + $lines[0] | Should Be "(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i)" + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout3.txt") + [String[]]$expectedOutput = [String[]]("Start solving the equation.", + "Rows manipulation:", "R1 / 1+2i -> R1", "1-3i * R1 +R2 -> R2", "-12.31 * R1 +R3 -> R3", + "R2 / 1.6+6.1i -> R2", "-10.4094+9.6778i * R2 +R3 -> R3", "R3 / -6.7848+9.7158i -> R3", + "0.5432-0.746i * R3 +R2 -> R2", "-0.424+0.848i * R3 +R1 -> R1", "0.74-0.38i * R2 +R1 -> R1", + "(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i)", "Saved to file out3.txt") + [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + $areEqual | Should Be $true + } + + It 'no output without -verbose' { + Remove-Item out4.txt -ErrorAction SilentlyContinue + Remove-Item stdout4.txt -ErrorAction SilentlyContinue + + java -classpath "../out/production/project" solver.Main -in in.txt -out out4.txt > stdout4.txt + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout4.txt") + $stdoutLines.Count | Should Be 0 + } +} From a73df1a5a179e012acf8fd5689a46b0d2edfe250 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sun, 30 Dec 2018 05:45:13 +0700 Subject: [PATCH 032/108] refactoring --- acceptance tests/stdout1.txt | Bin 508 -> 362 bytes acceptance tests/tests.ps1 | 6 ++--- src/solver/Complex.java | 9 +++----- src/solver/Main.java | 2 +- src/solver/Solver.java | 16 +++++++------ test/ComplexTest.java | 6 ++--- test/ParametersTest.java | 4 ++-- test/SolverTest.java | 42 +++++++++++++++++------------------ 8 files changed, 41 insertions(+), 44 deletions(-) diff --git a/acceptance tests/stdout1.txt b/acceptance tests/stdout1.txt index f1a443aa674922958a1a68b8f73170c5a5ed914e..0b2e781bff418a1233d1dfc23030e19e0ad58c0f 100644 GIT binary patch delta 43 wcmeyv{EBHp)x;kL;<^lm3=h{2eFmw^k&GoI|psLE(IxstIN0QPAKlmGw# delta 150 zcmaFG^oMyumAx~AA%g;g4TCO&9gucrFlOLo;9>{@i|PYK%zzjo2NDCx=>pX#FlYfW zP-Nn1X;C8t7s%2E3Ii2P%(hoFV9*2VF#|$#pajemhz%e)(}@RFxseo2eBKNIG))zW diff --git a/acceptance tests/tests.ps1 b/acceptance tests/tests.ps1 index f0131f5..546f575 100755 --- a/acceptance tests/tests.ps1 +++ b/acceptance tests/tests.ps1 @@ -28,10 +28,8 @@ Describe JavaAcceptanceTests { [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout1.txt") [String[]]$expectedOutput = [String[]]("Start solving the equation.", - "Rows manipulation:", "R1 <-> R3", "C1 <-> C3", "R1 / 6 -> R1", - "-3 * R1 +R2 -> R2", "-2 * R1 +R3 -> R3", "-1 * R2 +R3 -> R3", - "R3 / 0.1667 -> R3", "0.5 * R3 +R2 -> R2", "-0.1667 * R3 +R1 -> R1", - "There are no solutions", "Saved to file out1.txt") + "Rows manipulation:", "R1 <-> R3", "-1 * R2 +R3 -> R3", "R3 / -1 -> R3", + "-3 * R3 +R2 -> R2", "-6 * R3 +R1 -> R1", "There are no solutions", "Saved to file out1.txt") [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 $areEqual | Should Be $true } diff --git a/src/solver/Complex.java b/src/solver/Complex.java index 81a413d..b1eab9f 100644 --- a/src/solver/Complex.java +++ b/src/solver/Complex.java @@ -9,8 +9,8 @@ public class Complex { private static final double epsilon = 0.00001; - private double real; - private double imag; + private final double real; + private final double imag; public Complex(double real, double imag) { this.real = real; @@ -48,10 +48,7 @@ public boolean equals(Object other) { } Complex o = (Complex) other; - if (Math.abs(o.imag - imag) < epsilon && Math.abs(o.real - real) < epsilon) { - return true; - } - return false; + return Math.abs(o.imag - imag) < epsilon && Math.abs(o.real - real) < epsilon; } @NotNull diff --git a/src/solver/Main.java b/src/solver/Main.java index 310da85..07a0a01 100644 --- a/src/solver/Main.java +++ b/src/solver/Main.java @@ -1,6 +1,6 @@ package solver; -public class Main { +class Main { public static void main(String[] args) { try { final Parameters p = new Parameters(args); diff --git a/src/solver/Solver.java b/src/solver/Solver.java index da4953e..e45ed92 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -13,19 +13,20 @@ public class Solver { private static final Complex one = new Complex(1.0, 0.0); private static final Complex minusOne = new Complex(-1.0, 0.0); - private int numberEquations; - private int numberVariables; - private Complex[][] matrix; - private Complex[] solutionParticular; - private String[] solutionGeneral; - private int[] solutionIndexes; - private boolean verbose; + private final int numberEquations; + private final int numberVariables; + private final Complex[][] matrix; + private final Complex[] solutionParticular; + private final String[] solutionGeneral; + private final int[] solutionIndexes; + private final boolean verbose; private NumberSolutions numberSolutions = NumberSolutions.ONE; public Solver(@NotNull Scanner sc) throws NumberFormatException { this(sc, false); } + @SuppressWarnings("WeakerAccess") public Solver(@NotNull Scanner sc, boolean verbose) throws NumberFormatException { numberVariables = sc.nextInt(); final int realNumberEquations = sc.nextInt(); @@ -93,6 +94,7 @@ private void gausFirstStep() { for (int j = i + 1; j < numberEquations; ++j) { if (!matrix[j][i].equals(zero)) { swapRows(i, j); + notFound = false; break; } } diff --git a/test/ComplexTest.java b/test/ComplexTest.java index 50a159e..cd2e212 100644 --- a/test/ComplexTest.java +++ b/test/ComplexTest.java @@ -9,13 +9,13 @@ public class ComplexTest { public void equals1() { final Complex a = new Complex(1.0, 2.0); final Complex b = new Complex(1.0, 2.0); - Assert.assertTrue(a.equals(b)); + Assert.assertEquals(a, b); } @Test public void equals2() { final Complex a = new Complex(1.0, 2.0); - Assert.assertFalse(a.equals("Hello")); + Assert.assertNotEquals("Hello", a); } @@ -60,7 +60,7 @@ public void constructor1() { public void constructor2() { boolean ok = false; try { - final Complex c = new Complex("gbc"); + @SuppressWarnings("unused") final Complex c = new Complex("gbc"); } catch (Exception e) { ok = true; } diff --git a/test/ParametersTest.java b/test/ParametersTest.java index d29cfa9..7534a69 100644 --- a/test/ParametersTest.java +++ b/test/ParametersTest.java @@ -8,7 +8,7 @@ public void defaultParameters() { final Parameters p = new Parameters(new String[]{}); Assert.assertEquals("input.txt", p.in); Assert.assertEquals("output.txt", p.out); - Assert.assertEquals(false, p.verbose); + Assert.assertFalse(p.verbose); } @Test @@ -26,6 +26,6 @@ public void out() { @Test public void verbose() { final Parameters p = new Parameters(new String[]{"-verbose"}); - Assert.assertEquals(true, p.verbose); + Assert.assertTrue(p.verbose); } } diff --git a/test/SolverTest.java b/test/SolverTest.java index 061a5d7..b1f730d 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -20,7 +20,7 @@ public void constructor2() { boolean ok = false; try { final Scanner sc = new Scanner("1 1\nab 2"); - final Solver p = new Solver(sc); + @SuppressWarnings("unused") final Solver p = new Solver(sc); } catch (Exception e) { ok = true; } @@ -33,10 +33,10 @@ public void solve1() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(2.0, 0)}; + final Complex[] expectedPartialSolution = new Complex[]{new Complex(2.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @@ -46,11 +46,11 @@ public void solve2() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(-1.0, 0), + final Complex[] expectedPartialSolution = new Complex[]{new Complex(-1.0, 0), new Complex(2.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @@ -60,11 +60,11 @@ public void solve3() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(0.85714, 0), + final Complex[] expectedPartialSolution = new Complex[]{new Complex(0.85714, 0), new Complex(0.71429, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @@ -74,11 +74,11 @@ public void solve4() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(1.0, 0), + final Complex[] expectedPartialSolution = new Complex[]{new Complex(1.0, 0), new Complex(2.0, 0), new Complex(3.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @@ -88,11 +88,11 @@ public void solve5() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(1.0, 0), + final Complex[] expectedPartialSolution = new Complex[]{new Complex(1.0, 0), new Complex(1.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @@ -102,12 +102,12 @@ public void solve6() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(0.0, 0), + final Complex[] expectedPartialSolution = new Complex[]{new Complex(0.0, 0), new Complex(1.0, 0)}; final String[] expectedGeneralSolution = new String[]{"x1", "1"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); Assert.assertArrayEquals(expectedGeneralSolution, p.getSolutionGeneral()); } @@ -139,12 +139,12 @@ public void solve9() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(9.0, 0), + final Complex[] expectedPartialSolution = new Complex[]{new Complex(9.0, 0), new Complex(0, 0), new Complex(0, 0)}; final String[] expectedGeneralSolution = new String[]{"9 - x2 - x3 * (2)", "x2", "x3"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); Assert.assertArrayEquals(expectedGeneralSolution, p.getSolutionGeneral()); } @@ -154,12 +154,12 @@ public void solve10() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(-8.3333333, 0), + final Complex[] expectedPartialSolution = new Complex[]{new Complex(-8.3333333, 0), new Complex(0, 0), new Complex(-0.6666667, 0), new Complex(1.6666667, 0)}; final String[] expectedGeneralSolution = new String[]{"-8.3333", "x2", "-0.6667", "1.6667"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); Assert.assertArrayEquals(expectedGeneralSolution, p.getSolutionGeneral()); } @@ -169,13 +169,13 @@ public void solve11() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(0.6, 0), + final Complex[] expectedPartialSolution = new Complex[]{new Complex(0.6, 0), new Complex(0, 0), new Complex(0.2, 0), new Complex(0, 0)}; final String[] expectedGeneralSolution = new String[]{"0.6 - x2 * (1.5) - x4 * (0.1)", "x2", "0.2 - x4 * (-0.8)", "x4"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); Assert.assertArrayEquals(expectedGeneralSolution, p.getSolutionGeneral()); } @@ -186,11 +186,11 @@ public void solve12() { final Solver p = new Solver(sc); p.solve(); - final Complex[] expectedParticialSolution = new Complex[]{new Complex(6.73335286, -22.99754223), + final Complex[] expectedPartialSolution = new Complex[]{new Complex(6.73335286, -22.99754223), new Complex(-1.7976071, 2.08404919), new Complex(15.69938581, 7.3960106)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedParticialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } } From 1d7420e67c3c10a3874defe930a39883181d806b Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sun, 30 Dec 2018 05:59:43 +0700 Subject: [PATCH 033/108] change name to more clear --- src/solver/Solver.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/solver/Solver.java b/src/solver/Solver.java index e45ed92..15de6ba 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -90,38 +90,38 @@ private void swapRows(int row1, int row2) { private void gausFirstStep() { for (int i = 0; i < numberVariables; ++i) { if (matrix[i][i].equals(zero)) { - boolean notFound = true; + boolean foundNonZeroElement = false; for (int j = i + 1; j < numberEquations; ++j) { if (!matrix[j][i].equals(zero)) { swapRows(i, j); - notFound = false; + foundNonZeroElement = true; break; } } - if (notFound) { + if (!foundNonZeroElement) { for (int j = i + 1; j < numberEquations; ++j) { if (!matrix[i][j].equals(zero)) { swapColumns(i, j); - notFound = false; + foundNonZeroElement = true; break; } } } - if (notFound) { - for (int k = i + 1; notFound && k < numberVariables; ++k) { + if (!foundNonZeroElement) { + for (int k = i + 1; !foundNonZeroElement && k < numberVariables; ++k) { for (int j = i + 1; j < numberEquations; ++j) { if (!matrix[j][k].equals(zero)) { swapColumns(k, i); swapRows(j, i); - notFound = false; + foundNonZeroElement = true; break; } } } } - if (notFound) { + if (!foundNonZeroElement) { if (matrix[i][numberEquations].equals(zero)) { numberSolutions = NumberSolutions.MANY; continue; From 4c822aa85221d4094238613ee918f8f67911d94f Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Thu, 3 Jan 2019 04:30:36 +0700 Subject: [PATCH 034/108] refactoring --- acceptance tests/tests.ps1 | 50 ++++++----- src/solver/Complex.java | 99 +++++++++++----------- src/solver/Main.java | 4 +- src/solver/Solver.java | 166 ++++++++++++++++++------------------- test/ComplexTest.java | 94 ++++++++++----------- test/SolverTest.java | 24 +++--- 6 files changed, 220 insertions(+), 217 deletions(-) diff --git a/acceptance tests/tests.ps1 b/acceptance tests/tests.ps1 index 546f575..fc9237a 100755 --- a/acceptance tests/tests.ps1 +++ b/acceptance tests/tests.ps1 @@ -1,12 +1,16 @@ #!/usr/bin/env pwsh Describe JavaAcceptanceTests { It 'single solution' { - Remove-Item out.txt -ErrorAction SilentlyContinue - Remove-Item stdout.txt -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/out.txt" -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/stdout.txt" -ErrorAction SilentlyContinue - java -classpath "../out/production/project" solver.Main -in in.txt -out out.txt -verbose > stdout.txt + java -classpath "../out/production/project" solver.Main -in in.txt -out out.txt -verbose > "$PSScriptRoot/stdout.txt" - [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout.txt") + [String[]]$lines = [System.IO.File]::ReadLines("$PSScriptRoot/out.txt") + $lines.Count | Should Be 1 + $lines[0] | Should Be "(1, 2, 3)" + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("$PSScriptRoot/stdout.txt") [String[]]$expectedOutput = [String[]]("Start solving the equation.", "Rows manipulation:", "-2 * R1 +R2 -> R2", "-3 * R1 +R3 -> R3", "R2 / 2 -> R2", "-3 * R2 +R3 -> R3", "R3 / -0.5 -> R3", @@ -17,16 +21,16 @@ Describe JavaAcceptanceTests { } It 'no solution' { - Remove-Item out1.txt -ErrorAction SilentlyContinue - Remove-Item stdout1.txt -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/out1.txt" -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/stdout1.txt" -ErrorAction SilentlyContinue - java -classpath "../out/production/project" solver.Main -in in1.txt -out out1.txt -verbose > stdout1.txt + java -classpath "../out/production/project" solver.Main -in in1.txt -out out1.txt -verbose > "$PSScriptRoot/stdout1.txt" - [String[]]$lines = [System.IO.File]::ReadLines("out1.txt") + [String[]]$lines = [System.IO.File]::ReadLines("$PSScriptRoot/out1.txt") $lines.Count | Should Be 1 $lines[0] | Should Be "There are no solutions" - [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout1.txt") + [String[]]$stdoutLines = [System.IO.File]::ReadLines("$PSScriptRoot/stdout1.txt") [String[]]$expectedOutput = [String[]]("Start solving the equation.", "Rows manipulation:", "R1 <-> R3", "-1 * R2 +R3 -> R3", "R3 / -1 -> R3", "-3 * R3 +R2 -> R2", "-6 * R3 +R1 -> R1", "There are no solutions", "Saved to file out1.txt") @@ -35,16 +39,16 @@ Describe JavaAcceptanceTests { } It 'many solutions' { - Remove-Item out2.txt -ErrorAction SilentlyContinue - Remove-Item stdout2.txt -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/out2.txt" -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/stdout2.txt" -ErrorAction SilentlyContinue - java -classpath "../out/production/project" solver.Main -in in2.txt -out out2.txt -verbose > stdout2.txt + java -classpath "../out/production/project" solver.Main -in in2.txt -out out2.txt -verbose > "$PSScriptRoot/stdout2.txt" - [String[]]$lines = [System.IO.File]::ReadLines("out2.txt") + [String[]]$lines = [System.IO.File]::ReadLines("$PSScriptRoot/out2.txt") $lines.Count | Should Be 1 $lines[0] | Should Be "(-8.3333, x2, -0.6667, 1.6667)" - [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout2.txt") + [String[]]$stdoutLines = [System.IO.File]::ReadLines("$PSScriptRoot/stdout2.txt") [String[]]$expectedOutput = [String[]]("Start solving the equation.", "Rows manipulation:", "C3 <-> C2", "R3 <-> R2", "-5 * R2 +R4 -> R4", "C4 <-> C3", "R4 <-> R3", "R3 / -15 -> R3", "-4 * R3 +R2 -> R2", @@ -54,16 +58,16 @@ Describe JavaAcceptanceTests { } It 'single solution complex numbers' { - Remove-Item out3.txt -ErrorAction SilentlyContinue - Remove-Item stdout3.txt -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/out3.txt" -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/stdout3.txt" -ErrorAction SilentlyContinue - java -classpath "../out/production/project" solver.Main -in in3.txt -out out3.txt -verbose > stdout3.txt + java -classpath "../out/production/project" solver.Main -in in3.txt -out out3.txt -verbose > "$PSScriptRoot/stdout3.txt" - [String[]]$lines = [System.IO.File]::ReadLines("out3.txt") + [String[]]$lines = [System.IO.File]::ReadLines("$PSScriptRoot/out3.txt") $lines.Count | Should Be 1 $lines[0] | Should Be "(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i)" - [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout3.txt") + [String[]]$stdoutLines = [System.IO.File]::ReadLines("$PSScriptRoot/stdout3.txt") [String[]]$expectedOutput = [String[]]("Start solving the equation.", "Rows manipulation:", "R1 / 1+2i -> R1", "1-3i * R1 +R2 -> R2", "-12.31 * R1 +R3 -> R3", "R2 / 1.6+6.1i -> R2", "-10.4094+9.6778i * R2 +R3 -> R3", "R3 / -6.7848+9.7158i -> R3", @@ -74,12 +78,12 @@ Describe JavaAcceptanceTests { } It 'no output without -verbose' { - Remove-Item out4.txt -ErrorAction SilentlyContinue - Remove-Item stdout4.txt -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/out4.txt" -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/stdout4.txt" -ErrorAction SilentlyContinue - java -classpath "../out/production/project" solver.Main -in in.txt -out out4.txt > stdout4.txt + java -classpath "../out/production/project" solver.Main -in in.txt -out out4.txt > "$PSScriptRoot/stdout4.txt" - [String[]]$stdoutLines = [System.IO.File]::ReadLines("stdout4.txt") + [String[]]$stdoutLines = [System.IO.File]::ReadLines("$PSScriptRoot/stdout4.txt") $stdoutLines.Count | Should Be 0 } } diff --git a/src/solver/Complex.java b/src/solver/Complex.java index b1eab9f..1cc283e 100644 --- a/src/solver/Complex.java +++ b/src/solver/Complex.java @@ -8,7 +8,30 @@ import java.util.Locale; public class Complex { - private static final double epsilon = 0.00001; + public static final double EPSILON = 0.00001; + + @NotNull + @Contract("_, _ -> new") + public static Complex add(@NotNull Complex a, @NotNull Complex b) { + return new Complex(a.real + b.real, a.imag + b.imag); + } + + @NotNull + @Contract("_, _ -> new") + public static Complex divide(@NotNull Complex a, @NotNull Complex b) { + final Complex bConjugate = b.conjugate(); + final Complex a1 = Complex.multiply(a, bConjugate); + final Complex b1 = Complex.multiply(b, bConjugate); + + return new Complex(a1.real / b1.real, a1.imag / b1.real); + } + + @NotNull + @Contract("_, _ -> new") + public static Complex multiply(@NotNull Complex a, @NotNull Complex b) { + return new Complex(a.real * b.real - a.imag * b.imag, a.real * b.imag + a.imag * b.real); + } + private final double real; private final double imag; @@ -21,19 +44,14 @@ public Complex() { this(0.0, 0.0); } - @Override - public String toString() { - final DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US); - final DecimalFormat realFormat = new DecimalFormat("0.####", symbols); - final DecimalFormat imagFormat = new DecimalFormat("0.####i", symbols); - if (Math.abs(imag) < epsilon) { - return realFormat.format(real); - } - if (Math.abs(real) < epsilon) { - return imagFormat.format(imag); - } - imagFormat.setPositivePrefix("+"); - return String.format("%s%s", realFormat.format(real), imagFormat.format(imag)); + public Complex(@NotNull String s) throws NumberFormatException { + final String[] strs = split(s); + real = Double.parseDouble(strs[0]); + imag = Double.parseDouble(strs[1]); + } + + public Complex conjugate() { + return new Complex(real, -imag); } @Contract(value = "null -> false", pure = true) @@ -48,29 +66,30 @@ public boolean equals(Object other) { } Complex o = (Complex) other; - return Math.abs(o.imag - imag) < epsilon && Math.abs(o.real - real) < epsilon; + return Math.abs(o.imag - imag) < EPSILON && Math.abs(o.real - real) < EPSILON; } - @NotNull - @Contract("_, _ -> new") - public static Complex add(@NotNull Complex a, @NotNull Complex b) { - return new Complex(a.real + b.real, a.imag + b.imag); + public double getReal() { + return real; } - @NotNull - @Contract("_, _ -> new") - public static Complex multiply(@NotNull Complex a, @NotNull Complex b) { - return new Complex(a.real * b.real - a.imag * b.imag, a.real * b.imag + a.imag * b.real); + public double getImag() { + return imag; } - @NotNull - @Contract("_, _ -> new") - public static Complex divide(@NotNull Complex a, @NotNull Complex b) { - final Complex bConjugate = b.conjugate(); - final Complex a1 = Complex.multiply(a, bConjugate); - final Complex b1 = Complex.multiply(b, bConjugate); - assert (Math.abs(b1.imag) < epsilon); - return new Complex(a1.real / b1.real, a1.imag / b1.real); + @Override + public String toString() { + final DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US); + final DecimalFormat realFormat = new DecimalFormat("0.####", symbols); + final DecimalFormat imagFormat = new DecimalFormat("0.####i", symbols); + if (Math.abs(imag) < EPSILON) { + return realFormat.format(real); + } + if (Math.abs(real) < EPSILON) { + return imagFormat.format(imag); + } + imagFormat.setPositivePrefix("+"); + return String.format("%s%s", realFormat.format(real), imagFormat.format(imag)); } @NotNull @@ -95,22 +114,4 @@ private String[] split(@NotNull String s) { } return new String[]{realString, imagString}; } - - public Complex(@NotNull String s) throws NumberFormatException { - final String[] strs = split(s); - real = Double.parseDouble(strs[0]); - imag = Double.parseDouble(strs[1]); - } - - public double getReal() { - return real; - } - - public double getImag() { - return imag; - } - - public Complex conjugate() { - return new Complex(real, -imag); - } } diff --git a/src/solver/Main.java b/src/solver/Main.java index 07a0a01..7f48f4a 100644 --- a/src/solver/Main.java +++ b/src/solver/Main.java @@ -8,7 +8,7 @@ public static void main(String[] args) { s.solve(); s.writeSolutionToFile(p.out); } catch (Exception e) { - System.out.printf("An exception occurs %s", e.getMessage()); + System.out.printf("An exception occurs %s\n", e.getMessage()); } } -} \ No newline at end of file +} diff --git a/src/solver/Solver.java b/src/solver/Solver.java index 15de6ba..bc4d1c4 100644 --- a/src/solver/Solver.java +++ b/src/solver/Solver.java @@ -9,9 +9,9 @@ import java.util.stream.IntStream; public class Solver { - private static final Complex zero = new Complex(0.0, 0.0); - private static final Complex one = new Complex(1.0, 0.0); - private static final Complex minusOne = new Complex(-1.0, 0.0); + private static final Complex ZERO = new Complex(0.0, 0.0); + private static final Complex ONE = new Complex(1.0, 0.0); + private static final Complex MINUS_ONE = new Complex(-1.0, 0.0); private final int numberEquations; private final int numberVariables; @@ -52,17 +52,49 @@ public Solver(String in, boolean verbose) throws FileNotFoundException { this(new Scanner(new File(in)), verbose); } + public NumberSolutions getNumberSolutions() { + return numberSolutions; + } + public int getSize() { return matrix.length; } - private void divideRow(int row, @NotNull Complex k) { + public String[] getSolutionGeneral() { + if (numberSolutions != NumberSolutions.MANY) { + return null; + } + return solutionGeneral; + } + + public Complex[] getSolutionPartial() { + if (numberSolutions == NumberSolutions.NONE) { + return null; + } + return solutionParticular; + } + + public void solve() { if (verbose) { - System.out.printf("R%d / %s -> R%d\n", row + 1, k.toString(), row + 1); + System.out.println("Start solving the equation."); + System.out.println("Rows manipulation:"); } - final int n = matrix[row].length; - for (int i = 0; i < n; ++i) { - matrix[row][i] = Complex.divide(matrix[row][i], k); + gausFirstStep(); + if (numberSolutions != NumberSolutions.NONE) { + gausSecondStep(); + generateSolutions(); + checkThatSolutionIsSane(); + } + printSolution(); + } + + public void writeSolutionToFile(String out) throws FileNotFoundException { + final File file = new File(out); + final PrintWriter printWriter = new PrintWriter(file); + printSolutionInternal(printWriter); + printWriter.close(); + if (verbose) { + System.out.printf("Saved to file %s\n", out); } } @@ -76,23 +108,36 @@ private void addKRow1ToRow2(@NotNull Complex k, int row1, int row2) { } } - private void swapRows(int row1, int row2) { + private void checkThatSolutionIsSane() { + for (int i = numberVariables; i < numberEquations; ++i) { + Complex sum = new Complex(0.0, 0.0); + for (int j = 0; j < numberVariables; ++j) { + final Complex temp = Complex.multiply(solutionParticular[solutionIndexes[j]], matrix[i][solutionIndexes[j]]); + sum = Complex.add(sum, temp); + } + if (!sum.equals(matrix[i][numberVariables])) { + numberSolutions = NumberSolutions.NONE; + return; + } + } + } + + private void divideRow(int row, @NotNull Complex k) { if (verbose) { - System.out.printf("R%d <-> R%d\n", row1 + 1, row2 + 1); + System.out.printf("R%d / %s -> R%d\n", row + 1, k.toString(), row + 1); } - for (int i = 0; i < numberVariables + 1; ++i) { - final Complex temp = matrix[row1][i]; - matrix[row1][i] = matrix[row2][i]; - matrix[row2][i] = temp; + final int n = matrix[row].length; + for (int i = 0; i < n; ++i) { + matrix[row][i] = Complex.divide(matrix[row][i], k); } } private void gausFirstStep() { for (int i = 0; i < numberVariables; ++i) { - if (matrix[i][i].equals(zero)) { + if (matrix[i][i].equals(ZERO)) { boolean foundNonZeroElement = false; for (int j = i + 1; j < numberEquations; ++j) { - if (!matrix[j][i].equals(zero)) { + if (!matrix[j][i].equals(ZERO)) { swapRows(i, j); foundNonZeroElement = true; break; @@ -100,7 +145,7 @@ private void gausFirstStep() { } if (!foundNonZeroElement) { for (int j = i + 1; j < numberEquations; ++j) { - if (!matrix[i][j].equals(zero)) { + if (!matrix[i][j].equals(ZERO)) { swapColumns(i, j); foundNonZeroElement = true; break; @@ -111,7 +156,7 @@ private void gausFirstStep() { if (!foundNonZeroElement) { for (int k = i + 1; !foundNonZeroElement && k < numberVariables; ++k) { for (int j = i + 1; j < numberEquations; ++j) { - if (!matrix[j][k].equals(zero)) { + if (!matrix[j][k].equals(ZERO)) { swapColumns(k, i); swapRows(j, i); foundNonZeroElement = true; @@ -122,7 +167,7 @@ private void gausFirstStep() { } if (!foundNonZeroElement) { - if (matrix[i][numberEquations].equals(zero)) { + if (matrix[i][numberEquations].equals(ZERO)) { numberSolutions = NumberSolutions.MANY; continue; } else { @@ -132,12 +177,12 @@ private void gausFirstStep() { } } - if (!matrix[i][i].equals(one)) { + if (!matrix[i][i].equals(ONE)) { divideRow(i, matrix[i][i]); } for (int j = i + 1; j < numberEquations && j < numberVariables; ++j) { - final Complex k = Complex.multiply(minusOne, matrix[j][i]); - if (!k.equals(zero)) { + final Complex k = Complex.multiply(MINUS_ONE, matrix[j][i]); + if (!k.equals(ZERO)) { addKRow1ToRow2(k, i, j); } } @@ -147,8 +192,8 @@ private void gausFirstStep() { private void gausSecondStep() { for (int i = numberVariables - 1; i >= 0; --i) { for (int j = i - 1; j >= 0; --j) { - final Complex k = Complex.multiply(minusOne, matrix[j][i]); - if (!k.equals(zero)) { + final Complex k = Complex.multiply(MINUS_ONE, matrix[j][i]); + if (!k.equals(ZERO)) { addKRow1ToRow2(k, i, j); } } @@ -158,15 +203,15 @@ private void gausSecondStep() { private void generateSolutions() { for (int i = 0; i < numberEquations && i < numberVariables; ++i) { solutionParticular[solutionIndexes[i]] = matrix[i][numberVariables]; - if (matrix[i][i].equals(zero)) { + if (matrix[i][i].equals(ZERO)) { solutionGeneral[solutionIndexes[i]] = "x" + (solutionIndexes[i] + 1); } else { solutionGeneral[solutionIndexes[i]] = matrix[i][numberVariables].toString(); for (int j = i + 1; j < numberVariables; ++j) { - if (matrix[i][j].equals(one)) { + if (matrix[i][j].equals(ONE)) { solutionGeneral[solutionIndexes[i]] = solutionGeneral[solutionIndexes[i]] + " - x" + (solutionIndexes[j] + 1); - } else if (!matrix[i][j].equals(zero)) { + } else if (!matrix[i][j].equals(ZERO)) { solutionGeneral[solutionIndexes[i]] = solutionGeneral[solutionIndexes[i]] + " - x" + (solutionIndexes[j] + 1) + " * (" + matrix[i][j].toString() + ")"; } @@ -175,34 +220,6 @@ private void generateSolutions() { } } - private void checkThatSolutionIsSane() { - for (int i = numberVariables; i < numberEquations; ++i) { - Complex sum = new Complex(0.0, 0.0); - for (int j = 0; j < numberVariables; ++j) { - Complex temp = Complex.multiply(solutionParticular[solutionIndexes[j]], matrix[i][solutionIndexes[j]]); - sum = Complex.add(sum, temp); - } - if (!sum.equals(matrix[i][numberVariables])) { - numberSolutions = NumberSolutions.NONE; - return; - } - } - } - - public void solve() { - if (verbose) { - System.out.println("Start solving the equation."); - System.out.println("Rows manipulation:"); - } - gausFirstStep(); - if (numberSolutions != NumberSolutions.NONE) { - gausSecondStep(); - generateSolutions(); - checkThatSolutionIsSane(); - } - printSolution(); - } - private void printSolution() { if (verbose) { printSolutionInternal(new PrintWriter(System.out, true)); @@ -210,7 +227,7 @@ private void printSolution() { } private void printSolutionInternal(PrintWriter printWriter) { - switch(numberSolutions) { + switch (numberSolutions) { case NONE: printWriter.println("There are no solutions"); break; @@ -241,40 +258,23 @@ private void swapColumns(int column1, int column2) { } final int n = matrix.length; for (int i = 0; i < n; ++i) { - final Complex temp = matrix[i][column1]; + final Complex temp1 = matrix[i][column1]; matrix[i][column1] = matrix[i][column2]; - matrix[i][column2] = temp; + matrix[i][column2] = temp1; } - final int temp = solutionIndexes[column1]; + final int temp2 = solutionIndexes[column1]; solutionIndexes[column1] = solutionIndexes[column2]; - solutionIndexes[column2] = temp; + solutionIndexes[column2] = temp2; } - public void writeSolutionToFile(String out) throws FileNotFoundException { - final File file = new File(out); - final PrintWriter printWriter = new PrintWriter(file); - printSolutionInternal(printWriter); - printWriter.close(); + private void swapRows(int row1, int row2) { if (verbose) { - System.out.printf("Saved to file %s", out); - } - } - - public Complex[] getSolutionParticular() { - if (numberSolutions == NumberSolutions.NONE) { - return null; + System.out.printf("R%d <-> R%d\n", row1 + 1, row2 + 1); } - return solutionParticular; - } - - public NumberSolutions getNumberSolutions() { - return numberSolutions; - } - - public String[] getSolutionGeneral() { - if (numberSolutions != NumberSolutions.MANY) { - return null; + for (int i = 0; i < numberVariables + 1; ++i) { + final Complex temp = matrix[row1][i]; + matrix[row1][i] = matrix[row2][i]; + matrix[row2][i] = temp; } - return solutionGeneral; } } diff --git a/test/ComplexTest.java b/test/ComplexTest.java index cd2e212..b58bc6d 100644 --- a/test/ComplexTest.java +++ b/test/ComplexTest.java @@ -3,8 +3,6 @@ import solver.Complex; public class ComplexTest { - private final static double epsilon = 0.000001; - @Test public void equals1() { final Complex a = new Complex(1.0, 2.0); @@ -49,11 +47,18 @@ public void toString5() { Assert.assertEquals("0", a.toString()); } + @Test + public void defaultConstructor() { + final Complex c = new Complex(); + Assert.assertEquals(0.0, c.getReal(), Complex.EPSILON); + Assert.assertEquals(0.0, c.getImag(), Complex.EPSILON); + } + @Test public void constructor1() { final Complex c = new Complex(1.0, 0.0); - Assert.assertEquals(1.0, c.getReal(), epsilon); - Assert.assertEquals(0.0, c.getImag(), epsilon); + Assert.assertEquals(1.0, c.getReal(), Complex.EPSILON); + Assert.assertEquals(0.0, c.getImag(), Complex.EPSILON); } @Test @@ -68,10 +73,35 @@ public void constructor2() { } @Test - public void defaultConstructor() { - final Complex c = new Complex(); - Assert.assertEquals(0.0, c.getReal(), epsilon); - Assert.assertEquals(0.0, c.getImag(), epsilon); + public void constructor3() { + final String s = "-1.3"; + final Complex c = new Complex(s); + Assert.assertEquals(-1.3, c.getReal(), Complex.EPSILON); + Assert.assertEquals(0.0, c.getImag(), Complex.EPSILON); + } + + @Test + public void constructor4() { + final String s = "2.5i"; + final Complex c = new Complex(s); + Assert.assertEquals(0.0, c.getReal(), Complex.EPSILON); + Assert.assertEquals(2.5, c.getImag(), Complex.EPSILON); + } + + @Test + public void constructor5() { + final String s = "1.3-2.5i"; + final Complex c = new Complex(s); + Assert.assertEquals(1.3, c.getReal(), Complex.EPSILON); + Assert.assertEquals(-2.5, c.getImag(), Complex.EPSILON); + } + + @Test + public void constructor6() { + final String s = "1"; + final Complex c = new Complex(s); + Assert.assertEquals(1.0, c.getReal(), Complex.EPSILON); + Assert.assertEquals(0.0, c.getImag(), Complex.EPSILON); } @Test @@ -79,8 +109,8 @@ public void add() { final Complex a = new Complex(3.0, -5.0); final Complex b = new Complex(4.0, 2.0); final Complex c = Complex.add(a, b); - Assert.assertEquals(7.0, c.getReal(), epsilon); - Assert.assertEquals(-3.0, c.getImag(), epsilon); + Assert.assertEquals(7.0, c.getReal(), Complex.EPSILON); + Assert.assertEquals(-3.0, c.getImag(), Complex.EPSILON); } @Test @@ -88,16 +118,16 @@ public void multiply() { final Complex a = new Complex(3.0, 2.0); final Complex b = new Complex(1.0, 7.0); final Complex c = Complex.multiply(a, b); - Assert.assertEquals(-11.0, c.getReal(), epsilon); - Assert.assertEquals(23.0, c.getImag(), epsilon); + Assert.assertEquals(-11.0, c.getReal(), Complex.EPSILON); + Assert.assertEquals(23.0, c.getImag(), Complex.EPSILON); } @Test public void conjugate() { final Complex a = new Complex(3.0, 2.0); final Complex c = a.conjugate(); - Assert.assertEquals(3.0, c.getReal(), epsilon); - Assert.assertEquals(-2.0, c.getImag(), epsilon); + Assert.assertEquals(3.0, c.getReal(), Complex.EPSILON); + Assert.assertEquals(-2.0, c.getImag(), Complex.EPSILON); } @Test @@ -105,39 +135,7 @@ public void divide() { final Complex a = new Complex(2.0, 3.0); final Complex b = new Complex(4.0, -5.0); final Complex c = Complex.divide(a, b); - Assert.assertEquals(-7.0 / 41.0, c.getReal(), epsilon); - Assert.assertEquals(22.0 / 41.0, c.getImag(), epsilon); - } - - @Test - public void parseComplex1() { - final String s = "-1.3"; - final Complex c = new Complex(s); - Assert.assertEquals(-1.3, c.getReal(), epsilon); - Assert.assertEquals(0.0, c.getImag(), epsilon); - } - - @Test - public void parseComplex2() { - final String s = "2.5i"; - final Complex c = new Complex(s); - Assert.assertEquals(0.0, c.getReal(), epsilon); - Assert.assertEquals(2.5, c.getImag(), epsilon); - } - - @Test - public void parseComplex3() { - final String s = "1.3-2.5i"; - final Complex c = new Complex(s); - Assert.assertEquals(1.3, c.getReal(), epsilon); - Assert.assertEquals(-2.5, c.getImag(), epsilon); - } - - @Test - public void parseComplex4() { - final String s = "1"; - final Complex c = new Complex(s); - Assert.assertEquals(1.0, c.getReal(), epsilon); - Assert.assertEquals(0.0, c.getImag(), epsilon); + Assert.assertEquals(-7.0 / 41.0, c.getReal(), Complex.EPSILON); + Assert.assertEquals(22.0 / 41.0, c.getImag(), Complex.EPSILON); } } diff --git a/test/SolverTest.java b/test/SolverTest.java index b1f730d..0f12b83 100644 --- a/test/SolverTest.java +++ b/test/SolverTest.java @@ -36,7 +36,7 @@ public void solve1() { final Complex[] expectedPartialSolution = new Complex[]{new Complex(2.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @@ -50,7 +50,7 @@ public void solve2() { new Complex(2.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @@ -64,7 +64,7 @@ public void solve3() { new Complex(0.71429, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @@ -78,7 +78,7 @@ public void solve4() { new Complex(2.0, 0), new Complex(3.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @@ -92,7 +92,7 @@ public void solve5() { new Complex(1.0, 0)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @@ -107,7 +107,7 @@ public void solve6() { final String[] expectedGeneralSolution = new String[]{"x1", "1"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); Assert.assertArrayEquals(expectedGeneralSolution, p.getSolutionGeneral()); } @@ -118,7 +118,7 @@ public void solve7() { p.solve(); Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); - Assert.assertArrayEquals(null, p.getSolutionParticular()); + Assert.assertArrayEquals(null, p.getSolutionPartial()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @@ -129,7 +129,7 @@ public void solve8() { p.solve(); Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); - Assert.assertArrayEquals(null, p.getSolutionParticular()); + Assert.assertArrayEquals(null, p.getSolutionPartial()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } @@ -144,7 +144,7 @@ public void solve9() { final String[] expectedGeneralSolution = new String[]{"9 - x2 - x3 * (2)", "x2", "x3"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); Assert.assertArrayEquals(expectedGeneralSolution, p.getSolutionGeneral()); } @@ -159,7 +159,7 @@ public void solve10() { final String[] expectedGeneralSolution = new String[]{"-8.3333", "x2", "-0.6667", "1.6667"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); Assert.assertArrayEquals(expectedGeneralSolution, p.getSolutionGeneral()); } @@ -175,7 +175,7 @@ public void solve11() { "0.2 - x4 * (-0.8)", "x4"}; Assert.assertEquals(NumberSolutions.MANY, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); Assert.assertArrayEquals(expectedGeneralSolution, p.getSolutionGeneral()); } @@ -190,7 +190,7 @@ public void solve12() { new Complex(-1.7976071, 2.08404919), new Complex(15.69938581, 7.3960106)}; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); - Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionParticular()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } } From a727369081fa7486499f895473d9a354aa72fff7 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Thu, 3 Jan 2019 04:32:38 +0700 Subject: [PATCH 035/108] refactoring --- .gitignore | 5 +- .idea/checkstyle-idea.xml | 16 + .idea/compiler.xml | 9 + .idea/encodings.xml | 4 + .idea/libraries/junit_junit_4_12.xml | 11 + .idea/modules/Java.iml | 12 + .idea/modules/Java.main.iml | 10 + .idea/modules/Java.test.iml | 12 + .idea/vcs.xml | 6 + .idea/workspace.xml | 635 +++++++++++++++++++++++++++ 10 files changed, 716 insertions(+), 4 deletions(-) create mode 100644 .idea/checkstyle-idea.xml create mode 100644 .idea/compiler.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/libraries/junit_junit_4_12.xml create mode 100644 .idea/modules/Java.iml create mode 100644 .idea/modules/Java.main.iml create mode 100644 .idea/modules/Java.test.iml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml diff --git a/.gitignore b/.gitignore index 1dc9768..ee9a0c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Compiled class file *.class -out/ +Java/out/ # Log file *.log @@ -25,6 +25,3 @@ hs_err_pid* # Git git.properties - -# IntelliJ IDEA folder -.idea/ diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml new file mode 100644 index 0000000..b3059d6 --- /dev/null +++ b/.idea/checkstyle-idea.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..7d7a0fd --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..f13fa33 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/libraries/junit_junit_4_12.xml b/.idea/libraries/junit_junit_4_12.xml new file mode 100644 index 0000000..76510ff --- /dev/null +++ b/.idea/libraries/junit_junit_4_12.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/Java.iml b/.idea/modules/Java.iml new file mode 100644 index 0000000..a8aec01 --- /dev/null +++ b/.idea/modules/Java.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/Java.main.iml b/.idea/modules/Java.main.iml new file mode 100644 index 0000000..a720554 --- /dev/null +++ b/.idea/modules/Java.main.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/Java.test.iml b/.idea/modules/Java.test.iml new file mode 100644 index 0000000..dd331e2 --- /dev/null +++ b/.idea/modules/Java.test.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..c8397c9 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..6d5960d --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,635 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1545073768711 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No facets are configured + + + + + + + + + + + + + + + 11 + + + + + + + + project + + + + + + + + junit:junit:4.12 + + + + + + + + \ No newline at end of file From e6f66cbe8075d189ce09c49fbc0d696fc3e46639 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Thu, 3 Jan 2019 04:36:48 +0700 Subject: [PATCH 036/108] refactoring --- .idea/vcs.xml | 6 - {.idea => Java/.idea}/checkstyle-idea.xml | 0 {.idea => Java/.idea}/compiler.xml | 0 {.idea => Java/.idea}/encodings.xml | 0 .../.idea}/libraries/junit_junit_4_12.xml | 0 {.idea => Java/.idea}/misc.xml | 0 {.idea => Java/.idea}/modules.xml | 0 {.idea => Java/.idea}/modules/Java.iml | 0 {.idea => Java/.idea}/modules/Java.main.iml | 0 {.idea => Java/.idea}/modules/Java.test.iml | 0 {.idea => Java/.idea}/project.iml | 0 {.idea => Java/.idea}/workspace.xml | 139 +++++++++++------- .../acceptance tests}/in.txt | 0 .../acceptance tests}/in1.txt | 0 .../acceptance tests}/in2.txt | 0 .../acceptance tests}/in3.txt | 0 .../acceptance tests}/out.txt | 0 .../acceptance tests}/out1.txt | 0 .../acceptance tests}/out2.txt | 0 .../acceptance tests}/out3.txt | 0 .../acceptance tests}/out4.txt | 0 .../acceptance tests}/stdout.txt | Bin .../acceptance tests}/stdout1.txt | Bin .../acceptance tests}/stdout2.txt | Bin .../acceptance tests}/stdout3.txt | Bin .../acceptance tests}/stdout4.txt | 0 .../acceptance tests}/tests.ps1 | 0 {src => Java/src}/solver/Complex.java | 0 {src => Java/src}/solver/Main.java | 0 {src => Java/src}/solver/NumberSolutions.java | 0 {src => Java/src}/solver/Parameters.java | 0 {src => Java/src}/solver/Solver.java | 0 {test => Java/test}/ComplexTest.java | 0 {test => Java/test}/ParametersTest.java | 0 {test => Java/test}/SolverTest.java | 0 35 files changed, 83 insertions(+), 62 deletions(-) delete mode 100644 .idea/vcs.xml rename {.idea => Java/.idea}/checkstyle-idea.xml (100%) rename {.idea => Java/.idea}/compiler.xml (100%) rename {.idea => Java/.idea}/encodings.xml (100%) rename {.idea => Java/.idea}/libraries/junit_junit_4_12.xml (100%) rename {.idea => Java/.idea}/misc.xml (100%) rename {.idea => Java/.idea}/modules.xml (100%) rename {.idea => Java/.idea}/modules/Java.iml (100%) rename {.idea => Java/.idea}/modules/Java.main.iml (100%) rename {.idea => Java/.idea}/modules/Java.test.iml (100%) rename {.idea => Java/.idea}/project.iml (100%) rename {.idea => Java/.idea}/workspace.xml (79%) rename {acceptance tests => Java/acceptance tests}/in.txt (100%) rename {acceptance tests => Java/acceptance tests}/in1.txt (100%) rename {acceptance tests => Java/acceptance tests}/in2.txt (100%) rename {acceptance tests => Java/acceptance tests}/in3.txt (100%) rename {acceptance tests => Java/acceptance tests}/out.txt (100%) rename {acceptance tests => Java/acceptance tests}/out1.txt (100%) rename {acceptance tests => Java/acceptance tests}/out2.txt (100%) rename {acceptance tests => Java/acceptance tests}/out3.txt (100%) rename {acceptance tests => Java/acceptance tests}/out4.txt (100%) rename {acceptance tests => Java/acceptance tests}/stdout.txt (100%) rename {acceptance tests => Java/acceptance tests}/stdout1.txt (100%) rename {acceptance tests => Java/acceptance tests}/stdout2.txt (100%) rename {acceptance tests => Java/acceptance tests}/stdout3.txt (100%) rename {acceptance tests => Java/acceptance tests}/stdout4.txt (100%) rename {acceptance tests => Java/acceptance tests}/tests.ps1 (100%) mode change 100755 => 100644 rename {src => Java/src}/solver/Complex.java (100%) rename {src => Java/src}/solver/Main.java (100%) rename {src => Java/src}/solver/NumberSolutions.java (100%) rename {src => Java/src}/solver/Parameters.java (100%) rename {src => Java/src}/solver/Solver.java (100%) rename {test => Java/test}/ComplexTest.java (100%) rename {test => Java/test}/ParametersTest.java (100%) rename {test => Java/test}/SolverTest.java (100%) diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index c8397c9..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/checkstyle-idea.xml b/Java/.idea/checkstyle-idea.xml similarity index 100% rename from .idea/checkstyle-idea.xml rename to Java/.idea/checkstyle-idea.xml diff --git a/.idea/compiler.xml b/Java/.idea/compiler.xml similarity index 100% rename from .idea/compiler.xml rename to Java/.idea/compiler.xml diff --git a/.idea/encodings.xml b/Java/.idea/encodings.xml similarity index 100% rename from .idea/encodings.xml rename to Java/.idea/encodings.xml diff --git a/.idea/libraries/junit_junit_4_12.xml b/Java/.idea/libraries/junit_junit_4_12.xml similarity index 100% rename from .idea/libraries/junit_junit_4_12.xml rename to Java/.idea/libraries/junit_junit_4_12.xml diff --git a/.idea/misc.xml b/Java/.idea/misc.xml similarity index 100% rename from .idea/misc.xml rename to Java/.idea/misc.xml diff --git a/.idea/modules.xml b/Java/.idea/modules.xml similarity index 100% rename from .idea/modules.xml rename to Java/.idea/modules.xml diff --git a/.idea/modules/Java.iml b/Java/.idea/modules/Java.iml similarity index 100% rename from .idea/modules/Java.iml rename to Java/.idea/modules/Java.iml diff --git a/.idea/modules/Java.main.iml b/Java/.idea/modules/Java.main.iml similarity index 100% rename from .idea/modules/Java.main.iml rename to Java/.idea/modules/Java.main.iml diff --git a/.idea/modules/Java.test.iml b/Java/.idea/modules/Java.test.iml similarity index 100% rename from .idea/modules/Java.test.iml rename to Java/.idea/modules/Java.test.iml diff --git a/.idea/project.iml b/Java/.idea/project.iml similarity index 100% rename from .idea/project.iml rename to Java/.idea/project.iml diff --git a/.idea/workspace.xml b/Java/.idea/workspace.xml similarity index 79% rename from .idea/workspace.xml rename to Java/.idea/workspace.xml index 6d5960d..79b36ea 100644 --- a/.idea/workspace.xml +++ b/Java/.idea/workspace.xml @@ -2,12 +2,41 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -70,7 +99,7 @@ - + @@ -78,8 +107,8 @@ - - + + @@ -87,8 +116,8 @@ - - + + @@ -99,8 +128,8 @@ - - + + @@ -111,8 +140,8 @@ - - + + @@ -133,8 +162,8 @@ - - + + @@ -166,7 +195,7 @@ - - + @@ -199,6 +228,7 @@ + @@ -206,11 +236,6 @@ - - - - - @@ -236,7 +261,6 @@ - @@ -253,7 +277,7 @@ - + @@ -398,9 +422,8 @@ - - + @@ -430,6 +453,12 @@ + + + + + + @@ -445,9 +474,7 @@ - - - + @@ -493,33 +520,47 @@ + + + + + + + + + + + + + + - - + + - + - - + + - - + - - + + + @@ -533,28 +574,14 @@ - - + + - - - - - - - - - - - - - - diff --git a/acceptance tests/in.txt b/Java/acceptance tests/in.txt similarity index 100% rename from acceptance tests/in.txt rename to Java/acceptance tests/in.txt diff --git a/acceptance tests/in1.txt b/Java/acceptance tests/in1.txt similarity index 100% rename from acceptance tests/in1.txt rename to Java/acceptance tests/in1.txt diff --git a/acceptance tests/in2.txt b/Java/acceptance tests/in2.txt similarity index 100% rename from acceptance tests/in2.txt rename to Java/acceptance tests/in2.txt diff --git a/acceptance tests/in3.txt b/Java/acceptance tests/in3.txt similarity index 100% rename from acceptance tests/in3.txt rename to Java/acceptance tests/in3.txt diff --git a/acceptance tests/out.txt b/Java/acceptance tests/out.txt similarity index 100% rename from acceptance tests/out.txt rename to Java/acceptance tests/out.txt diff --git a/acceptance tests/out1.txt b/Java/acceptance tests/out1.txt similarity index 100% rename from acceptance tests/out1.txt rename to Java/acceptance tests/out1.txt diff --git a/acceptance tests/out2.txt b/Java/acceptance tests/out2.txt similarity index 100% rename from acceptance tests/out2.txt rename to Java/acceptance tests/out2.txt diff --git a/acceptance tests/out3.txt b/Java/acceptance tests/out3.txt similarity index 100% rename from acceptance tests/out3.txt rename to Java/acceptance tests/out3.txt diff --git a/acceptance tests/out4.txt b/Java/acceptance tests/out4.txt similarity index 100% rename from acceptance tests/out4.txt rename to Java/acceptance tests/out4.txt diff --git a/acceptance tests/stdout.txt b/Java/acceptance tests/stdout.txt similarity index 100% rename from acceptance tests/stdout.txt rename to Java/acceptance tests/stdout.txt diff --git a/acceptance tests/stdout1.txt b/Java/acceptance tests/stdout1.txt similarity index 100% rename from acceptance tests/stdout1.txt rename to Java/acceptance tests/stdout1.txt diff --git a/acceptance tests/stdout2.txt b/Java/acceptance tests/stdout2.txt similarity index 100% rename from acceptance tests/stdout2.txt rename to Java/acceptance tests/stdout2.txt diff --git a/acceptance tests/stdout3.txt b/Java/acceptance tests/stdout3.txt similarity index 100% rename from acceptance tests/stdout3.txt rename to Java/acceptance tests/stdout3.txt diff --git a/acceptance tests/stdout4.txt b/Java/acceptance tests/stdout4.txt similarity index 100% rename from acceptance tests/stdout4.txt rename to Java/acceptance tests/stdout4.txt diff --git a/acceptance tests/tests.ps1 b/Java/acceptance tests/tests.ps1 old mode 100755 new mode 100644 similarity index 100% rename from acceptance tests/tests.ps1 rename to Java/acceptance tests/tests.ps1 diff --git a/src/solver/Complex.java b/Java/src/solver/Complex.java similarity index 100% rename from src/solver/Complex.java rename to Java/src/solver/Complex.java diff --git a/src/solver/Main.java b/Java/src/solver/Main.java similarity index 100% rename from src/solver/Main.java rename to Java/src/solver/Main.java diff --git a/src/solver/NumberSolutions.java b/Java/src/solver/NumberSolutions.java similarity index 100% rename from src/solver/NumberSolutions.java rename to Java/src/solver/NumberSolutions.java diff --git a/src/solver/Parameters.java b/Java/src/solver/Parameters.java similarity index 100% rename from src/solver/Parameters.java rename to Java/src/solver/Parameters.java diff --git a/src/solver/Solver.java b/Java/src/solver/Solver.java similarity index 100% rename from src/solver/Solver.java rename to Java/src/solver/Solver.java diff --git a/test/ComplexTest.java b/Java/test/ComplexTest.java similarity index 100% rename from test/ComplexTest.java rename to Java/test/ComplexTest.java diff --git a/test/ParametersTest.java b/Java/test/ParametersTest.java similarity index 100% rename from test/ParametersTest.java rename to Java/test/ParametersTest.java diff --git a/test/SolverTest.java b/Java/test/SolverTest.java similarity index 100% rename from test/SolverTest.java rename to Java/test/SolverTest.java From e91062aba11074d8ac498e7d15a480888ca7b04e Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Thu, 3 Jan 2019 04:41:50 +0700 Subject: [PATCH 037/108] add Typescript port --- .gitignore | 6 + Typescript/acceptance tests/in.txt | 4 + Typescript/acceptance tests/in1.txt | 5 + Typescript/acceptance tests/in2.txt | 5 + Typescript/acceptance tests/in3.txt | 4 + Typescript/acceptance tests/out.txt | 1 + Typescript/acceptance tests/out1.txt | 1 + Typescript/acceptance tests/out2.txt | 1 + Typescript/acceptance tests/out3.txt | 1 + Typescript/acceptance tests/out4.txt | 1 + Typescript/acceptance tests/stdout.txt | Bin 0 -> 460 bytes Typescript/acceptance tests/stdout1.txt | Bin 0 -> 362 bytes Typescript/acceptance tests/stdout2.txt | Bin 0 -> 446 bytes Typescript/acceptance tests/stdout3.txt | Bin 0 -> 710 bytes Typescript/acceptance tests/stdout4.txt | 0 Typescript/acceptance tests/tests.ps1 | 89 ++++++++ Typescript/package.json | 23 ++ Typescript/spec/complex.spec.ts | 125 +++++++++++ Typescript/spec/parameters.spec.ts | 26 +++ Typescript/spec/solver.spec.ts | 276 +++++++++++++++++++++++ Typescript/spec/support/jasmine.json | 11 + Typescript/src/complex.ts | 79 +++++++ Typescript/src/main.ts | 11 + Typescript/src/numberSolutions.ts | 5 + Typescript/src/parameters.ts | 33 +++ Typescript/src/solver.ts | 283 ++++++++++++++++++++++++ Typescript/tsconfig.json | 58 +++++ Typescript/tslint.json | 18 ++ 28 files changed, 1066 insertions(+) create mode 100644 Typescript/acceptance tests/in.txt create mode 100644 Typescript/acceptance tests/in1.txt create mode 100644 Typescript/acceptance tests/in2.txt create mode 100644 Typescript/acceptance tests/in3.txt create mode 100644 Typescript/acceptance tests/out.txt create mode 100644 Typescript/acceptance tests/out1.txt create mode 100644 Typescript/acceptance tests/out2.txt create mode 100644 Typescript/acceptance tests/out3.txt create mode 100644 Typescript/acceptance tests/out4.txt create mode 100644 Typescript/acceptance tests/stdout.txt create mode 100644 Typescript/acceptance tests/stdout1.txt create mode 100644 Typescript/acceptance tests/stdout2.txt create mode 100644 Typescript/acceptance tests/stdout3.txt create mode 100644 Typescript/acceptance tests/stdout4.txt create mode 100644 Typescript/acceptance tests/tests.ps1 create mode 100644 Typescript/package.json create mode 100644 Typescript/spec/complex.spec.ts create mode 100644 Typescript/spec/parameters.spec.ts create mode 100644 Typescript/spec/solver.spec.ts create mode 100644 Typescript/spec/support/jasmine.json create mode 100644 Typescript/src/complex.ts create mode 100644 Typescript/src/main.ts create mode 100644 Typescript/src/numberSolutions.ts create mode 100644 Typescript/src/parameters.ts create mode 100644 Typescript/src/solver.ts create mode 100644 Typescript/tsconfig.json create mode 100644 Typescript/tslint.json diff --git a/.gitignore b/.gitignore index ee9a0c6..d2bbc65 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,12 @@ Java/out/ # Log file *.log +# Javascript files +*.js + +# node_modules +Typescript/node_modules/ + # BlueJ files *.ctxt diff --git a/Typescript/acceptance tests/in.txt b/Typescript/acceptance tests/in.txt new file mode 100644 index 0000000..b1db2cf --- /dev/null +++ b/Typescript/acceptance tests/in.txt @@ -0,0 +1,4 @@ +3 3 +1 1 2 9 +2 4 -3 1 +3 6 -5 0 diff --git a/Typescript/acceptance tests/in1.txt b/Typescript/acceptance tests/in1.txt new file mode 100644 index 0000000..112d10d --- /dev/null +++ b/Typescript/acceptance tests/in1.txt @@ -0,0 +1,5 @@ +3 4 +0 1 2 9 +0 1 3 1 +1 0 6 0 +2 0 2 0 \ No newline at end of file diff --git a/Typescript/acceptance tests/in2.txt b/Typescript/acceptance tests/in2.txt new file mode 100644 index 0000000..512957d --- /dev/null +++ b/Typescript/acceptance tests/in2.txt @@ -0,0 +1,5 @@ +4 4 +1 0 0 5 0 +0 0 0 0 0 +0 0 1 4 6 +0 0 5 5 5 \ No newline at end of file diff --git a/Typescript/acceptance tests/in3.txt b/Typescript/acceptance tests/in3.txt new file mode 100644 index 0000000..3b20f11 --- /dev/null +++ b/Typescript/acceptance tests/in3.txt @@ -0,0 +1,4 @@ +3 3 +1+2i -1.5-1.1i 2.12 91+5i +-1+3i 1.2+3.5i -3.3 1+15i +12.31 1.3-5i 12.3i -78.3i \ No newline at end of file diff --git a/Typescript/acceptance tests/out.txt b/Typescript/acceptance tests/out.txt new file mode 100644 index 0000000..fcb8c89 --- /dev/null +++ b/Typescript/acceptance tests/out.txt @@ -0,0 +1 @@ +(1, 2, 3) diff --git a/Typescript/acceptance tests/out1.txt b/Typescript/acceptance tests/out1.txt new file mode 100644 index 0000000..4a011fc --- /dev/null +++ b/Typescript/acceptance tests/out1.txt @@ -0,0 +1 @@ +There are no solutions diff --git a/Typescript/acceptance tests/out2.txt b/Typescript/acceptance tests/out2.txt new file mode 100644 index 0000000..fec4b4c --- /dev/null +++ b/Typescript/acceptance tests/out2.txt @@ -0,0 +1 @@ +(-8.3333, x2, -0.6667, 1.6667) diff --git a/Typescript/acceptance tests/out3.txt b/Typescript/acceptance tests/out3.txt new file mode 100644 index 0000000..2f10760 --- /dev/null +++ b/Typescript/acceptance tests/out3.txt @@ -0,0 +1 @@ +(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i) diff --git a/Typescript/acceptance tests/out4.txt b/Typescript/acceptance tests/out4.txt new file mode 100644 index 0000000..fcb8c89 --- /dev/null +++ b/Typescript/acceptance tests/out4.txt @@ -0,0 +1 @@ +(1, 2, 3) diff --git a/Typescript/acceptance tests/stdout.txt b/Typescript/acceptance tests/stdout.txt new file mode 100644 index 0000000000000000000000000000000000000000..fa91df995e062c04430baafa347883f23629b07a GIT binary patch literal 460 zcmaKpNe;p=3`PGMi92M;RG^L6u;38w36Lm*RGI>zaC+c7gG9x!u#?!&W1f!!7HgcT z6)rHS(Bgm^JH9RUD0!AR;Y!NVW9XZrj~;T~Z;Vkm(pS^hkgDFerQ;H0WJZ)6DfO7A zSQ4z9Een+9t4oO`QaaR>$Qk8-2JuRrZyCfU84}Dn$->=yC%%RbR^N-zzdDvGT}tMQ y9j9R~v3V+X^+^r5nF+bfX^o+aEx5~;+uzV*xow3lw_LeDG2FFfrxtgL{KpH&PBz*A literal 0 HcmV?d00001 diff --git a/Typescript/acceptance tests/stdout1.txt b/Typescript/acceptance tests/stdout1.txt new file mode 100644 index 0000000000000000000000000000000000000000..0b2e781bff418a1233d1dfc23030e19e0ad58c0f GIT binary patch literal 362 zcmZXQ%?iRW5QOI}_zpQMt+av%5g(%U1qAC4#6;V)`t<7Twh^g^Y?7TX8)n|G5&?VE ztOgA{EIM4^aN<4SjEZ}OJ6ckKil>%hiU|syAADnQrRJ#JNZB85J#ZPB4H9g*7g%aH zfpllu$yw*Bm=Ptk!Gf#j$1_CjXUIur$gD`^!%wR}O8$;irqoWo*6LUC5Z{gtV=C>} eeWQFypB}vDU3oH}-r~ikd#<78S=TkE6~~ZJvB<7_0CaOS;ui#YUGw zrwmoto%P(_s|cAzzjeZTYf;wehLdM+HJ^ufTQNgBrtTiLfhlu(z}JOY?3u9ve2)EM H+5G$h>H<-o literal 0 HcmV?d00001 diff --git a/Typescript/acceptance tests/stdout4.txt b/Typescript/acceptance tests/stdout4.txt new file mode 100644 index 0000000..e69de29 diff --git a/Typescript/acceptance tests/tests.ps1 b/Typescript/acceptance tests/tests.ps1 new file mode 100644 index 0000000..bfd3c75 --- /dev/null +++ b/Typescript/acceptance tests/tests.ps1 @@ -0,0 +1,89 @@ +#!/usr/bin/env pwsh +Describe TypescriptAcceptanceTests { + It 'single solution' { + Remove-Item "$PSScriptRoot/out.txt" -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/stdout.txt" -ErrorAction SilentlyContinue + + node ../src/main.js -in in.txt -out out.txt -verbose > "$PSScriptRoot/stdout.txt" + + [String[]]$lines = [System.IO.File]::ReadLines("$PSScriptRoot/out.txt") + $lines.Count | Should Be 1 + $lines[0] | Should Be "(1, 2, 3)" + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("$PSScriptRoot/stdout.txt") + [String[]]$expectedOutput = [String[]]("Start solving the equation.", + "Rows manipulation:", "-2 * R1 +R2 -> R2", "-3 * R1 +R3 -> R3", + "R2 / 2 -> R2", "-3 * R2 +R3 -> R3", "R3 / -0.5 -> R3", + "3.5 * R3 +R2 -> R2", "-2 * R3 +R1 -> R1", "-1 * R2 +R1 -> R1", + "(1, 2, 3)", "Saved to file out.txt") + [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + $areEqual | Should Be $true + } + + It 'no solution' { + Remove-Item "$PSScriptRoot/out1.txt" -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/stdout1.txt" -ErrorAction SilentlyContinue + + node ../src/main.js -in in1.txt -out out1.txt -verbose > "$PSScriptRoot/stdout1.txt" + + [String[]]$lines = [System.IO.File]::ReadLines("$PSScriptRoot/out1.txt") + $lines.Count | Should Be 1 + $lines[0] | Should Be "There are no solutions" + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("$PSScriptRoot/stdout1.txt") + [String[]]$expectedOutput = [String[]]("Start solving the equation.", + "Rows manipulation:", "R1 <-> R3", "-1 * R2 +R3 -> R3", "R3 / -1 -> R3", + "-3 * R3 +R2 -> R2", "-6 * R3 +R1 -> R1", "There are no solutions", "Saved to file out1.txt") + [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + $areEqual | Should Be $true + } + + It 'many solutions' { + Remove-Item "$PSScriptRoot/out2.txt" -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/stdout2.txt" -ErrorAction SilentlyContinue + + node ../src/main.js -in in2.txt -out out2.txt -verbose > "$PSScriptRoot/stdout2.txt" + + [String[]]$lines = [System.IO.File]::ReadLines("$PSScriptRoot/out2.txt") + $lines.Count | Should Be 1 + $lines[0] | Should Be "(-8.3333, x2, -0.6667, 1.6667)" + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("$PSScriptRoot/stdout2.txt") + [String[]]$expectedOutput = [String[]]("Start solving the equation.", + "Rows manipulation:", "C3 <-> C2", "R3 <-> R2", "-5 * R2 +R4 -> R4", + "C4 <-> C3", "R4 <-> R3", "R3 / -15 -> R3", "-4 * R3 +R2 -> R2", + "-5 * R3 +R1 -> R1", "(-8.3333, x2, -0.6667, 1.6667)","Saved to file out2.txt") + [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + $areEqual | Should Be $true + } + + It 'single solution complex numbers' { + Remove-Item "$PSScriptRoot/out3.txt" -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/stdout3.txt" -ErrorAction SilentlyContinue + + node ../src/main.js -in in3.txt -out out3.txt -verbose > "$PSScriptRoot/stdout3.txt" + + [String[]]$lines = [System.IO.File]::ReadLines("$PSScriptRoot/out3.txt") + $lines.Count | Should Be 1 + $lines[0] | Should Be "(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i)" + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("$PSScriptRoot/stdout3.txt") + [String[]]$expectedOutput = [String[]]("Start solving the equation.", + "Rows manipulation:", "R1 / 1+2i -> R1", "1-3i * R1 +R2 -> R2", "-12.31 * R1 +R3 -> R3", + "R2 / 1.6+6.1i -> R2", "-10.4094+9.6778i * R2 +R3 -> R3", "R3 / -6.7848+9.7158i -> R3", + "0.5432-0.746i * R3 +R2 -> R2", "-0.424+0.848i * R3 +R1 -> R1", "0.74-0.38i * R2 +R1 -> R1", + "(6.7334-22.9975i, -1.7976+2.084i, 15.6994+7.396i)", "Saved to file out3.txt") + [bool]$areEqual = @(Compare-Object $expectedOutput $stdoutLines -SyncWindow 0).Length -eq 0 + $areEqual | Should Be $true + } + + It 'no output without -verbose' { + Remove-Item "$PSScriptRoot/out4.txt" -ErrorAction SilentlyContinue + Remove-Item "$PSScriptRoot/stdout4.txt" -ErrorAction SilentlyContinue + + node ../src/main.js -in in.txt -out out4.txt > "$PSScriptRoot/stdout4.txt" + + [String[]]$stdoutLines = [System.IO.File]::ReadLines("$PSScriptRoot/stdout4.txt") + $stdoutLines.Count | Should Be 0 + } +} diff --git a/Typescript/package.json b/Typescript/package.json new file mode 100644 index 0000000..995d48e --- /dev/null +++ b/Typescript/package.json @@ -0,0 +1,23 @@ +{ + "name": "solution", + "version": "0.0.1", + "description": "", + "main": "./src/main.js", + "dependencies": { + "@types/jasmine": "3.3.5", + "@types/node": "10.12.18", + "jasmine": "3.3.1", + "npm-check-updates": "2.15.0", + "tslint": "5.12.0", + "typescript": "3.2.2", + "typescript-formatter": "7.2.2" + }, + "scripts": { + "start": "node ./src/main.js", + "build": "tsc", + "test": "jasmine", + "update": "ncu -u && npm update" + }, + "author": "fsb4000", + "license": "MIT" +} diff --git a/Typescript/spec/complex.spec.ts b/Typescript/spec/complex.spec.ts new file mode 100644 index 0000000..585f3d3 --- /dev/null +++ b/Typescript/spec/complex.spec.ts @@ -0,0 +1,125 @@ +import { Complex } from "../src/complex"; + +describe("complex tests", () => { + it("equals1", () => { + const a = new Complex(1, 2); + const b = new Complex(1, 2); + + expect(a.equals(b)).toBe(true); + }); + + it("toString1", () => { + const a = new Complex(1, 0); + + expect("1").toEqual(a.toString()); + }); + + it("toString2", () => { + const a = new Complex(0, 1); + + expect("1i").toEqual(a.toString()); + }); + + it("toString3", () => { + const a = new Complex(-2.4, 1.5); + + expect("-2.4+1.5i").toEqual(a.toString()); + }); + + it("toString4", () => { + const a = new Complex(2.4, -1.5); + + expect("2.4-1.5i").toEqual(a.toString()); + }); + + it("toString5", () => { + const a = new Complex(0, 0); + + expect("0").toEqual(a.toString()); + }); + + it("defaultConstructor", () => { + const c = new Complex(); + + expect(0).toBeCloseTo(c.getReal()); + expect(0).toBeCloseTo(c.getImag()); + }); + + it("constructor", () => { + const c = new Complex(1, 0); + + expect(1).toBeCloseTo(c.getReal()); + expect(0).toBeCloseTo(c.getImag()); + }); + + it("fromString1", () => { + const s = "-1.3"; + const c = Complex.fromString(s); + + expect(-1.3).toBeCloseTo(c.getReal()); + expect(0).toBeCloseTo(c.getImag()); + }); + + it("fromString2", () => { + const s = "2.5i"; + const c = Complex.fromString(s); + + expect(0).toBeCloseTo(c.getReal()); + expect(2.5).toBeCloseTo(c.getImag()); + }); + + it("fromString3", () => { + const s = "1.3-2.5i"; + const c = Complex.fromString(s); + + expect(1.3).toBeCloseTo(c.getReal()); + expect(-2.5).toBeCloseTo(c.getImag()); + }); + + it("fromString4", () => { + const s = "1"; + const c = Complex.fromString(s); + + expect(1).toBeCloseTo(c.getReal()); + expect(0).toBeCloseTo(c.getImag()); + }); + + it("fromString5", () => { + expect(Complex.fromString.bind("gdc")).toThrow(); + }); + + it("add", () => { + const a = new Complex(3, -5); + const b = new Complex(4, 2); + const c = Complex.add(a, b); + + expect(7).toBeCloseTo(c.getReal()); + expect(-3).toBeCloseTo(c.getImag()); + }); + + it("multiply", () => { + const a = new Complex(3, 2); + const b = new Complex(1, 7); + const c = Complex.multiply(a, b); + + expect(-11).toBeCloseTo(c.getReal()); + expect(23).toBeCloseTo(c.getImag()); + }); + + it("conjugate", () => { + const a = new Complex(3, 2); + const c = a.conjugate(); + + expect(3).toBeCloseTo(c.getReal()); + expect(-2).toBeCloseTo(c.getImag()); + }); + + it("divide", () => { + const a = new Complex(2, 3); + const b = new Complex(4, -5); + const c = Complex.divide(a, b); + + expect(-7 / 41).toBeCloseTo(c.getReal()); + expect(22 / 41).toBeCloseTo(c.getImag()); + }); +}); diff --git a/Typescript/spec/parameters.spec.ts b/Typescript/spec/parameters.spec.ts new file mode 100644 index 0000000..41702a4 --- /dev/null +++ b/Typescript/spec/parameters.spec.ts @@ -0,0 +1,26 @@ +import { Parameters } from "../src/parameters"; + +describe("parameters tests", () => { + it("defaultParameters", () => { + const p = new Parameters([]); + + expect(p.in).toBe("input.txt"); + expect(p.out).toBe("output.txt"); + expect(p.verbose).toBe(false); + }); + + it("in", () => { + const p = new Parameters(["-in", "in.txt"]); + expect(p.in).toBe("in.txt"); + }); + + it("out", () => { + const p = new Parameters(["-out", "out2.txt"]); + expect(p.out).toBe("out2.txt"); + }); + + it("verbose", () => { + const p = new Parameters(["-verbose"]); + expect(p.verbose).toBe(true); + }); +}); diff --git a/Typescript/spec/solver.spec.ts b/Typescript/spec/solver.spec.ts new file mode 100644 index 0000000..e75ec77 --- /dev/null +++ b/Typescript/spec/solver.spec.ts @@ -0,0 +1,276 @@ +import { Complex } from "../src/complex"; +import { NumberSolutions } from "../src/numberSolutions"; +import { Solver } from "../src/solver"; + +describe("solver tests", () => { + it("constructor1", () => { + const s = "1 1\n1 2"; + const p = new Solver(s); + + expect(p.getSize()).toBe(1); + }); + + it("constructor2", () => { + const s = "1 1\nab 2"; + + expect(Solver.bind(s)).toThrow(); + }); + + it("solve1", () => { + const s = "1 1\n2 4"; + const p = new Solver(s); + p.solve(); + + const expectedPartialSolution = [new Complex(2, 0)]; + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution === undefined || actualGeneralSolution !== undefined) { + fail(); + } else { + expect(NumberSolutions.ONE).toBe(p.getNumberSolutions()); + expect(expectedPartialSolution.length).toBe(actualPartialSolution.length); + for (let i = 0; i < expectedPartialSolution.length; i += 1) { + expect(expectedPartialSolution[i].equals(actualPartialSolution[i])).toBe(true); + } + expect(undefined).toBe(actualGeneralSolution); + } + }); + + it("solve2", () => { + const s = "2 2\n1 2 3\n4 5 6"; + const p = new Solver(s); + p.solve(); + + const expectedPartialSolution = [new Complex(-1, 0), new Complex(2, 0)]; + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution === undefined || actualGeneralSolution !== undefined) { + fail(); + } else { + expect(NumberSolutions.ONE).toBe(p.getNumberSolutions()); + expect(expectedPartialSolution.length).toBe(actualPartialSolution.length); + for (let i = 0; i < expectedPartialSolution.length; i += 1) { + expect(expectedPartialSolution[i].equals(actualPartialSolution[i])).toBe(true); + } + expect(undefined).toBe(actualGeneralSolution); + } + }); + + it("solve3", () => { + const s = "2 2\n4 5 7\n3 9 9"; + const p = new Solver(s); + p.solve(); + + const expectedPartialSolution = [new Complex(0.85714, 0), new Complex(0.71429, 0)]; + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution === undefined || actualGeneralSolution !== undefined) { + fail(); + } else { + expect(NumberSolutions.ONE).toBe(p.getNumberSolutions()); + expect(expectedPartialSolution.length).toBe(actualPartialSolution.length); + for (let i = 0; i < expectedPartialSolution.length; i += 1) { + expect(expectedPartialSolution[i].equals(actualPartialSolution[i])).toBe(true); + } + expect(undefined).toBe(actualGeneralSolution); + } + }); + + it("solve4", () => { + const s = "3 3\n1 1 2 9\n2 4 -3 1\n3 6 -5 0"; + const p = new Solver(s); + p.solve(); + + const expectedPartialSolution = [new Complex(1, 0), new Complex(2, 0), new Complex(3, 0)]; + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution === undefined || actualGeneralSolution !== undefined) { + fail(); + } else { + expect(NumberSolutions.ONE).toBe(p.getNumberSolutions()); + expect(expectedPartialSolution.length).toBe(actualPartialSolution.length); + for (let i = 0; i < expectedPartialSolution.length; i += 1) { + expect(expectedPartialSolution[i].equals(actualPartialSolution[i])).toBe(true); + } + expect(undefined).toBe(actualGeneralSolution); + } + }); + + it("solve5", () => { + const s = "2 2\n0 1 1\n1 0 1"; + const p = new Solver(s); + p.solve(); + + const expectedPartialSolution = [new Complex(1, 0), new Complex(1, 0)]; + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution === undefined || actualGeneralSolution !== undefined) { + fail(); + } else { + expect(NumberSolutions.ONE).toBe(p.getNumberSolutions()); + expect(expectedPartialSolution.length).toBe(actualPartialSolution.length); + for (let i = 0; i < expectedPartialSolution.length; i += 1) { + expect(expectedPartialSolution[i].equals(actualPartialSolution[i])).toBe(true); + } + expect(undefined).toBe(actualGeneralSolution); + } + }); + + it("solve6", () => { + const s = "2 2\n0 1 1\n0 2 2"; + const p = new Solver(s); + p.solve(); + + const expectedPartialSolution = [new Complex(0, 0), new Complex(1, 0)]; + const expectedGeneralSolution = ["x1", "1"]; + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution === undefined || actualGeneralSolution === undefined) { + fail(); + } else { + expect(NumberSolutions.MANY).toBe(p.getNumberSolutions()); + expect(expectedPartialSolution.length).toBe(actualPartialSolution.length); + for (let i = 0; i < expectedPartialSolution.length; i += 1) { + expect(expectedPartialSolution[i].equals(actualPartialSolution[i])).toBe(true); + } + expect(expectedGeneralSolution).toEqual(actualGeneralSolution); + } + }); + + it("solve7", () => { + const s = "2 2\n0 1 1\n0 2 3"; + const p = new Solver(s); + p.solve(); + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution !== undefined || actualGeneralSolution !== undefined) { + fail(); + } else { + expect(NumberSolutions.NONE).toBe(p.getNumberSolutions()); + } + }); + + it("solve8", () => { + const s = "3 4\n0 1 2 9\n0 1 3 1\n1 0 6 0\n2 0 2 0"; + const p = new Solver(s); + p.solve(); + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution !== undefined || actualGeneralSolution !== undefined) { + fail(); + } else { + expect(NumberSolutions.NONE).toBe(p.getNumberSolutions()); + } + }); + + it("solve9", () => { + const s = "3 1\n1 1 2 9"; + const p = new Solver(s); + p.solve(); + + const expectedPartialSolution = [new Complex(9, 0), new Complex(0, 0), new Complex(0, 0)]; + const expectedGeneralSolution = ["9 - x2 - x3 * (2)", "x2", "x3"]; + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution === undefined || actualGeneralSolution === undefined) { + fail(); + } else { + expect(NumberSolutions.MANY).toBe(p.getNumberSolutions()); + expect(expectedPartialSolution.length).toBe(actualPartialSolution.length); + for (let i = 0; i < expectedPartialSolution.length; i += 1) { + expect(expectedPartialSolution[i].equals(actualPartialSolution[i])).toBe(true); + } + expect(expectedGeneralSolution).toEqual(actualGeneralSolution); + } + }); + + it("solve10", () => { + const s = "4 4\n1 0 0 5 0\n0 0 0 0 0\n0 0 1 4 6\n0 0 5 5 5"; + const p = new Solver(s); + p.solve(); + + const expectedPartialSolution = + [new Complex(-8.3333333, 0), new Complex(0, 0), new Complex(-0.6666667, 0), new Complex(1.6666667, 0)]; + const expectedGeneralSolution = ["-8.3333", "x2", "-0.6667", "1.6667"]; + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution === undefined || actualGeneralSolution === undefined) { + fail(); + } else { + expect(NumberSolutions.MANY).toBe(p.getNumberSolutions()); + expect(expectedPartialSolution.length).toBe(actualPartialSolution.length); + for (let i = 0; i < expectedPartialSolution.length; i += 1) { + expect(expectedPartialSolution[i].equals(actualPartialSolution[i])).toBe(true); + } + expect(expectedGeneralSolution).toEqual(actualGeneralSolution); + } + }); + + it("solve11", () => { + const s = "4 4\n2 3 -1 1 1\n8 12 -9 8 3\n4 6 3 -2 3\n2 3 9 -7 3"; + const p = new Solver(s); + p.solve(); + + const expectedPartialSolution = + [new Complex(0.6, 0), new Complex(0, 0), new Complex(0.2, 0), new Complex(0, 0)]; + const expectedGeneralSolution = + ["0.6 - x2 * (1.5) - x4 * (0.1)", "x2", "0.2 - x4 * (-0.8)", "x4"]; + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution === undefined || actualGeneralSolution === undefined) { + fail(); + } else { + expect(NumberSolutions.MANY).toBe(p.getNumberSolutions()); + expect(expectedPartialSolution.length).toBe(actualPartialSolution.length); + for (let i = 0; i < expectedPartialSolution.length; i += 1) { + expect(expectedPartialSolution[i].equals(actualPartialSolution[i])).toBe(true); + } + expect(expectedGeneralSolution).toEqual(actualGeneralSolution); + } + }); + + it("solve12", () => { + const s = "3 3\n1+2i -1.5-1.1i 2.12 91+5i\n-1+3i 1.2+3.5i -3.3 1+15i\n12.31 1.3-5i 12.3i -78.3i"; + const p = new Solver(s); + p.solve(); + + const expectedPartialSolution = [new Complex(6.73335286, -22.99754223), + new Complex(-1.7976071, 2.08404919), new Complex(15.69938581, 7.3960106)]; + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution === undefined || actualGeneralSolution !== undefined) { + fail(); + } else { + expect(NumberSolutions.ONE).toBe(p.getNumberSolutions()); + expect(expectedPartialSolution.length).toBe(actualPartialSolution.length); + for (let i = 0; i < expectedPartialSolution.length; i += 1) { + expect(expectedPartialSolution[i].equals(actualPartialSolution[i])).toBe(true); + } + expect(undefined).toBe(actualGeneralSolution); + } + }); +}); diff --git a/Typescript/spec/support/jasmine.json b/Typescript/spec/support/jasmine.json new file mode 100644 index 0000000..c6cd880 --- /dev/null +++ b/Typescript/spec/support/jasmine.json @@ -0,0 +1,11 @@ +{ + "spec_dir": "spec", + "spec_files": [ + "*.spec.js" + ], + "helpers": [ + "helpers/**/*.js" + ], + "stopSpecOnExpectationFailure": false, + "random": true +} diff --git a/Typescript/src/complex.ts b/Typescript/src/complex.ts new file mode 100644 index 0000000..0f9c4aa --- /dev/null +++ b/Typescript/src/complex.ts @@ -0,0 +1,79 @@ +const split = (s: string): string[] => { + let realString = "0"; + let imagString = "0"; + let i = 1; + for (; i < s.length; i += 1) { + if (s.charAt(i) === "+" || s.charAt(i) === "-") { + realString = s.substring(0, i); + imagString = s.substring(i, s.length - 1); + break; + } + if (s.charAt(i) === "i") { + imagString = s.substring(0, i); + break; + } + } + if (i === s.length) { + realString = s; + } + + return [realString, imagString]; +}; + +export class Complex { + public static readonly EPSILON = 0.00001; + + public static readonly add = (a: Complex, b: Complex) => + new Complex(a.real + b.real, a.imag + b.imag) + + public static readonly divide = (a: Complex, b: Complex): Complex => { + const bConjugate = b.conjugate(); + const a1 = Complex.multiply(a, bConjugate); + const b1 = Complex.multiply(b, bConjugate); + + return new Complex(a1.real / b1.real, a1.imag / b1.real); + } + + public static readonly fromString = (s: string): Complex => { + const strs = split(s); + const real = Number.parseFloat(strs[0]); + const imag = Number.parseFloat(strs[1]); + + return new Complex(real, imag); + } + + public static readonly multiply = (a: Complex, b: Complex) => + new Complex(a.real * b.real - a.imag * b.imag, a.real * b.imag + a.imag * b.real) + + private imag: number; + private real: number; + public constructor(real = 0, imag = 0) { + this.real = real; + this.imag = imag; + } + + public readonly conjugate = () => new Complex(this.real, -this.imag); + + public readonly equals = (o: Complex): boolean => + Math.abs(o.imag - this.imag) < Complex.EPSILON && + Math.abs(o.real - this.real) < Complex.EPSILON + + public readonly getImag = () => this.imag; + + public readonly getReal = () => this.real; + + public readonly toString = (): string => { + const real = (Math.round(this.real * 10000) / 10000).toString(); + const imag = (Math.round(this.imag * 10000) / 10000).toString(); + + if (Math.abs(this.imag) < Complex.EPSILON) { + return real; + } + if (Math.abs(this.real) < Complex.EPSILON) { + return `${imag}i`; + } + const prefix = (this.imag > 0) ? "+" : ""; + + return `${real}${prefix}${imag}i`; + } +} diff --git a/Typescript/src/main.ts b/Typescript/src/main.ts new file mode 100644 index 0000000..6300e44 --- /dev/null +++ b/Typescript/src/main.ts @@ -0,0 +1,11 @@ +import * as fs from "fs"; +import { Parameters } from "./parameters"; +import { Solver } from "./solver"; +try { + const p = new Parameters(process.argv); + const s = new Solver(fs.readFileSync(p.in, "utf8"), p.verbose); + s.solve(); + s.writeSolutionToFile(p.out); +} catch (e) { + console.error(`An exception occurs ${(e as Error).message}`); +} diff --git a/Typescript/src/numberSolutions.ts b/Typescript/src/numberSolutions.ts new file mode 100644 index 0000000..0401fb6 --- /dev/null +++ b/Typescript/src/numberSolutions.ts @@ -0,0 +1,5 @@ +export enum NumberSolutions { + NONE, + ONE, + MANY, +} diff --git a/Typescript/src/parameters.ts b/Typescript/src/parameters.ts new file mode 100644 index 0000000..a63ce97 --- /dev/null +++ b/Typescript/src/parameters.ts @@ -0,0 +1,33 @@ +export class Parameters { + public readonly in: string; + public readonly out: string; + public readonly verbose: boolean; + + public constructor(args: string[]) { + let needAssignedIn = true; + let inTemp = "input.txt"; + let needAssignedOut = true; + let outTemp = "output.txt"; + let verboseTemp = false; + for (let i = 0; i < args.length; i += 1) { + if (needAssignedIn && args[i] === "-in") { + if (i < args.length - 1) { + inTemp = args[i + 1]; + needAssignedIn = false; + i += 1; + } + } else if (needAssignedOut && args[i] === "-out") { + if (i < args.length - 1) { + outTemp = args[i + 1]; + needAssignedOut = false; + i += 1; + } + } else if (!verboseTemp && args[i] === "-verbose") { + verboseTemp = true; + } + } + this.in = inTemp; + this.out = outTemp; + this.verbose = verboseTemp; + } +} diff --git a/Typescript/src/solver.ts b/Typescript/src/solver.ts new file mode 100644 index 0000000..2ed3374 --- /dev/null +++ b/Typescript/src/solver.ts @@ -0,0 +1,283 @@ +import * as fs from "fs"; +import * as os from "os"; +import { Complex } from "./complex"; +import { NumberSolutions } from "./numberSolutions"; + +export class Solver { + private static readonly MINUS_ONE = new Complex(-1, 0); + private static readonly ONE = new Complex(1, 0); + private static readonly ZERO = new Complex(0, 0); + + private readonly matrix: Complex[][]; + private readonly numberEquations: number; + private numberSolutions = NumberSolutions.ONE; + private readonly numberVariables: number; + private readonly solutionGeneral: string[]; + private readonly solutionIndexes: number[]; + private readonly solutionParticular: Complex[]; + private readonly verbose: boolean; + + public constructor(s: string, verbose = false) { + const args = s.split(new RegExp("\n| ")); + let argsI = 0; + this.numberVariables = Number.parseInt(args[argsI], 10); + argsI += 1; + const realNumberEquations = Number.parseInt(args[argsI], 10); + argsI += 1; + this.numberEquations = (realNumberEquations < this.numberVariables) ? this.numberVariables + : realNumberEquations; + this.matrix = []; + for (let i = 0; i < realNumberEquations; i += 1) { + this.matrix.push(new Array(this.numberVariables + 1)); + for (let j = 0; j < this.numberVariables + 1; j += 1) { + this.matrix[i][j] = Complex.fromString(args[argsI]); + argsI += 1; + } + } + for (let i = realNumberEquations; i < this.numberEquations; i += 1) { + this.matrix.push(new Array(this.numberVariables + 1)); + for (let j = 0; j < this.numberVariables + 1; j += 1) { + this.matrix[i][j] = new Complex(); + } + } + this.solutionParticular = new Array(this.numberVariables); + this.solutionGeneral = new Array(this.numberVariables); + this.solutionIndexes = new Array(this.numberVariables); + for (let i = 0; i < this.numberVariables; i += 1) { + this.solutionIndexes[i] = i; + } + this.verbose = verbose; + } + + public readonly getNumberSolutions = () => this.numberSolutions; + + public readonly getSize = () => this.matrix.length; + + public readonly getSolutionGeneral = (): string[] | undefined => { + if (this.numberSolutions !== NumberSolutions.MANY) { + return undefined; + } + + return this.solutionGeneral; + } + + public readonly getSolutionPartial = (): Complex[] | undefined => { + if (this.numberSolutions === NumberSolutions.NONE) { + return undefined; + } + + return this.solutionParticular; + } + + public readonly solve = (): void => { + if (this.verbose) { + console.log("Start solving the equation."); + console.log("Rows manipulation:"); + } + this.gausFirstStep(); + if (this.numberSolutions !== NumberSolutions.NONE) { + this.gausSecondStep(); + this.generateSolutions(); + this.checkThatSolutionIsSane(); + } + this.printSolution(); + } + + public readonly writeSolutionToFile = (out: string): void => { + const file = fs.createWriteStream(out); + this.printSolutionInternal(file); + file.close(); + if (this.verbose) { + console.log(`Saved to file ${out}`); + } + } + + private readonly addKRow1ToRow2 = (k: Complex, row1: number, row2: number): void => { + if (this.verbose) { + console.log(`${k.toString()} * R${row1 + 1} +R${row2 + 1} -> R${row2 + 1}`); + } + for (let i = 0; i < this.numberVariables + 1; i += 1) { + const temp = Complex.multiply(k, this.matrix[row1][i]); + this.matrix[row2][i] = Complex.add(temp, this.matrix[row2][i]); + } + } + + private readonly checkThatSolutionIsSane = (): void => { + for (let i = this.numberVariables; i < this.numberEquations; i += 1) { + let sum = new Complex(0, 0); + for (let j = 0; j < this.numberVariables; j += 1) { + const temp = Complex.multiply( + this.solutionParticular[this.solutionIndexes[j]], + this.matrix[i][this.solutionIndexes[j]]); + sum = Complex.add(sum, temp); + } + if (!sum.equals(this.matrix[i][this.numberVariables])) { + this.numberSolutions = NumberSolutions.NONE; + + return; + } + } + } + + private readonly divideRow = (row: number, k: Complex): void => { + if (this.verbose) { + console.log(`R${row + 1} / ${k.toString()} -> R${row + 1}`); + } + const n = this.matrix[row].length; + for (let i = 0; i < n; i += 1) { + this.matrix[row][i] = Complex.divide(this.matrix[row][i], k); + } + } + + private readonly gausFirstStep = (): void => { + for (let i = 0; i < this.numberVariables; i += 1) { + if (this.matrix[i][i].equals(Solver.ZERO)) { + let foundNonZeroElement = false; + for (let j = i + 1; j < this.numberEquations; j += 1) { + if (!this.matrix[j][i].equals(Solver.ZERO)) { + this.swapRows(i, j); + foundNonZeroElement = true; + break; + } + } + if (!foundNonZeroElement) { + for (let j = i + 1; j < this.numberEquations; j += 1) { + if (!this.matrix[i][j].equals(Solver.ZERO)) { + this.swapColumns(i, j); + foundNonZeroElement = true; + break; + } + } + } + + if (!foundNonZeroElement) { + for (let k = i + 1; !foundNonZeroElement && k < this.numberVariables; k += 1) { + for (let j = i + 1; j < this.numberEquations; j += 1) { + if (!this.matrix[j][k].equals(Solver.ZERO)) { + this.swapColumns(k, i); + this.swapRows(j, i); + foundNonZeroElement = true; + break; + } + } + } + } + + if (!foundNonZeroElement) { + if (this.matrix[i][this.numberEquations].equals(Solver.ZERO)) { + this.numberSolutions = NumberSolutions.MANY; + continue; + } else { + this.numberSolutions = NumberSolutions.NONE; + + return; + } + } + } + + if (!this.matrix[i][i].equals(Solver.ONE)) { + this.divideRow(i, this.matrix[i][i]); + } + for (let j = i + 1; j < this.numberEquations && j < this.numberVariables; j += 1) { + const k = Complex.multiply(Solver.MINUS_ONE, this.matrix[j][i]); + if (!k.equals(Solver.ZERO)) { + this.addKRow1ToRow2(k, i, j); + } + } + } + } + + private readonly gausSecondStep = (): void => { + for (let i = this.numberVariables - 1; i >= 0; i -= 1) { + for (let j = i - 1; j >= 0; j -= 1) { + const k = Complex.multiply(Solver.MINUS_ONE, this.matrix[j][i]); + if (!k.equals(Solver.ZERO)) { + this.addKRow1ToRow2(k, i, j); + } + } + } + } + + private readonly generateSolutions = (): void => { + for (let i = 0; i < this.numberEquations && i < this.numberVariables; i += 1) { + this.solutionParticular[this.solutionIndexes[i]] = this.matrix[i][this.numberVariables]; + if (this.matrix[i][i].equals(Solver.ZERO)) { + this.solutionGeneral[this.solutionIndexes[i]] = `x${this.solutionIndexes[i] + 1}`; + } else { + this.solutionGeneral[this.solutionIndexes[i]] = this.matrix[i][this.numberVariables].toString(); + for (let j = i + 1; j < this.numberVariables; j += 1) { + if (this.matrix[i][j].equals(Solver.ONE)) { + this.solutionGeneral[this.solutionIndexes[i]] = + `${this.solutionGeneral[this.solutionIndexes[i]]} - x${this.solutionIndexes[j] + 1}`; + } else if (!this.matrix[i][j].equals(Solver.ZERO)) { + this.solutionGeneral[this.solutionIndexes[i]] = + // tslint:disable-next-line:max-line-length + `${this.solutionGeneral[this.solutionIndexes[i]]} - x${this.solutionIndexes[j] + 1} * (${this.matrix[i][j].toString()})`; + } + } + } + } + } + + private readonly printSolution = (): void => { + if (this.verbose) { + this.printSolutionInternal(); + } + } + + private readonly printSolutionInternal = (writer: fs.WriteStream | undefined = undefined): void => { + let result: string; + switch (this.numberSolutions) { + case NumberSolutions.NONE: + result = "There are no solutions"; + break; + case NumberSolutions.ONE: + result = `(${this.solutionParticular[0].toString()}`; + for (let i = 1; i < this.solutionParticular.length; i += 1) { + result += `, ${this.solutionParticular[i].toString()}`; + } + result += ")"; + break; + case NumberSolutions.MANY: + result = `(${this.solutionGeneral[0]}`; + for (let i = 1; i < this.solutionParticular.length; i += 1) { + result += `, ${this.solutionGeneral[i]}`; + } + result += ")"; + break; + default: + throw new Error("Never should happend"); + } + if (writer instanceof fs.WriteStream) { + writer.end(`${result}${os.EOL}`); + } else { + console.log(result); + } + } + + private readonly swapColumns = (column1: number, column2: number): void => { + if (this.verbose) { + console.log(`C${column1 + 1} <-> C${column2 + 1}`); + } + const n = this.matrix.length; + for (let i = 0; i < n; i += 1) { + const temp1 = this.matrix[i][column1]; + this.matrix[i][column1] = this.matrix[i][column2]; + this.matrix[i][column2] = temp1; + } + const temp2 = this.solutionIndexes[column1]; + this.solutionIndexes[column1] = this.solutionIndexes[column2]; + this.solutionIndexes[column2] = temp2; + } + + private readonly swapRows = (row1: number, row2: number): void => { + if (this.verbose) { + console.log(`R${row1 + 1} <-> R${row2 + 1}`); + } + for (let i = 0; i < this.numberVariables + 1; i += 1) { + const temp = this.matrix[row1][i]; + this.matrix[row1][i] = this.matrix[row2][i]; + this.matrix[row2][i] = temp; + } + } +} diff --git a/Typescript/tsconfig.json b/Typescript/tsconfig.json new file mode 100644 index 0000000..bc59330 --- /dev/null +++ b/Typescript/tsconfig.json @@ -0,0 +1,58 @@ +{ + "compilerOptions": { + /* Basic Options */ + "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + + /* Source Map Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + }, + "exclude": [ "node_modules"] +} \ No newline at end of file diff --git a/Typescript/tslint.json b/Typescript/tslint.json new file mode 100644 index 0000000..2db6819 --- /dev/null +++ b/Typescript/tslint.json @@ -0,0 +1,18 @@ +{ + "defaultSeverity": "error", + "extends": [ + "tslint:all" + ], + "jsRules": {}, + "rules": { + "no-console": false, + "no-empty": false, + "typedef": false, + "linebreak-style": false, + "no-bitwise": false, + "no-magic-numbers": false, + "newline-per-chained-call": false, + "no-require-imports": false + }, + "rulesDirectory": [] +} From 2a2b03376e362d90d03f7cb4fec879a5ad95d610 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Thu, 3 Jan 2019 04:44:32 +0700 Subject: [PATCH 038/108] ignore package-lock.json --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index d2bbc65..b4eeaaf 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ Java/out/ # node_modules Typescript/node_modules/ +# package-lock +Typescript/package-lock.json + # BlueJ files *.ctxt From 8667c3900780328fdfdf30480995d7f1ebbfa8d6 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Wed, 2 Jan 2019 17:08:04 -0500 Subject: [PATCH 039/108] refactoring --- .../org_jetbrains_annotations_16_0_3.xml | 10 ++ Java/.idea/project.iml | 1 + Java/.idea/workspace.xml | 119 +++++++++--------- Java/acceptance tests/out.txt | 2 +- Java/acceptance tests/out1.txt | 2 +- Java/acceptance tests/out2.txt | 2 +- Java/acceptance tests/out3.txt | 2 +- Java/acceptance tests/out4.txt | 2 +- Java/acceptance tests/stdout.txt | Bin 460 -> 217 bytes Java/acceptance tests/stdout1.txt | Bin 362 -> 171 bytes Java/acceptance tests/stdout2.txt | Bin 446 -> 210 bytes Java/acceptance tests/stdout3.txt | Bin 710 -> 341 bytes Java/acceptance tests/tests.ps1 | 0 Typescript/acceptance tests/out.txt | 2 +- Typescript/acceptance tests/out1.txt | 2 +- Typescript/acceptance tests/out2.txt | 2 +- Typescript/acceptance tests/out3.txt | 2 +- Typescript/acceptance tests/out4.txt | 2 +- Typescript/acceptance tests/stdout.txt | Bin 460 -> 217 bytes Typescript/acceptance tests/stdout1.txt | Bin 362 -> 171 bytes Typescript/acceptance tests/stdout2.txt | Bin 446 -> 210 bytes Typescript/acceptance tests/stdout3.txt | Bin 710 -> 341 bytes Typescript/acceptance tests/tests.ps1 | 0 23 files changed, 78 insertions(+), 72 deletions(-) create mode 100644 Java/.idea/libraries/org_jetbrains_annotations_16_0_3.xml mode change 100644 => 100755 Java/acceptance tests/tests.ps1 mode change 100644 => 100755 Typescript/acceptance tests/tests.ps1 diff --git a/Java/.idea/libraries/org_jetbrains_annotations_16_0_3.xml b/Java/.idea/libraries/org_jetbrains_annotations_16_0_3.xml new file mode 100644 index 0000000..1e76a4d --- /dev/null +++ b/Java/.idea/libraries/org_jetbrains_annotations_16_0_3.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Java/.idea/project.iml b/Java/.idea/project.iml index e77ad25..9362fd9 100644 --- a/Java/.idea/project.iml +++ b/Java/.idea/project.iml @@ -17,5 +17,6 @@ + \ No newline at end of file diff --git a/Java/.idea/workspace.xml b/Java/.idea/workspace.xml index 79b36ea..b3bc298 100644 --- a/Java/.idea/workspace.xml +++ b/Java/.idea/workspace.xml @@ -93,22 +93,32 @@ + + + + + + + + + + - + - + - + - - + + @@ -116,7 +126,7 @@ - + @@ -128,7 +138,7 @@ - + @@ -140,7 +150,7 @@ - + @@ -153,7 +163,7 @@ - + @@ -162,7 +172,7 @@ - + @@ -228,7 +238,7 @@ - + @@ -260,7 +270,7 @@ - + @@ -414,34 +406,34 @@ - + - + - + - + - + - + - + - + - + - + @@ -458,7 +450,7 @@ - + @@ -466,7 +458,7 @@ - + @@ -519,10 +511,17 @@ + + + + + + + - - + + @@ -531,7 +530,7 @@ - + @@ -539,35 +538,37 @@ - + - - - - - - + + - + + + + - - + + - + - - + + + + + - - + + @@ -576,26 +577,14 @@ - - + + - - - - - - - - - - - - diff --git a/Java/test/SolverTest.java b/Java/test/SolverTest.java index 43f0c8a..03023f7 100644 --- a/Java/test/SolverTest.java +++ b/Java/test/SolverTest.java @@ -7,6 +7,45 @@ import java.util.Scanner; public class SolverTest { + + @Test + public void types1() { + final Scanner sc = new Scanner("1 1\r\n2 4"); + final Solver p = new Solver(sc); + p.solve(); + + NumberSolutions n = p.getNumberSolutions(); + Assert.assertEquals(NumberSolutions.ONE, n); + n = NumberSolutions.MANY; + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); + } + + @Test + public void types2() { + final Scanner sc = new Scanner("1 1\r\n2 4"); + final Solver p = new Solver(sc); + p.solve(); + + Complex[] array = p.getSolutionPartial(); + Assert.assertEquals(array[0], new Complex(2.0, 0.0)); + array[0] = new Complex(); + array = p.getSolutionPartial(); + Assert.assertEquals(array[0], new Complex(2.0, 0.0)); + } + + @Test + public void types3() { + final Scanner sc = new Scanner("1 1\r\n0 0"); + final Solver p = new Solver(sc); + p.solve(); + + String[] array = p.getSolutionGeneral(); + Assert.assertEquals(array[0], "x1"); + array[0] = "hello"; + array = p.getSolutionGeneral(); + Assert.assertEquals(array[0], "x1"); + } + @Test public void constructor1() { try { @@ -282,4 +321,17 @@ public void solve13() { Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } + + @Test + public void solve14() { + final Scanner sc = new Scanner("1 1\r\n2 4"); + final Solver p = new Solver(sc); + p.solve(); + + final Complex[] expectedPartialSolution = new Complex[]{new Complex(2.0, 0)}; + + Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); + Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); + Assert.assertArrayEquals(null, p.getSolutionGeneral()); + } } diff --git a/Typescript/spec/solver.spec.ts b/Typescript/spec/solver.spec.ts index dff6d7b..f70b7cd 100644 --- a/Typescript/spec/solver.spec.ts +++ b/Typescript/spec/solver.spec.ts @@ -3,6 +3,48 @@ import { NumberSolutions } from "../src/numberSolutions"; import { Solver } from "../src/solver"; describe("solver tests", () => { + it("types1", () => { + const f = () => { + const p = new Solver("1 1\n1 2"); + p.solve(); + let n = p.getNumberSolutions(); + expect(n).toBe(NumberSolutions.ONE); + n = NumberSolutions.MANY; + expect(p.getNumberSolutions()).toBe(NumberSolutions.ONE); + }; + expect(f).not.toThrow(); + }); + + it("types2", () => { + const f = () => { + const p = new Solver("1 1\n1 2"); + p.solve(); + let array = p.getSolutionPartial(); + const expected = new Complex(2.0, 0.0); + expect(array !== undefined).toBe(true); + expect(expected.equals(array![0])).toBe(true); + array![0] = new Complex(); + array = p.getSolutionPartial(); + expect(expected.equals(array![0])).toBe(true); + }; + expect(f).not.toThrow(); + }); + + it("types3", () => { + const f = () => { + const p = new Solver("1 1\n0 0"); + p.solve(); + let array = p.getSolutionGeneral(); + const expected = "x1"; + expect(array !== undefined).toBe(true); + expect(expected).toBe(array![0]); + array![0] = "hello"; + array = p.getSolutionGeneral(); + expect(expected).toBe(array![0]); + }; + expect(f).not.toThrow(); + }); + it("constructor1", () => { const f = () => new Solver("1 1\n2 2"); expect(f).not.toThrow(); @@ -339,4 +381,26 @@ describe("solver tests", () => { expect(undefined).toBe(actualGeneralSolution); } }); + + it("solve14", () => { + const s = "1 1\r\n2 4"; + const p = new Solver(s); + p.solve(); + + const expectedPartialSolution = [new Complex(2, 0)]; + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution === undefined || actualGeneralSolution !== undefined) { + fail(); + } else { + expect(NumberSolutions.ONE).toBe(p.getNumberSolutions()); + expect(expectedPartialSolution.length).toBe(actualPartialSolution.length); + for (let i = 0; i < expectedPartialSolution.length; i += 1) { + expect(expectedPartialSolution[i].equals(actualPartialSolution[i])).toBe(true); + } + expect(undefined).toBe(actualGeneralSolution); + } + }); }); diff --git a/Typescript/src/solver.ts b/Typescript/src/solver.ts index 4318866..e829b0b 100644 --- a/Typescript/src/solver.ts +++ b/Typescript/src/solver.ts @@ -59,7 +59,7 @@ export class Solver { return undefined; } - return this.solutionGeneral; + return Object.assign([], this.solutionGeneral); } public readonly getSolutionPartial = (): Complex[] | undefined => { @@ -67,7 +67,7 @@ export class Solver { return undefined; } - return this.solutionPartial; + return Object.assign([], this.solutionPartial); } public readonly solve = (): void => { diff --git a/Vala/test/solver.test.vala b/Vala/test/solver.test.vala index 4b54777..fe0bc64 100644 --- a/Vala/test/solver.test.vala +++ b/Vala/test/solver.test.vala @@ -20,6 +20,56 @@ void solver_tests () { Test.add_func ( "/solve11_solver_test", solve11_solver_test ); Test.add_func ( "/solve12_solver_test", solve12_solver_test ); Test.add_func ( "/solve13_solver_test", solve13_solver_test ); + Test.add_func ( "/solve14_solver_test", solve14_solver_test ); + Test.add_func ( "/types1_solver_test", types1_solver_test ); + Test.add_func ( "/types2_solver_test", types2_solver_test ); + Test.add_func ( "/types3_solver_test", types3_solver_test ); +} + +void types1_solver_test () { + try { + var in = generate_filestream ( "1 1\n1 2" ); + Solver p = new Solver ( in ); + p.solve (); + NumberSolutions n = p.number_solutions; + assert ( NumberSolutions.ONE == n ); + n = NumberSolutions.MANY; + assert ( NumberSolutions.ONE == p.number_solutions ); + } catch { + assert ( false ); + } +} + +void types2_solver_test () { + try { + var in = generate_filestream ( "1 1\n1 2" ); + Solver p = new Solver ( in ); + p.solve (); + var array = p.get_solution_partial(); + ComplexNumber expected = new ComplexNumber ( 2.0, 0.0 ); + assert ( expected.equals ( array[0] ) ); + array[0] = new ComplexNumber(); + array = p.get_solution_partial(); + assert ( expected.equals ( array[0] ) ); + } catch { + assert ( false ); + } +} + +void types3_solver_test () { + try { + var in = generate_filestream ( "1 1\n0 0" ); + Solver p = new Solver ( in ); + p.solve (); + var array = p.get_solution_general(); + string expected = "x1"; + assert ( expected == array[0] ); + array[0] = "hello"; + array = p.get_solution_general(); + assert ( expected == array[0] ); + } catch { + assert ( false ); + } } void constructor1_solver_test () { @@ -458,3 +508,26 @@ void solve13_solver_test () { assert ( false ); } } + +void solve14_solver_test () { + try { + var in = generate_filestream ( "1 1\r\n2 4" ); + Solver p = new Solver ( in ); + p.solve (); + + ComplexNumber[] expected_partial_solution = new ComplexNumber[] {new ComplexNumber ( 2.0, 0 ) }; + NumberSolutions expected_number_solutions = NumberSolutions.ONE; + string[] ? expected_general_solution = null; + + var actual_partial_solution = p.get_solution_partial (); + + assert ( expected_number_solutions == p.number_solutions ); + assert ( expected_general_solution == p.get_solution_general () ); + assert ( actual_partial_solution.length == expected_partial_solution.length ); + for ( int i = 0; i < actual_partial_solution.length; ++i ) { + assert ( actual_partial_solution[i].equals ( expected_partial_solution[i] ) ); + } + } catch { + assert ( false ); + } +} From c7f36d3392e86ab8a788291a83688a8aaca8583b Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Fri, 25 Jan 2019 04:10:17 +0700 Subject: [PATCH 104/108] update Java to 11.0.2 --- Java/.idea/misc.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Java/.idea/misc.xml b/Java/.idea/misc.xml index cbb200f..df60b67 100644 --- a/Java/.idea/misc.xml +++ b/Java/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file From 2f11faad7bf7598473bc800cd60d11dc8eb227ec Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Fri, 25 Jan 2019 04:24:09 +0700 Subject: [PATCH 105/108] fix bug, thanks aaaaaa2493 --- C++/src/solver.cpp | 4 +- C++/test/solver.test.cpp | 17 + C/src/solver.c | 4 +- C/test/solver.test.c | 27 ++ C/test/test_runners/solver.runner.c | 1 + DotNET/src/Solver.cs | 4 +- DotNET/tests/SolverTest.cs | 563 ++++++++++++++-------------- Java/src/solver/Solver.java | 4 +- Java/test/SolverTest.java | 11 + Typescript/spec/solver.spec.ts | 15 + Typescript/src/solver.ts | 8 +- Vala/src/solver.vala | 4 +- Vala/test/solver.test.vala | 20 + 13 files changed, 392 insertions(+), 290 deletions(-) diff --git a/C++/src/solver.cpp b/C++/src/solver.cpp index 8bfd443..40501d7 100644 --- a/C++/src/solver.cpp +++ b/C++/src/solver.cpp @@ -214,7 +214,7 @@ void solver::gaus_first_step() } if (!found_non_zero_element) { - for (size_t j = i + 1; j < number_equations; ++j) + for (size_t j = i + 1; j < number_variables; ++j) { if (!equals (matrix.at (i).at (j), ZERO)) { @@ -244,7 +244,7 @@ void solver::gaus_first_step() if (!found_non_zero_element) { - if (equals (matrix.at (i).at (number_equations), ZERO)) + if (equals (matrix.at (i).at (number_variables), ZERO)) { number_solutions_ = number_solutions::many; continue; diff --git a/C++/test/solver.test.cpp b/C++/test/solver.test.cpp index 35bb7a9..52727f4 100644 --- a/C++/test/solver.test.cpp +++ b/C++/test/solver.test.cpp @@ -557,3 +557,20 @@ BOOST_AUTO_TEST_CASE (solver_solve14) BOOST_CHECK (equals_partial); BOOST_CHECK (!actual_general_solution.has_value()); } + +BOOST_AUTO_TEST_CASE (solver_solve15) +{ + istringstream in ("3 4\n1 1 2 9\n0 1 3 1\n0 2 6 1\n0 0 0 0"); + solver s (in); + s.solve(); + + const number_solutions expected_number_solutions = number_solutions::none; + + const auto actual_partial_solution = s.get_solution_partial(); + const auto actual_number_solutions = s.get_number_solutions(); + const auto actual_general_solution = s.get_solution_general(); + + BOOST_CHECK_EQUAL (expected_number_solutions, actual_number_solutions); + BOOST_CHECK (!actual_partial_solution.has_value()); + BOOST_CHECK (!actual_general_solution.has_value()); +} diff --git a/C/src/solver.c b/C/src/solver.c index 329542f..ad82f04 100644 --- a/C/src/solver.c +++ b/C/src/solver.c @@ -295,7 +295,7 @@ static void gaus_first_step (solver* self) } if (!found_non_zero_element) { - for (size_t j = i + 1; j < self->number_equations; ++j) + for (size_t j = i + 1; j < self->number_variables; ++j) { if (!complex_equals (self->matrix[get_matrix_index (self, i, j)], ZERO)) { @@ -327,7 +327,7 @@ static void gaus_first_step (solver* self) if (!found_non_zero_element) { if (complex_equals (self->matrix[get_matrix_index (self, i, - self->number_equations)], ZERO)) + self->number_variables)], ZERO)) { self->number_solutions_ = number_solutions_many; continue; diff --git a/C/test/solver.test.c b/C/test/solver.test.c index 34b2c77..fe5bfd4 100644 --- a/C/test/solver.test.c +++ b/C/test/solver.test.c @@ -751,3 +751,30 @@ TEST (Solver, solve14) solver_free (s); fclose (in); } + +TEST (Solver, solve15) +{ + FILE* in = generate_file ("3 4\n1 1 2 9\n0 1 3 1\n0 2 6 1\n0 0 0 0"); + TEST_ASSERT_NOT_NULL (in); + solver* s = solver_new (in); + TEST_ASSERT_NOT_NULL (s); + solver_solve (s); + + const number_solutions expected_number_solutions = number_solutions_none; + + size_t actual_partial_solution_size = 0; + const complex_double* actual_partial_solution = solver_get_solution_partial (s, + &actual_partial_solution_size); + const number_solutions actual_number_solutions = solver_get_number_solutions ( + s); + size_t actual_general_solution_size = 0; + const char* const* actual_general_solution = solver_get_solution_general (s, + &actual_general_solution_size); + + TEST_ASSERT_NULL (actual_partial_solution); + TEST_ASSERT_NULL (actual_general_solution); + TEST_ASSERT_EQUAL (expected_number_solutions, actual_number_solutions); + + solver_free (s); + fclose (in); +} diff --git a/C/test/test_runners/solver.runner.c b/C/test/test_runners/solver.runner.c index 0160a72..27718e6 100644 --- a/C/test/test_runners/solver.runner.c +++ b/C/test/test_runners/solver.runner.c @@ -27,6 +27,7 @@ TEST_GROUP_RUNNER (Solver) RUN_TEST_CASE (Solver, solve12); RUN_TEST_CASE (Solver, solve13); RUN_TEST_CASE (Solver, solve14); + RUN_TEST_CASE (Solver, solve15); RUN_TEST_CASE (Solver, types1); RUN_TEST_CASE (Solver, types2); RUN_TEST_CASE (Solver, types3); diff --git a/DotNET/src/Solver.cs b/DotNET/src/Solver.cs index 9ccd67c..8872645 100644 --- a/DotNET/src/Solver.cs +++ b/DotNET/src/Solver.cs @@ -156,7 +156,7 @@ private void GausFirstStep() } if (!foundNonZeroElement) { - for (int j = i + 1; j < numberEquations; ++j) + for (int j = i + 1; j < numberVariables; ++j) { if (matrix[i, j] != ZERO) { @@ -186,7 +186,7 @@ private void GausFirstStep() if (!foundNonZeroElement) { - if (matrix[i, numberEquations] == ZERO) + if (matrix[i, numberVariables] == ZERO) { NumberSolutions = NumberSolutions.MANY; continue; diff --git a/DotNET/tests/SolverTest.cs b/DotNET/tests/SolverTest.cs index fc7fb95..7d6ea9b 100644 --- a/DotNET/tests/SolverTest.cs +++ b/DotNET/tests/SolverTest.cs @@ -1,16 +1,16 @@ -// This is an independent project of an individual developer. Dear PVS-Studio, please check it. -// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -using NUnit.Framework; -using src; -using System; -namespace tests -{ - [TestFixture()] - public class SolverTest - { - [Test()] - public void Types1() - { +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +using NUnit.Framework; +using src; +using System; +namespace tests +{ + [TestFixture()] + public class SolverTest + { + [Test()] + public void Types1() + { void f() { Solver p = new Solver("1 1\n1 2"); @@ -20,13 +20,13 @@ void f() n = NumberSolutions.MANY; Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); - } - Assert.DoesNotThrow(f); + } + Assert.DoesNotThrow(f); } - [Test()] - public void Types2() - { + [Test()] + public void Types2() + { void f() { Solver p = new Solver("1 1\n1 2"); @@ -38,13 +38,13 @@ void f() array = p.GetSolutionPartial(); Assert.AreEqual(expected, array[0]); - } - Assert.DoesNotThrow(f); + } + Assert.DoesNotThrow(f); } - [Test()] - public void Types3() - { + [Test()] + public void Types3() + { void f() { Solver p = new Solver("1 1\n0 0"); @@ -56,256 +56,267 @@ void f() array = p.GetSolutionGeneral(); Assert.AreEqual(expected, array[0]); - } - Assert.DoesNotThrow(f); - } - - [Test()] - public void Constructor1() - { - void f() { Solver p = new Solver("1 1\n1 2"); } - Assert.DoesNotThrow(f); - } - [Test()] - public void Constructor2() - { - void f() { Solver p = new Solver("1 1\nab 2"); } - Assert.Throws(f); - } - [Test()] - public void Constructor3() - { - void f() { Solver p = new Solver("-1 1\n2 2"); } - Assert.Throws(f); - } - [Test()] - public void Constructor4() - { - void f() { Solver p = new Solver("1 -1\n2 2"); } - Assert.Throws(f); - } - - [Test()] - public void Constructor5() - { - void f() { Solver p = new Solver("1 1\n2"); } - Assert.Throws(f); - } - [Test()] - public void Constructor6() - { - void f() { Solver p = new Solver("0 1\n2 2"); } - Assert.Throws(f); - } - [Test()] - public void Constructor7() - { - void f() { Solver p = new Solver("1 0\n2 2"); } - Assert.Throws(f); - } - [Test()] - public void Solve0() - { - string s = "1 1 \n\n 2 4"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(2.0, 0) }; - - Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(null, p.GetSolutionGeneral()); - } - [Test()] - public void Solve1() - { - string s = "1 1\n2 4"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(2.0, 0) }; - - Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(null, p.GetSolutionGeneral()); - } - [Test()] - public void Solve2() - { - string s = "2 2\n1 2 3\n4 5 6"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(-1.0, 0), new Complex(2.0, 0) }; - - Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(null, p.GetSolutionGeneral()); - } - [Test()] - public void Solve3() - { - string s = "2 2\n4 5 7\n3 9 9"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(0.85714, 0), - new Complex(0.71429, 0) }; - - Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(null, p.GetSolutionGeneral()); - } - [Test()] - public void Solve4() - { - string s = "3 3\n1 1 2 9\n2 4 -3 1\n3 6 -5 0"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(1.0, 0), - new Complex(2.0, 0), new Complex(3.0, 0) }; - - Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(null, p.GetSolutionGeneral()); - } - [Test()] - public void Solve5() - { - string s = "2 2\n0 1 1\n1 0 1"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(1.0, 0), - new Complex(1.0, 0) }; - - Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(null, p.GetSolutionGeneral()); - } - [Test()] - public void Solve6() - { - string s = "2 2\n0 1 1\n0 2 2"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(0.0, 0), - new Complex(1.0, 0) }; - string[] expectedGeneralSolution = { "x1", "1" }; - - Assert.AreEqual(NumberSolutions.MANY, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(expectedGeneralSolution, p.GetSolutionGeneral()); - } - [Test()] - public void Solve7() - { - string s = "2 2\n0 1 1\n0 2 3"; - Solver p = new Solver(s); - p.Solve(); - - Assert.AreEqual(NumberSolutions.NONE, p.NumberSolutions); - Assert.AreEqual(null, p.GetSolutionPartial()); - Assert.AreEqual(null, p.GetSolutionGeneral()); - } - [Test()] - public void Solve8() - { - string s = "3 4\n0 1 2 9\n0 1 3 1\n1 0 6 0\n2 0 2 0"; - Solver p = new Solver(s); - p.Solve(); - - Assert.AreEqual(NumberSolutions.NONE, p.NumberSolutions); - Assert.AreEqual(null, p.GetSolutionPartial()); - Assert.AreEqual(null, p.GetSolutionGeneral()); - } - [Test()] - public void Solve9() - { - string s = "3 1\n1 1 2 9"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(9.0, 0), - new Complex(0, 0), new Complex(0, 0) }; - string[] expectedGeneralSolution = { "9 - x2 - x3 * (2)", "x2", "x3" }; - - Assert.AreEqual(NumberSolutions.MANY, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(expectedGeneralSolution, p.GetSolutionGeneral()); - } - [Test()] - public void Solve10() - { - string s = "4 4\n1 0 0 5 0\n0 0 0 0 0\n0 0 1 4 6\n0 0 5 5 5"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(-8.3333333, 0), - new Complex(0, 0), new Complex(-0.6666667, 0), new Complex(1.6666667, 0) }; - string[] expectedGeneralSolution = { "-8.3333", "x2", "-0.6667", "1.6667" }; - - Assert.AreEqual(NumberSolutions.MANY, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(expectedGeneralSolution, p.GetSolutionGeneral()); - } - [Test()] - public void Solve11() - { - string s = "4 4\n2 3 -1 1 1\n8 12 -9 8 3\n4 6 3 -2 3\n2 3 9 -7 3"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(0.6, 0), - new Complex(0, 0), new Complex(0.2, 0), new Complex(0, 0) }; - string[] expectedGeneralSolution = { "0.6 - x2 * (1.5) - x4 * (0.1)", "x2", - "0.2 - x4 * (-0.8)", "x4" }; - - Assert.AreEqual(NumberSolutions.MANY, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(expectedGeneralSolution, p.GetSolutionGeneral()); - } - [Test()] - public void Solve12() - { - string s = "3 3\n1+2i -1.5-1.1i 2.12 91+5i\n-1+3i 1.2+3.5i -3.3 1+15i\n12.31 1.3-5i 12.3i -78.3i"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(6.73335286, -22.99754223), - new Complex(-1.7976071, 2.08404919), new Complex(15.69938581, 7.3960106) }; - - Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(null, p.GetSolutionGeneral()); - } - [Test()] - public void Solve13() - { - string s = "1\t1\t2\t4"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(2.0, 0) }; - - Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(null, p.GetSolutionGeneral()); - } - [Test()] - public void Solve14() - { - string s = "1 1\r\n2 4"; - Solver p = new Solver(s); - p.Solve(); - - Complex[] expectedPartialSolution = { new Complex(2.0, 0) }; - - Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); - Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); - Assert.AreEqual(null, p.GetSolutionGeneral()); - } - } -} + } + Assert.DoesNotThrow(f); + } + + [Test()] + public void Constructor1() + { + void f() { Solver p = new Solver("1 1\n1 2"); } + Assert.DoesNotThrow(f); + } + [Test()] + public void Constructor2() + { + void f() { Solver p = new Solver("1 1\nab 2"); } + Assert.Throws(f); + } + [Test()] + public void Constructor3() + { + void f() { Solver p = new Solver("-1 1\n2 2"); } + Assert.Throws(f); + } + [Test()] + public void Constructor4() + { + void f() { Solver p = new Solver("1 -1\n2 2"); } + Assert.Throws(f); + } + + [Test()] + public void Constructor5() + { + void f() { Solver p = new Solver("1 1\n2"); } + Assert.Throws(f); + } + [Test()] + public void Constructor6() + { + void f() { Solver p = new Solver("0 1\n2 2"); } + Assert.Throws(f); + } + [Test()] + public void Constructor7() + { + void f() { Solver p = new Solver("1 0\n2 2"); } + Assert.Throws(f); + } + [Test()] + public void Solve0() + { + string s = "1 1 \n\n 2 4"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(2.0, 0) }; + + Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(null, p.GetSolutionGeneral()); + } + [Test()] + public void Solve1() + { + string s = "1 1\n2 4"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(2.0, 0) }; + + Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(null, p.GetSolutionGeneral()); + } + [Test()] + public void Solve2() + { + string s = "2 2\n1 2 3\n4 5 6"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(-1.0, 0), new Complex(2.0, 0) }; + + Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(null, p.GetSolutionGeneral()); + } + [Test()] + public void Solve3() + { + string s = "2 2\n4 5 7\n3 9 9"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(0.85714, 0), + new Complex(0.71429, 0) }; + + Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(null, p.GetSolutionGeneral()); + } + [Test()] + public void Solve4() + { + string s = "3 3\n1 1 2 9\n2 4 -3 1\n3 6 -5 0"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(1.0, 0), + new Complex(2.0, 0), new Complex(3.0, 0) }; + + Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(null, p.GetSolutionGeneral()); + } + [Test()] + public void Solve5() + { + string s = "2 2\n0 1 1\n1 0 1"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(1.0, 0), + new Complex(1.0, 0) }; + + Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(null, p.GetSolutionGeneral()); + } + [Test()] + public void Solve6() + { + string s = "2 2\n0 1 1\n0 2 2"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(0.0, 0), + new Complex(1.0, 0) }; + string[] expectedGeneralSolution = { "x1", "1" }; + + Assert.AreEqual(NumberSolutions.MANY, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(expectedGeneralSolution, p.GetSolutionGeneral()); + } + [Test()] + public void Solve7() + { + string s = "2 2\n0 1 1\n0 2 3"; + Solver p = new Solver(s); + p.Solve(); + + Assert.AreEqual(NumberSolutions.NONE, p.NumberSolutions); + Assert.AreEqual(null, p.GetSolutionPartial()); + Assert.AreEqual(null, p.GetSolutionGeneral()); + } + [Test()] + public void Solve8() + { + string s = "3 4\n0 1 2 9\n0 1 3 1\n1 0 6 0\n2 0 2 0"; + Solver p = new Solver(s); + p.Solve(); + + Assert.AreEqual(NumberSolutions.NONE, p.NumberSolutions); + Assert.AreEqual(null, p.GetSolutionPartial()); + Assert.AreEqual(null, p.GetSolutionGeneral()); + } + [Test()] + public void Solve9() + { + string s = "3 1\n1 1 2 9"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(9.0, 0), + new Complex(0, 0), new Complex(0, 0) }; + string[] expectedGeneralSolution = { "9 - x2 - x3 * (2)", "x2", "x3" }; + + Assert.AreEqual(NumberSolutions.MANY, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(expectedGeneralSolution, p.GetSolutionGeneral()); + } + [Test()] + public void Solve10() + { + string s = "4 4\n1 0 0 5 0\n0 0 0 0 0\n0 0 1 4 6\n0 0 5 5 5"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(-8.3333333, 0), + new Complex(0, 0), new Complex(-0.6666667, 0), new Complex(1.6666667, 0) }; + string[] expectedGeneralSolution = { "-8.3333", "x2", "-0.6667", "1.6667" }; + + Assert.AreEqual(NumberSolutions.MANY, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(expectedGeneralSolution, p.GetSolutionGeneral()); + } + [Test()] + public void Solve11() + { + string s = "4 4\n2 3 -1 1 1\n8 12 -9 8 3\n4 6 3 -2 3\n2 3 9 -7 3"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(0.6, 0), + new Complex(0, 0), new Complex(0.2, 0), new Complex(0, 0) }; + string[] expectedGeneralSolution = { "0.6 - x2 * (1.5) - x4 * (0.1)", "x2", + "0.2 - x4 * (-0.8)", "x4" }; + + Assert.AreEqual(NumberSolutions.MANY, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(expectedGeneralSolution, p.GetSolutionGeneral()); + } + [Test()] + public void Solve12() + { + string s = "3 3\n1+2i -1.5-1.1i 2.12 91+5i\n-1+3i 1.2+3.5i -3.3 1+15i\n12.31 1.3-5i 12.3i -78.3i"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(6.73335286, -22.99754223), + new Complex(-1.7976071, 2.08404919), new Complex(15.69938581, 7.3960106) }; + + Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(null, p.GetSolutionGeneral()); + } + [Test()] + public void Solve13() + { + string s = "1\t1\t2\t4"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(2.0, 0) }; + + Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(null, p.GetSolutionGeneral()); + } + [Test()] + public void Solve14() + { + string s = "1 1\r\n2 4"; + Solver p = new Solver(s); + p.Solve(); + + Complex[] expectedPartialSolution = { new Complex(2.0, 0) }; + + Assert.AreEqual(NumberSolutions.ONE, p.NumberSolutions); + Assert.AreEqual(expectedPartialSolution, p.GetSolutionPartial()); + Assert.AreEqual(null, p.GetSolutionGeneral()); + } + [Test()] + public void Solve15() + { + string s = "3 4\n1 1 2 9\n0 1 3 1\n0 2 6 1\n0 0 0 0"; + Solver p = new Solver(s); + p.Solve(); + + Assert.AreEqual(NumberSolutions.NONE, p.NumberSolutions); + Assert.AreEqual(null, p.GetSolutionPartial()); + Assert.AreEqual(null, p.GetSolutionGeneral()); + } + } +} diff --git a/Java/src/solver/Solver.java b/Java/src/solver/Solver.java index 4d11bab..5c1a326 100644 --- a/Java/src/solver/Solver.java +++ b/Java/src/solver/Solver.java @@ -143,7 +143,7 @@ private void gausFirstStep() { } } if (!foundNonZeroElement) { - for (int j = i + 1; j < numberEquations; ++j) { + for (int j = i + 1; j < numberVariables; ++j) { if (!matrix[i][j].equals(ZERO)) { swapColumns(i, j); foundNonZeroElement = true; @@ -166,7 +166,7 @@ private void gausFirstStep() { } if (!foundNonZeroElement) { - if (matrix[i][numberEquations].equals(ZERO)) { + if (matrix[i][numberVariables].equals(ZERO)) { numberSolutions = NumberSolutions.MANY; continue; } else { diff --git a/Java/test/SolverTest.java b/Java/test/SolverTest.java index 03023f7..7223fd9 100644 --- a/Java/test/SolverTest.java +++ b/Java/test/SolverTest.java @@ -334,4 +334,15 @@ public void solve14() { Assert.assertArrayEquals(expectedPartialSolution, p.getSolutionPartial()); Assert.assertArrayEquals(null, p.getSolutionGeneral()); } + + @Test + public void solve15() { + final Scanner sc = new Scanner("3 4\n1 1 2 9\n0 1 3 1\n0 2 6 1\n0 0 0 0"); + final Solver p = new Solver(sc); + p.solve(); + + Assert.assertEquals(NumberSolutions.NONE, p.getNumberSolutions()); + Assert.assertArrayEquals(null, p.getSolutionPartial()); + Assert.assertArrayEquals(null, p.getSolutionGeneral()); + } } diff --git a/Typescript/spec/solver.spec.ts b/Typescript/spec/solver.spec.ts index f70b7cd..76bcc9f 100644 --- a/Typescript/spec/solver.spec.ts +++ b/Typescript/spec/solver.spec.ts @@ -403,4 +403,19 @@ describe("solver tests", () => { expect(undefined).toBe(actualGeneralSolution); } }); + + it("solve15", () => { + const s = "3 4\n1 1 2 9\n0 1 3 1\n0 2 6 1\n0 0 0 0"; + const p = new Solver(s); + p.solve(); + + const actualPartialSolution = p.getSolutionPartial(); + const actualGeneralSolution = p.getSolutionGeneral(); + + if (actualPartialSolution !== undefined || actualGeneralSolution !== undefined) { + fail(); + } else { + expect(NumberSolutions.NONE).toBe(p.getNumberSolutions()); + } + }); }); diff --git a/Typescript/src/solver.ts b/Typescript/src/solver.ts index e829b0b..ace22e3 100644 --- a/Typescript/src/solver.ts +++ b/Typescript/src/solver.ts @@ -59,7 +59,7 @@ export class Solver { return undefined; } - return Object.assign([], this.solutionGeneral); + return [...this.solutionGeneral]; } public readonly getSolutionPartial = (): Complex[] | undefined => { @@ -67,7 +67,7 @@ export class Solver { return undefined; } - return Object.assign([], this.solutionPartial); + return [...this.solutionPartial]; } public readonly solve = (): void => { @@ -142,7 +142,7 @@ export class Solver { } } if (!foundNonZeroElement) { - for (let j = i + 1; j < this.numberEquations; j += 1) { + for (let j = i + 1; j < this.numberVariables; j += 1) { if (!this.matrix[i][j].equals(Solver.ZERO)) { this.swapColumns(i, j); foundNonZeroElement = true; @@ -165,7 +165,7 @@ export class Solver { } if (!foundNonZeroElement) { - if (this.matrix[i][this.numberEquations].equals(Solver.ZERO)) { + if (this.matrix[i][this.numberVariables].equals(Solver.ZERO)) { this.numberSolutions = NumberSolutions.MANY; continue; } else { diff --git a/Vala/src/solver.vala b/Vala/src/solver.vala index 87a29f8..7c8f891 100644 --- a/Vala/src/solver.vala +++ b/Vala/src/solver.vala @@ -134,7 +134,7 @@ public class Solver { } } if ( !found_non_zero_element ) { - for ( int j = i + 1; j < number_equations; ++j ) { + for ( int j = i + 1; j < number_variables; ++j ) { if ( !matrix[i, j].equals ( ZERO ) ) { swap_columns ( i, j ); found_non_zero_element = true; @@ -157,7 +157,7 @@ public class Solver { } if ( !found_non_zero_element ) { - if ( matrix[i, number_equations].equals ( ZERO ) ) { + if ( matrix[i, number_variables].equals ( ZERO ) ) { number_solutions = NumberSolutions.MANY; continue; } else { diff --git a/Vala/test/solver.test.vala b/Vala/test/solver.test.vala index fe0bc64..98b75b5 100644 --- a/Vala/test/solver.test.vala +++ b/Vala/test/solver.test.vala @@ -21,6 +21,7 @@ void solver_tests () { Test.add_func ( "/solve12_solver_test", solve12_solver_test ); Test.add_func ( "/solve13_solver_test", solve13_solver_test ); Test.add_func ( "/solve14_solver_test", solve14_solver_test ); + Test.add_func ( "/solve15_solver_test", solve15_solver_test ); Test.add_func ( "/types1_solver_test", types1_solver_test ); Test.add_func ( "/types2_solver_test", types2_solver_test ); Test.add_func ( "/types3_solver_test", types3_solver_test ); @@ -531,3 +532,22 @@ void solve14_solver_test () { assert ( false ); } } + +void solve15_solver_test () { + try { + var in = generate_filestream ( "3 4\n1 1 2 9\n0 1 3 1\n0 2 6 1\n0 0 0 0" ); + Solver p = new Solver ( in ); + p.solve (); + + NumberSolutions expected_number_solutions = NumberSolutions.NONE; + + var actual_partial_solution = p.get_solution_partial (); + var actual_general_solution = p.get_solution_general (); + + assert ( p.number_solutions == expected_number_solutions ); + assert ( actual_partial_solution == null ); + assert ( actual_general_solution == null ); + } catch { + assert ( false ); + } +} From 5da91878cee10ce7ddc5fe11c174a25e006ea1e1 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 26 Jan 2019 06:17:21 +0700 Subject: [PATCH 106/108] allow omit +-1 before i --- C++/include/complex.hpp | 2 +- C++/src/complex.cpp | 34 +++++++++-- C++/test/complex.test.cpp | 40 +++++++++++++ C/src/complex_support.c | 36 ++++++++++++ C/test/complex_support.test.c | 50 ++++++++++++++++ C/test/test_runners/complex_support.runner.c | 5 ++ DotNET/src/Complex.cs | 16 +++++- DotNET/tests/ComplexTest.cs | 45 +++++++++++++++ Java/src/solver/Complex.java | 10 ++++ Java/test/ComplexTest.java | 40 +++++++++++++ Java/test/SolverTest.java | 1 + Typescript/spec/complex.spec.ts | 40 +++++++++++++ Typescript/src/complex.ts | 10 ++++ Vala/src/complex.vala | 21 +++++++ Vala/test/complex.test.vala | 60 ++++++++++++++++++++ 15 files changed, 403 insertions(+), 7 deletions(-) diff --git a/C++/include/complex.hpp b/C++/include/complex.hpp index aacec2a..822bb6b 100644 --- a/C++/include/complex.hpp +++ b/C++/include/complex.hpp @@ -8,7 +8,7 @@ #include -std::complex parse_complex (const std::string& s); +std::complex parse_complex (std::string s); bool PURE equals (const std::complex& a, const std::complex& b) noexcept; diff --git a/C++/src/complex.cpp b/C++/src/complex.cpp index 98cd193..52ff5e7 100644 --- a/C++/src/complex.cpp +++ b/C++/src/complex.cpp @@ -16,20 +16,45 @@ using std::string; using std::istringstream; using std::ostringstream; using std::runtime_error; +using std::size_t; #ifndef __DJGPP__ using std::round; #endif constexpr double EPSILON = 0.00001; +static void restore_omitted_imaginary_coefficient (string& s) +{ + if (s == "i") + { + s = "1i"; + } + const string plus_i = "+i"; + const string minus_i = "-i"; + size_t found = s.find (plus_i); + if (found != string::npos) + { + s.replace (found, plus_i.size(), "+1i"); + } + else + { + found = s.find (minus_i); + if (found != string::npos) + { + s.replace (found, minus_i.size(), "-1i"); + } + } +} + #ifdef _LIBCPP_VERSION /* в libc++ по другому устроена логика чтения из стрима, чем в libstdc++ и стандартной библиотеки от Microsoft * подробнее: https://bugs.llvm.org/show_bug.cgi?id=17782 */ -complex parse_complex (const string& s) +complex parse_complex (string s) { - double real; - double imag; + restore_omitted_imaginary_coefficient (s); + double real = 0.0; + double imag = 0.0; char c[3] = {0}; int result = sscanf (s.c_str(), "%lg%lg%2s", &real, &imag, c); if (result != 3) @@ -55,8 +80,9 @@ complex parse_complex (const string& s) return complex (real, imag); } #else -complex parse_complex (const string& s) +complex parse_complex (string s) { + restore_omitted_imaginary_coefficient (s); double real = 0.0; double imag = 0.0; istringstream in (s); diff --git a/C++/test/complex.test.cpp b/C++/test/complex.test.cpp index a1acf12..65b474c 100644 --- a/C++/test/complex.test.cpp +++ b/C++/test/complex.test.cpp @@ -206,3 +206,43 @@ BOOST_AUTO_TEST_CASE (complex_parse11) } BOOST_FAIL ("no throw exception"); } + +BOOST_AUTO_TEST_CASE (complex_parse12) +{ + const complex actual = parse_complex ("i"); + const complex expected (0.0, 1.0); + + BOOST_CHECK (equals (actual, expected)); +} + +BOOST_AUTO_TEST_CASE (complex_parse13) +{ + const complex actual = parse_complex ("-i"); + const complex expected (0.0, -1.0); + + BOOST_CHECK (equals (actual, expected)); +} + +BOOST_AUTO_TEST_CASE (complex_parse14) +{ + const complex actual = parse_complex ("0.5+i"); + const complex expected (0.5, 1.0); + + BOOST_CHECK (equals (actual, expected)); +} + +BOOST_AUTO_TEST_CASE (complex_parse15) +{ + const complex actual = parse_complex ("0.5-i"); + const complex expected (0.5, -1.0); + + BOOST_CHECK (equals (actual, expected)); +} + +BOOST_AUTO_TEST_CASE (complex_parse16) +{ + const complex actual = parse_complex ("+i"); + const complex expected (0.0, 1.0); + + BOOST_CHECK (equals (actual, expected)); +} diff --git a/C/src/complex_support.c b/C/src/complex_support.c index 3763357..db6e44d 100644 --- a/C/src/complex_support.c +++ b/C/src/complex_support.c @@ -66,6 +66,42 @@ bool complex_parse (complex_double* a, const char* s) c[0] = 'i'; c[1] = '\0'; } + else + { + result = sscanf (s, "%2s", c); + if (result == 1) + { + if (str_equal (c, "i") || str_equal (c, "+i")) + { + imag = 1.0; + c[0] = 'i'; + c[1] = '\0'; + } + else if (str_equal (c, "-i")) + { + imag = -1.0; + c[0] = 'i'; + c[1] = '\0'; + } + } + } + } + else + { + if (str_equal (c, "+i")) + { + real = imag; + imag = 1.0; + c[0] = 'i'; + c[1] = '\0'; + } + else if (str_equal (c, "-i")) + { + real = imag; + imag = -1.0; + c[0] = 'i'; + c[1] = '\0'; + } } } if (!str_equal (c, "i")) diff --git a/C/test/complex_support.test.c b/C/test/complex_support.test.c index 1e31e79..e3c5bd8 100644 --- a/C/test/complex_support.test.c +++ b/C/test/complex_support.test.c @@ -184,3 +184,53 @@ TEST (ComplexSupport, parse11) TEST_ASSERT_FALSE (ok); } + +TEST (ComplexSupport, parse12) +{ + const complex_double expected = CMPLX (0.0, 1.0); + complex_double actual = CMPLX (0.0, 0.0); + const bool ok = complex_parse (&actual, "i"); + + TEST_ASSERT (ok); + TEST_ASSERT (complex_equals (expected, actual)); +} + +TEST (ComplexSupport, parse13) +{ + const complex_double expected = CMPLX (0.0, -1.0); + complex_double actual = CMPLX (0.0, 0.0); + const bool ok = complex_parse (&actual, "-i"); + + TEST_ASSERT (ok); + TEST_ASSERT (complex_equals (expected, actual)); +} + +TEST (ComplexSupport, parse14) +{ + const complex_double expected = CMPLX (0.5, 1.0); + complex_double actual = CMPLX (0.0, 0.0); + const bool ok = complex_parse (&actual, "0.5+i"); + + TEST_ASSERT (ok); + TEST_ASSERT (complex_equals (expected, actual)); +} + +TEST (ComplexSupport, parse15) +{ + const complex_double expected = CMPLX (0.5, -1.0); + complex_double actual = CMPLX (0.0, 0.0); + const bool ok = complex_parse (&actual, "0.5-i"); + + TEST_ASSERT (ok); + TEST_ASSERT (complex_equals (expected, actual)); +} + +TEST (ComplexSupport, parse16) +{ + const complex_double expected = CMPLX (0.0, 1.0); + complex_double actual = CMPLX (0.0, 0.0); + const bool ok = complex_parse (&actual, "+i"); + + TEST_ASSERT (ok); + TEST_ASSERT (complex_equals (expected, actual)); +} diff --git a/C/test/test_runners/complex_support.runner.c b/C/test/test_runners/complex_support.runner.c index 7bf0952..a8f655c 100644 --- a/C/test/test_runners/complex_support.runner.c +++ b/C/test/test_runners/complex_support.runner.c @@ -23,4 +23,9 @@ TEST_GROUP_RUNNER (ComplexSupport) RUN_TEST_CASE (ComplexSupport, parse9); RUN_TEST_CASE (ComplexSupport, parse10); RUN_TEST_CASE (ComplexSupport, parse11); + RUN_TEST_CASE (ComplexSupport, parse12); + RUN_TEST_CASE (ComplexSupport, parse13); + RUN_TEST_CASE (ComplexSupport, parse14); + RUN_TEST_CASE (ComplexSupport, parse15); + RUN_TEST_CASE (ComplexSupport, parse16); } diff --git a/DotNET/src/Complex.cs b/DotNET/src/Complex.cs index ee30f9f..ad004ac 100644 --- a/DotNET/src/Complex.cs +++ b/DotNET/src/Complex.cs @@ -75,6 +75,7 @@ public override string ToString() private string[] Split(string s) { + s = Restore_omitted_imaginary_coefficient(s); string realString = "0"; string imagString = "0"; int i = 1; @@ -105,8 +106,19 @@ private string[] Split(string s) realString = s; } return new string[] { realString, imagString }; - } - + } + + private string Restore_omitted_imaginary_coefficient(string s) + { + if (s == "i") + { + return "1i"; + } + s = s.Replace("+i", "+1i"); + s = s.Replace("-i", "-1i"); + return s; + } + public override bool Equals(object obj) { return obj is Complex && this == (Complex)obj; diff --git a/DotNET/tests/ComplexTest.cs b/DotNET/tests/ComplexTest.cs index 1e25721..fe78e96 100644 --- a/DotNET/tests/ComplexTest.cs +++ b/DotNET/tests/ComplexTest.cs @@ -166,6 +166,51 @@ public void Constructor12() Assert.Throws(f); } + [Test()] + public void Constructor13() + { + string s = "i"; + Complex c = new Complex(s); + Assert.AreEqual(0.0, c.Real, Complex.EPSILON); + Assert.AreEqual(1.0, c.Imag, Complex.EPSILON); + } + + [Test()] + public void Constructor14() + { + string s = "-i"; + Complex c = new Complex(s); + Assert.AreEqual(0.0, c.Real, Complex.EPSILON); + Assert.AreEqual(-1.0, c.Imag, Complex.EPSILON); + } + + [Test()] + public void Constructor15() + { + string s = "0.5+i"; + Complex c = new Complex(s); + Assert.AreEqual(0.5, c.Real, Complex.EPSILON); + Assert.AreEqual(1.0, c.Imag, Complex.EPSILON); + } + + [Test()] + public void Constructor16() + { + string s = "0.5-i"; + Complex c = new Complex(s); + Assert.AreEqual(0.5, c.Real, Complex.EPSILON); + Assert.AreEqual(-1.0, c.Imag, Complex.EPSILON); + } + + [Test()] + public void Constructor17() + { + string s = "+i"; + Complex c = new Complex(s); + Assert.AreEqual(0.0, c.Real, Complex.EPSILON); + Assert.AreEqual(1.0, c.Imag, Complex.EPSILON); + } + [Test()] public void Add() { diff --git a/Java/src/solver/Complex.java b/Java/src/solver/Complex.java index 4e0e69a..a7cb16c 100644 --- a/Java/src/solver/Complex.java +++ b/Java/src/solver/Complex.java @@ -95,6 +95,7 @@ public String toString() { @NotNull @Contract("_ -> new") private String[] split(@NotNull String s) throws NumberFormatException { + s = restoreOmittedImaginaryCoefficient(s); String realString = "0"; String imagString = "0"; int i = 1; @@ -120,4 +121,13 @@ private String[] split(@NotNull String s) throws NumberFormatException { } return new String[]{realString, imagString}; } + + private String restoreOmittedImaginaryCoefficient(@NotNull String s) { + if (s.equals("i")) { + return "1i"; + } + s = s.replaceAll("\\+i", "+1i"); + s = s.replaceAll("-i", "-1i"); + return s; + } } diff --git a/Java/test/ComplexTest.java b/Java/test/ComplexTest.java index 8869879..065965b 100644 --- a/Java/test/ComplexTest.java +++ b/Java/test/ComplexTest.java @@ -183,6 +183,46 @@ public void constructor12() { Assert.assertTrue(ok); } + @Test + public void constructor13() { + final String s = "i"; + final Complex c = new Complex(s); + Assert.assertEquals(0.0, c.getReal(), Complex.EPSILON); + Assert.assertEquals(1.0, c.getImag(), Complex.EPSILON); + } + + @Test + public void constructor14() { + final String s = "-i"; + final Complex c = new Complex(s); + Assert.assertEquals(0.0, c.getReal(), Complex.EPSILON); + Assert.assertEquals(-1.0, c.getImag(), Complex.EPSILON); + } + + @Test + public void constructor15() { + final String s = "0.5+i"; + final Complex c = new Complex(s); + Assert.assertEquals(0.5, c.getReal(), Complex.EPSILON); + Assert.assertEquals(1.0, c.getImag(), Complex.EPSILON); + } + + @Test + public void constructor16() { + final String s = "0.5-i"; + final Complex c = new Complex(s); + Assert.assertEquals(0.5, c.getReal(), Complex.EPSILON); + Assert.assertEquals(-1.0, c.getImag(), Complex.EPSILON); + } + + @Test + public void constructor17() { + final String s = "+i"; + final Complex c = new Complex(s); + Assert.assertEquals(0.0, c.getReal(), Complex.EPSILON); + Assert.assertEquals(1.0, c.getImag(), Complex.EPSILON); + } + @Test public void add() { final Complex a = new Complex(3.0, -5.0); diff --git a/Java/test/SolverTest.java b/Java/test/SolverTest.java index 7223fd9..2dba167 100644 --- a/Java/test/SolverTest.java +++ b/Java/test/SolverTest.java @@ -16,6 +16,7 @@ public void types1() { NumberSolutions n = p.getNumberSolutions(); Assert.assertEquals(NumberSolutions.ONE, n); + //noinspection UnusedAssignment n = NumberSolutions.MANY; Assert.assertEquals(NumberSolutions.ONE, p.getNumberSolutions()); } diff --git a/Typescript/spec/complex.spec.ts b/Typescript/spec/complex.spec.ts index 3f23d64..865245f 100644 --- a/Typescript/spec/complex.spec.ts +++ b/Typescript/spec/complex.spec.ts @@ -133,6 +133,46 @@ describe("complex tests", () => { expect(f).toThrow(); }); + it("fromString12", () => { + const s = "i"; + const c = Complex.fromString(s); + + expect(0).toBeCloseTo(c.getReal()); + expect(1).toBeCloseTo(c.getImag()); + }); + + it("fromString13", () => { + const s = "-i"; + const c = Complex.fromString(s); + + expect(0).toBeCloseTo(c.getReal()); + expect(-1).toBeCloseTo(c.getImag()); + }); + + it("fromString14", () => { + const s = "0.5+i"; + const c = Complex.fromString(s); + + expect(0.5).toBeCloseTo(c.getReal()); + expect(1).toBeCloseTo(c.getImag()); + }); + + it("fromString15", () => { + const s = "0.5-i"; + const c = Complex.fromString(s); + + expect(0.5).toBeCloseTo(c.getReal()); + expect(-1).toBeCloseTo(c.getImag()); + }); + + it("fromString16", () => { + const s = "+i"; + const c = Complex.fromString(s); + + expect(0).toBeCloseTo(c.getReal()); + expect(1).toBeCloseTo(c.getImag()); + }); + it("add", () => { const a = new Complex(3, -5); const b = new Complex(4, 2); diff --git a/Typescript/src/complex.ts b/Typescript/src/complex.ts index a3ae9ae..72a0ec0 100644 --- a/Typescript/src/complex.ts +++ b/Typescript/src/complex.ts @@ -1,4 +1,14 @@ +const restoreOmittedImaginaryCoefficient = (s: string): string => { + if (s == "i") { + return "1i"; + } + s = s.replace("+i", "+1i"); + s = s.replace("-i", "-1i"); + return s; +}; + const split = (s: string): string[] => { + s = restoreOmittedImaginaryCoefficient(s); let realString = "0"; let imagString = "0"; let i = 1; diff --git a/Vala/src/complex.vala b/Vala/src/complex.vala index 7929610..6b6c341 100644 --- a/Vala/src/complex.vala +++ b/Vala/src/complex.vala @@ -47,6 +47,27 @@ public class ComplexNumber { result = s.scanf ( "%lg", &real ); if ( result == 1 ) { c = "i"; + } else { + result = s.scanf ( "%2s", c ); + if ( result == 1 ) { + if ( c == "i" || c == "+i" ) { + imag = 1.0; + c = "i"; + } else if ( c == "-i" ) { + imag = -1.0; + c = "i"; + } + } + } + } else { + if ( c == "+i" ) { + real = imag; + imag = 1.0; + c = "i"; + } else if ( c == "-i" ) { + real = imag; + imag = -1.0; + c = "i"; } } } diff --git a/Vala/test/complex.test.vala b/Vala/test/complex.test.vala index ba3df51..f7da06b 100644 --- a/Vala/test/complex.test.vala +++ b/Vala/test/complex.test.vala @@ -20,6 +20,11 @@ void complex_tests () { Test.add_func ( "/from_string9_complex_test", from_string9_complex_test ); Test.add_func ( "/from_string10_complex_test", from_string10_complex_test ); Test.add_func ( "/from_string11_complex_test", from_string11_complex_test ); + Test.add_func ( "/from_string12_complex_test", from_string12_complex_test ); + Test.add_func ( "/from_string13_complex_test", from_string13_complex_test ); + Test.add_func ( "/from_string14_complex_test", from_string14_complex_test ); + Test.add_func ( "/from_string15_complex_test", from_string15_complex_test ); + Test.add_func ( "/from_string16_complex_test", from_string16_complex_test ); Test.add_func ( "/add_complex_test", add_complex_test ); Test.add_func ( "/multiply_complex_test", multiply_complex_test ); Test.add_func ( "/conjugate_complex_test", conjugate_complex_test ); @@ -219,6 +224,61 @@ void from_string11_complex_test () { assert ( ok ); } +void from_string12_complex_test () { + try { + ComplexNumber a = new ComplexNumber.from_string ( "i" ); + ComplexNumber e = new ComplexNumber ( 0.0, 1.0 ); + + assert ( a.equals ( e ) ); + } catch { + assert ( false ); + } +} + +void from_string13_complex_test () { + try { + ComplexNumber a = new ComplexNumber.from_string ( "-i" ); + ComplexNumber e = new ComplexNumber ( 0.0, -1.0 ); + + assert ( a.equals ( e ) ); + } catch { + assert ( false ); + } +} + +void from_string14_complex_test () { + try { + ComplexNumber a = new ComplexNumber.from_string ( "0.5+i" ); + ComplexNumber e = new ComplexNumber ( 0.5, 1.0 ); + + assert ( a.equals ( e ) ); + } catch { + assert ( false ); + } +} + +void from_string15_complex_test () { + try { + ComplexNumber a = new ComplexNumber.from_string ( "0.5-i" ); + ComplexNumber e = new ComplexNumber ( 0.5, -1.0 ); + + assert ( a.equals ( e ) ); + } catch { + assert ( false ); + } +} + +void from_string16_complex_test () { + try { + ComplexNumber a = new ComplexNumber.from_string ( "+i" ); + ComplexNumber e = new ComplexNumber ( 0.0, 1.0 ); + + assert ( a.equals ( e ) ); + } catch { + assert ( false ); + } +} + void add_complex_test () { ComplexNumber a = new ComplexNumber ( 3.0, -5.0 ); ComplexNumber b = new ComplexNumber ( 4.0, 2.0 ); From 35d33d32b46e1cf7db039453d1c2a3a420e3c187 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Sat, 26 Jan 2019 07:00:04 +0700 Subject: [PATCH 107/108] add PVS-Studio for Java --- .gitignore | 1 + Java/src/solver/Complex.java | 7 +++++++ Java/src/solver/Main.java | 2 ++ Java/src/solver/NumberSolutions.java | 2 ++ Java/src/solver/Parameters.java | 2 ++ Java/src/solver/Solver.java | 2 ++ Java/test/ComplexTest.java | 2 ++ Java/test/ParametersTest.java | 2 ++ Java/test/SolverTest.java | 2 ++ 9 files changed, 22 insertions(+) diff --git a/.gitignore b/.gitignore index 47f868f..92f80e3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.class Java/out/ Java/.idea/workspace.xml +Java/.PVS-Studio/ # Log file *.log diff --git a/Java/src/solver/Complex.java b/Java/src/solver/Complex.java index a7cb16c..b5451c5 100644 --- a/Java/src/solver/Complex.java +++ b/Java/src/solver/Complex.java @@ -1,3 +1,5 @@ +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com package solver; import org.jetbrains.annotations.Contract; @@ -77,6 +79,11 @@ public double getImag() { return imag; } + @Override + public int hashCode() { + return toString().hashCode(); + } + @Override public String toString() { final DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US); diff --git a/Java/src/solver/Main.java b/Java/src/solver/Main.java index 7f48f4a..6709a2f 100644 --- a/Java/src/solver/Main.java +++ b/Java/src/solver/Main.java @@ -1,3 +1,5 @@ +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com package solver; class Main { diff --git a/Java/src/solver/NumberSolutions.java b/Java/src/solver/NumberSolutions.java index 7513a64..f28a70a 100644 --- a/Java/src/solver/NumberSolutions.java +++ b/Java/src/solver/NumberSolutions.java @@ -1,3 +1,5 @@ +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com package solver; public enum NumberSolutions { diff --git a/Java/src/solver/Parameters.java b/Java/src/solver/Parameters.java index 95fff77..0538f46 100644 --- a/Java/src/solver/Parameters.java +++ b/Java/src/solver/Parameters.java @@ -1,3 +1,5 @@ +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com package solver; import org.jetbrains.annotations.NotNull; diff --git a/Java/src/solver/Solver.java b/Java/src/solver/Solver.java index 5c1a326..72c17f3 100644 --- a/Java/src/solver/Solver.java +++ b/Java/src/solver/Solver.java @@ -1,3 +1,5 @@ +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com package solver; import org.jetbrains.annotations.NotNull; diff --git a/Java/test/ComplexTest.java b/Java/test/ComplexTest.java index 065965b..c60a7b0 100644 --- a/Java/test/ComplexTest.java +++ b/Java/test/ComplexTest.java @@ -1,3 +1,5 @@ +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com import org.junit.Assert; import org.junit.Test; import solver.Complex; diff --git a/Java/test/ParametersTest.java b/Java/test/ParametersTest.java index 7534a69..d46b589 100644 --- a/Java/test/ParametersTest.java +++ b/Java/test/ParametersTest.java @@ -1,3 +1,5 @@ +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com import org.junit.Assert; import org.junit.Test; import solver.Parameters; diff --git a/Java/test/SolverTest.java b/Java/test/SolverTest.java index 2dba167..e754172 100644 --- a/Java/test/SolverTest.java +++ b/Java/test/SolverTest.java @@ -1,3 +1,5 @@ +// This is an independent project of an individual developer. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com import org.junit.Assert; import org.junit.Test; import solver.Complex; From aba3fcb30639f2874211bfac2cc3083ab30eef60 Mon Sep 17 00:00:00 2001 From: fsb4000 Date: Thu, 31 Jan 2019 20:56:07 +0700 Subject: [PATCH 108/108] fix some warnings --- Typescript/src/complex.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Typescript/src/complex.ts b/Typescript/src/complex.ts index 72a0ec0..712e501 100644 --- a/Typescript/src/complex.ts +++ b/Typescript/src/complex.ts @@ -1,14 +1,15 @@ const restoreOmittedImaginaryCoefficient = (s: string): string => { - if (s == "i") { + if (s === "i") { return "1i"; } - s = s.replace("+i", "+1i"); - s = s.replace("-i", "-1i"); - return s; + let result = s.replace("+i", "+1i"); + result = result.replace("-i", "-1i"); + + return result; }; -const split = (s: string): string[] => { - s = restoreOmittedImaginaryCoefficient(s); +const split = (str: string): string[] => { + const s = restoreOmittedImaginaryCoefficient(str); let realString = "0"; let imagString = "0"; let i = 1;