From 4c976710f92a9596da9de906bd6e76f96c909127 Mon Sep 17 00:00:00 2001 From: Hubert Tylkowski Date: Sat, 9 Jun 2018 14:04:27 +0200 Subject: [PATCH] Zadanie 02 --- 02-Wielomiany/src/DivisionErrorException.java | 5 + 02-Wielomiany/src/Main.java | 17 +++ .../src/MultiplierNotFoundException.java | 5 + 02-Wielomiany/src/PolynomialTask.java | 134 ++++++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 02-Wielomiany/src/DivisionErrorException.java create mode 100644 02-Wielomiany/src/Main.java create mode 100644 02-Wielomiany/src/MultiplierNotFoundException.java create mode 100644 02-Wielomiany/src/PolynomialTask.java diff --git a/02-Wielomiany/src/DivisionErrorException.java b/02-Wielomiany/src/DivisionErrorException.java new file mode 100644 index 0000000..7560c50 --- /dev/null +++ b/02-Wielomiany/src/DivisionErrorException.java @@ -0,0 +1,5 @@ +public class DivisionErrorException extends Throwable { + public DivisionErrorException() { + System.out.println("Division error!"); + } +} diff --git a/02-Wielomiany/src/Main.java b/02-Wielomiany/src/Main.java new file mode 100644 index 0000000..364a9b4 --- /dev/null +++ b/02-Wielomiany/src/Main.java @@ -0,0 +1,17 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Main { + + public static void main(String[] args) throws DivisionErrorException, MultiplierNotFoundException { + //ex input in run console : 2 "1 1 1 0 1" "0 1 1" + int n = Integer.parseInt(args[0]); + List firstPolynomial = new ArrayList<>(); + Arrays.asList(args[1].split("\\s* \\s*")).forEach(factor -> firstPolynomial.add(Integer.valueOf(factor))); + List secondPolynomial = new ArrayList<>(); + Arrays.asList(args[2].split("\\s* \\s*")).forEach(factor -> secondPolynomial.add(Integer.valueOf(factor))); + PolynomialTask polynomialTask = new PolynomialTask(n, firstPolynomial, secondPolynomial); + polynomialTask.printAllValuesToStandardOutput(); + } +} diff --git a/02-Wielomiany/src/MultiplierNotFoundException.java b/02-Wielomiany/src/MultiplierNotFoundException.java new file mode 100644 index 0000000..3a9d83b --- /dev/null +++ b/02-Wielomiany/src/MultiplierNotFoundException.java @@ -0,0 +1,5 @@ +public class MultiplierNotFoundException extends Throwable { + public MultiplierNotFoundException() { + System.out.println("DivisionError"); + } +} diff --git a/02-Wielomiany/src/PolynomialTask.java b/02-Wielomiany/src/PolynomialTask.java new file mode 100644 index 0000000..1370891 --- /dev/null +++ b/02-Wielomiany/src/PolynomialTask.java @@ -0,0 +1,134 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class PolynomialTask { + private int n; + + private List firstPolynomial; + private List secondPolynomial; + + public PolynomialTask(int n, List firstPoly, List secondPoly) { + this.n = n; + this.firstPolynomial = firstPoly; + this.secondPolynomial = secondPoly; + } + + public Integer[] multiplyPolynomials(List firstPolynomial, List secondPolynomial) { + int[] multiplied = new int[firstPolynomial.size() + secondPolynomial.size() - 1]; + int sizeOfFirstPoly = firstPolynomial.size(); + int sizeOfSecondPoly = secondPolynomial.size(); + for (int i = 0; i < sizeOfFirstPoly; i++) { + for (int j = 0; j < sizeOfSecondPoly; j++) + multiplied[i + j] = (multiplied[i + j] + (firstPolynomial.get(i) * secondPolynomial.get(j))) % n; + } + return Arrays.stream(multiplied).boxed().toArray(Integer[]::new); + } + + public int[] moduloDividePolynomialsReturnQuotient(List firstPoly, List secondPoly) throws MultiplierNotFoundException, DivisionErrorException { + int[] quotient = new int[firstPoly.size() + secondPoly.size()]; + int firstPolyDegree = firstPoly.size() - 1; + int secondPolyDegree = secondPoly.size() - 1; + List polynomialAfterSubtract = firstPoly; + + + while (firstPolyDegree >= secondPolyDegree) { + polynomialAfterSubtract = calcQuotient(polynomialAfterSubtract, secondPoly, quotient); + firstPolyDegree = polynomialAfterSubtract.size() - 1; + } + + int[] remainder = new int[polynomialAfterSubtract.size()]; + for (int i = 0; i < polynomialAfterSubtract.size(); i++) { + remainder[i] = polynomialAfterSubtract.get(i); + } + return remainder; + } + + private List calcQuotient(List firstPoly, List secondPoly, int[] quotient) throws MultiplierNotFoundException, DivisionErrorException { + int firstPolyDegree = firstPoly.size() - 1; + int secondPolyDegree = secondPoly.size() - 1; + if (firstPolyDegree < secondPolyDegree) { + throw new DivisionErrorException(); + } + int quotientCoefficient; + if ((((float) firstPoly.get(firstPolyDegree) / (float) secondPoly.get(secondPolyDegree))) == Math.round(firstPoly.get(firstPolyDegree) / secondPoly.get(secondPolyDegree))) { + quotientCoefficient = firstPoly.get(firstPolyDegree) / secondPoly.get(secondPolyDegree); + } else { + quotientCoefficient = invElem(firstPoly.get(firstPolyDegree), secondPoly.get(secondPolyDegree)); + } + quotient[firstPolyDegree - secondPolyDegree] += quotientCoefficient; + List newPoly = generatePolyFromIndexAndValue(firstPolyDegree - secondPolyDegree, quotientCoefficient); + Integer[] multipliedPolynomials = multiplyPolynomials(newPoly, secondPoly); + List polynomialAfterFirstDivide = new ArrayList<>(Arrays.asList(multipliedPolynomials)); + + return removeUnnecessaryZeros(subtractTwoPolynomials(firstPoly, polynomialAfterFirstDivide)); + } + + private List removeUnnecessaryZeros(List polynomialAfterSubtract) { + int amountOfZeros = 0; + for (int i = polynomialAfterSubtract.size() - 1; i >= 0; i--) { + if (polynomialAfterSubtract.get(i) == 0) { + amountOfZeros++; + } else { + break; + } + } + + polynomialAfterSubtract = polynomialAfterSubtract.subList(0, polynomialAfterSubtract.size() - amountOfZeros); + return polynomialAfterSubtract; + } + + private List subtractTwoPolynomials(List firstPoly, List secondPoly) { + List subtractedPolynomial = new ArrayList<>(Collections.nCopies(firstPoly.size() + secondPoly.size(), 0)); + for (int index = firstPoly.size(); index >= 0; index--) { + if (index < secondPoly.size()) { + subtractedPolynomial.set(index, firstPoly.get(index) - secondPoly.get(index)); + parseNegativeElement(subtractedPolynomial, index); + } + } + return subtractedPolynomial; + } + + private void parseNegativeElement(List subtractedPolynomial, int index) { + while (subtractedPolynomial.get(index) < 0) + subtractedPolynomial.set(index, (subtractedPolynomial.get(index) * subtractedPolynomial.get(index)) % n); + } + + private List generatePolyFromIndexAndValue(int size, int quotientCoefficient) { + List poly = new ArrayList<>(Collections.nCopies(size + 1, 0)); + poly.set(size, quotientCoefficient); + return poly; + } + + private int invElem(int a, int b) throws MultiplierNotFoundException { + + for (int i = 0; i < n; i++) { + if (a == (b * i) % n) { + return i; + } + } + + throw new MultiplierNotFoundException(); + } + + public void printAllValuesToStandardOutput() throws DivisionErrorException, MultiplierNotFoundException { + List> values = new ArrayList<>(); + values.add(Arrays.asList(multiplyPolynomials(firstPolynomial, secondPolynomial))); + values.add(Arrays.stream(moduloDividePolynomialsReturnQuotient(firstPolynomial, secondPolynomial)).boxed().collect(Collectors.toList())); + try { + values.add(gcd(firstPolynomial, secondPolynomial)); + } catch (MultiplierNotFoundException e) { + } + System.out.println(values); + } + + private List gcd(List polyOne, List polyTwo) throws MultiplierNotFoundException, DivisionErrorException { + if (polyTwo.isEmpty()) return polyOne; + List poly = Arrays.stream(moduloDividePolynomialsReturnQuotient(polyOne, polyTwo)).boxed().collect(Collectors.toList()); + return gcd(polyTwo, poly); + + } + +}