Zadananie 3 - CRC #26
5
02-Wielomiany/src/DivisionErrorException.java
Normal file
5
02-Wielomiany/src/DivisionErrorException.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
public class DivisionErrorException extends Throwable {
|
||||||
|
public DivisionErrorException() {
|
||||||
|
System.out.println("Division error!");
|
||||||
|
}
|
||||||
|
}
|
17
02-Wielomiany/src/Main.java
Normal file
17
02-Wielomiany/src/Main.java
Normal file
@ -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<Integer> firstPolynomial = new ArrayList<>();
|
||||||
|
Arrays.asList(args[1].split("\\s* \\s*")).forEach(factor -> firstPolynomial.add(Integer.valueOf(factor)));
|
||||||
|
List<Integer> 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();
|
||||||
|
}
|
||||||
|
}
|
5
02-Wielomiany/src/MultiplierNotFoundException.java
Normal file
5
02-Wielomiany/src/MultiplierNotFoundException.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
public class MultiplierNotFoundException extends Throwable {
|
||||||
|
public MultiplierNotFoundException() {
|
||||||
|
System.out.println("DivisionError");
|
||||||
|
}
|
||||||
|
}
|
134
02-Wielomiany/src/PolynomialTask.java
Normal file
134
02-Wielomiany/src/PolynomialTask.java
Normal file
@ -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<Integer> firstPolynomial;
|
||||||
|
private List<Integer> secondPolynomial;
|
||||||
|
|
||||||
|
public PolynomialTask(int n, List<Integer> firstPoly, List<Integer> secondPoly) {
|
||||||
|
this.n = n;
|
||||||
|
this.firstPolynomial = firstPoly;
|
||||||
|
this.secondPolynomial = secondPoly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer[] multiplyPolynomials(List<Integer> firstPolynomial, List<Integer> 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<Integer> firstPoly, List<Integer> secondPoly) throws MultiplierNotFoundException, DivisionErrorException {
|
||||||
|
int[] quotient = new int[firstPoly.size() + secondPoly.size()];
|
||||||
|
int firstPolyDegree = firstPoly.size() - 1;
|
||||||
|
int secondPolyDegree = secondPoly.size() - 1;
|
||||||
|
List<Integer> 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<Integer> calcQuotient(List<Integer> firstPoly, List<Integer> 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<Integer> newPoly = generatePolyFromIndexAndValue(firstPolyDegree - secondPolyDegree, quotientCoefficient);
|
||||||
|
Integer[] multipliedPolynomials = multiplyPolynomials(newPoly, secondPoly);
|
||||||
|
List<Integer> polynomialAfterFirstDivide = new ArrayList<>(Arrays.asList(multipliedPolynomials));
|
||||||
|
|
||||||
|
return removeUnnecessaryZeros(subtractTwoPolynomials(firstPoly, polynomialAfterFirstDivide));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Integer> removeUnnecessaryZeros(List<Integer> 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<Integer> subtractTwoPolynomials(List<Integer> firstPoly, List<Integer> secondPoly) {
|
||||||
|
List<Integer> 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<Integer> subtractedPolynomial, int index) {
|
||||||
|
while (subtractedPolynomial.get(index) < 0)
|
||||||
|
subtractedPolynomial.set(index, (subtractedPolynomial.get(index) * subtractedPolynomial.get(index)) % n);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Integer> generatePolyFromIndexAndValue(int size, int quotientCoefficient) {
|
||||||
|
List<Integer> 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<List<Integer>> 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<Integer> gcd(List<Integer> polyOne, List<Integer> polyTwo) throws MultiplierNotFoundException, DivisionErrorException {
|
||||||
|
if (polyTwo.isEmpty()) return polyOne;
|
||||||
|
List<Integer> poly = Arrays.stream(moduloDividePolynomialsReturnQuotient(polyOne, polyTwo)).boxed().collect(Collectors.toList());
|
||||||
|
return gcd(polyTwo, poly);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user