DALGLI0/Main.java
2018-06-28 00:35:28 +02:00

248 lines
6.0 KiB
Java

import java.util.LinkedList;
import java.util.Queue;
public class Main {
public static void main(String[] args) {
String input = args[0];
String[] parts = input.split(" ");
// n
int mod = Integer.parseInt(parts[0]);
//int number = Character.getNumericValue(numberStr.charAt(0));
String polynomialStr = parts[1];
// usuwam '[', ']'
polynomialStr = polynomialStr.substring(1, polynomialStr.length()-1);
// ,
String[] polynomialNumbers = polynomialStr.split(",");
LinkedList<Integer> polynomial = new LinkedList<Integer>();
//test poly
LinkedList<Integer> polynomial2 = new LinkedList<Integer>();
// wypelnienie wielomianu
polynomial = fill(polynomialNumbers, polynomial);
//test
LinkedList<LinkedList<Integer>> elements = new LinkedList<LinkedList<Integer>>();
elements = createCandidates(polynomial,mod);
// Idemp
System.out.println(idempotent(elements,polynomial,mod));
//showPoly(polynomial);
}
// wypelnienie wielomianu
public static LinkedList<Integer> fill(String[] str, LinkedList<Integer> polynomial){
for(int i=0; i <str.length; i++) {
polynomial.add(Integer.parseInt(str[i]));
}
return polynomial;
}
public static void showPoly(LinkedList<Integer> poly) {
System.out.println(poly.toString());
}
public static int multiplier(int number, int expect, int mod) {
/*
if(nwd(number,mod) != 1 || nwd(number,mod) != number) {
System.out.println("NIE DA SIE");
return 0;
}*/
for(int i=1;i<mod;i++) {
if(((number*i) % mod) == expect) {
return i;
}
}
return 0;
}
public static LinkedList<Integer> modPolynomial(int mod, LinkedList<Integer> polynomial){
LinkedList<Integer> result = new LinkedList<Integer>();
while(!polynomial.isEmpty()) {
if(polynomial.peek() < 0) {
result.add(mod + polynomial.poll());
}
else result.add(polynomial.poll() % mod);
}
return result;
}
public static LinkedList<Integer> multiplyPolynomial(LinkedList<Integer> p1, int multiplier){
LinkedList<Integer> result = new LinkedList<Integer>();
while(!p1.isEmpty()) {
result.add(p1.poll() * multiplier);
}
return result;
}
public static LinkedList<Integer> shiftList(LinkedList<Integer> p, int places){
LinkedList<Integer> result = new LinkedList<Integer>(p);
if(places == 0) {
return result;
}
for(; places>0; places--) {
result.addFirst(0);
}
return result;
}
public static LinkedList<Integer> polynomialsMultiplication(LinkedList<Integer> p1, LinkedList<Integer> p2){
// suma dlugosci
int amount = p1.size() + p2.size();
// nowy wielomian bedzie dlugosci sumy poteg wyrazow wiodacych obu tablic -1
LinkedList<Integer> result = new LinkedList<Integer>();
for(int i=0;i<amount-1;i++) {
result.add(0);
}
// mnozenie
for(int i=0; i<p1.size(); i++) {
for(int j=0; j<p2.size(); j++) {
result.set(i+j, (result.get(i+j) + p1.get(i) * p2.get(j)));
}
}
return result;
}
public static LinkedList<Integer> substractPolynomials(LinkedList<Integer> p1, LinkedList<Integer> p2){
LinkedList<Integer> result = new LinkedList<Integer>();
LinkedList<Integer> p2Copy = new LinkedList<Integer>();
for(int i=0; i<p2.size(); i++) {
p2Copy.add(p2.get(i));
}
while(!p2Copy.isEmpty()) {
result.add(p1.poll() - p2Copy.poll());
}
while(!p1.isEmpty()) {
result.add(p1.poll());
}
while(result.getLast() == 0) {
if(result.size()>1) {
result.removeLast();
}
else break;
}
return result;
}
public static LinkedList<LinkedList<Integer>> createCandidates(LinkedList<Integer> orig, int mod){
LinkedList<LinkedList<Integer>> elements = new LinkedList<LinkedList<Integer>>();
LinkedList<Integer> result = new LinkedList<>();
result.add(0);
int i = 0;
while (result.size() < orig.size()){
elements.add(new LinkedList<>(result));
i = (i + 1) % mod;
result.set(0, i);
if (i == 0){
if (result.size() == 1){
result.add(1);
}else {
int tmp = (result.get(1) + 1);
result.set(1, tmp);
for (int k = 1; k < result.size(); ++k){
if (result.get(k) == 0 || result.get(k) % mod != 0) break;
tmp = (result.get(k)) % mod;
result.set(k, 0);
if (tmp == 0){
if (k + 1 < result.size()){
tmp = (result.get(k + 1) + 1);
result.set(k + 1, tmp);
} else {
result.add(1);
}
}
}
}
}
}
return elements;
}
public static LinkedList<Integer> dividePolynomials(LinkedList<Integer> p1, LinkedList<Integer> p2, int mod) {
LinkedList<Integer> result = new LinkedList<Integer>(p1);
LinkedList<Integer> tmpP = new LinkedList<Integer>();
int stP1 = p1.size();
int stP2 = p2.size();
if(p1.size() < p2.size()) {
System.out.println("NIE DA SIE");
return result;
}
int tmp;
// sprawdzenie czy reszta jest mniejszego stopnia
while(stP1 >= stP2) {
tmp = multiplier(p2.getLast(), result.getLast(), mod);
// przesuniecie
tmpP = shiftList(p2,stP1 - stP2);
if(tmp != 0) {
// mnoznie przez liczbe
tmpP = multiplyPolynomial(tmpP,tmp);
}
// dzielenie modulo
tmpP = modPolynomial(mod,tmpP);
// odejmowanie
result = substractPolynomials(result,tmpP);
result = modPolynomial(mod, result);
// st po odjeciu
stP1 = result.size();
}
return result;
}
}