ZAD4 #33
@ -1,21 +0,0 @@
|
||||
## Zadanie
|
||||
|
||||
Napisać algorytm, który dla danego `n ∈ ℕ` znajdzie wszystkie:
|
||||
|
||||
1. elementy odwracalne
|
||||
2. dzielniki zera
|
||||
3. elementy nilpotentne
|
||||
4. elementy idempotentne
|
||||
|
||||
w pierścieniu `{ℤ/nℤ, +, ⋅}`.
|
||||
|
||||
Termin: 31.05
|
||||
|
||||
### Przykłady:
|
||||
|
||||
> Input: `4`
|
||||
> Output: `[[1,3], [0,2], [0,2], [0,1]]`
|
||||
|
||||
> Input: `6`
|
||||
> Output: `[[1,5], [0,2,3,4], [0], [0,1,3,4]]`
|
||||
|
@ -1,19 +0,0 @@
|
||||
## Zadanie
|
||||
|
||||
Napisać program, który dla danego pierścienia współczynników `R = ℤ/nℤ, n ∈ ℕ` oraz wielomianów `f,g ∈ R[x] ` zmiennej `x ` znajdzie:
|
||||
|
||||
1. iloczyn `f⋅g ∈ R[x]`
|
||||
2. klasę reszty `f ∈ R[x]/(g)`
|
||||
3. największy wspólny dzielnik `nwd(f,g)` korzystając z algorytmu Euklidesa.
|
||||
|
||||
**Uwaga**: wielomiany są podawane jako ciąg współczynników **od wyrazu wolnego, do współczynnika wiodącego**.
|
||||
|
||||
Termin: 07.06
|
||||
|
||||
### Przykłady:
|
||||
|
||||
> Input: `2, [1,1,1,0,1], [0,1,1]` (i.e. `f = 1 + x + x² + x⁴, g = x² + x`)
|
||||
> Output: `[[0,1,0,0,1,1,1], [1,1], [1,1]]`
|
||||
|
||||
> Input: `6, [2,1,0,2,1,3], [1,0,0,5]`
|
||||
> Output: `[[3,1,0,5,0,1,4,5,5], [5,2,1], DivisionError]`
|
383
Main.java
Normal file
383
Main.java
Normal file
@ -0,0 +1,383 @@
|
||||
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>();
|
||||
|
||||
// wypelnienie wielomianu
|
||||
polynomial = fill(polynomialNumbers, polynomial);
|
||||
|
||||
// candidates
|
||||
LinkedList<LinkedList<Integer>> elements = new LinkedList<LinkedList<Integer>>();
|
||||
elements = createCandidates(polynomial,mod);
|
||||
|
||||
// output
|
||||
// odwracalne
|
||||
System.out.println(reversible(elements,polynomial,mod));
|
||||
// dzielniki zera
|
||||
System.out.println(zeroDivisors(elements,polynomial,mod));
|
||||
// nilpotenty
|
||||
System.out.println(nilpotent(elements,polynomial,mod));
|
||||
// idempotenty
|
||||
System.out.println(idempotent(elements,polynomial,mod));
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
public static LinkedList<LinkedList<Integer>> idempotent(LinkedList<LinkedList<Integer>> elements, LinkedList<Integer> expect, int mod) {
|
||||
|
||||
LinkedList<LinkedList<Integer>> result = new LinkedList<LinkedList<Integer>>();
|
||||
LinkedList<Integer> temp = new LinkedList<Integer>();
|
||||
|
||||
result.add(elements.get(0));
|
||||
|
||||
for(int i=1; i<elements.size();i++) {
|
||||
// a*a
|
||||
temp = polynomialsMultiplication(elements.get(i),elements.get(i));
|
||||
|
||||
// mod
|
||||
temp = modPolynomial(mod,temp);
|
||||
|
||||
if(expect.size()<= temp.size()) {
|
||||
temp = dividePolynomials(temp,expect,mod);
|
||||
}
|
||||
|
||||
if(temp.equals(elements.get(i))) {
|
||||
result.add(temp);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static LinkedList<LinkedList<Integer>> nilpotent(LinkedList<LinkedList<Integer>> elements,LinkedList<Integer> expect, int mod) {
|
||||
|
||||
LinkedList<LinkedList<Integer>> result = new LinkedList<LinkedList<Integer>>();
|
||||
LinkedList<Integer> temp = new LinkedList<Integer>();
|
||||
|
||||
LinkedList<Integer> tempPow = new LinkedList<Integer>();
|
||||
|
||||
result.add(elements.get(0));
|
||||
|
||||
for(int i=1; i<elements.size();i++) {
|
||||
|
||||
temp = elements.get(i);
|
||||
|
||||
for(int j=2; j<mod; j++)
|
||||
|
||||
tempPow = temp;
|
||||
|
||||
temp = polynomialsMultiplication(tempPow,temp);
|
||||
|
||||
// mod
|
||||
temp = modPolynomial(mod,temp);
|
||||
|
||||
if(temp.size() >= expect.size()) {
|
||||
temp = dividePolynomials(temp, expect, mod);
|
||||
}
|
||||
else continue;
|
||||
|
||||
if(temp.size() == 1 && temp.getFirst() == 0) {
|
||||
result.add(elements.get(i));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public static LinkedList<LinkedList<Integer>> reversible(LinkedList<LinkedList<Integer>> elements,LinkedList<Integer> expect, int mod) {
|
||||
|
||||
LinkedList<LinkedList<Integer>> result = new LinkedList<LinkedList<Integer>>();
|
||||
LinkedList<Integer> temp = new LinkedList<Integer>();
|
||||
|
||||
for(int i=1; i<mod; i++) {
|
||||
result.add(elements.get(i));
|
||||
}
|
||||
|
||||
for(int i=mod; i<elements.size();i++) {
|
||||
|
||||
temp = elements.get(i);
|
||||
|
||||
if(temp.size() <= expect.size()) {
|
||||
temp = nwdPoly(temp, expect, mod);
|
||||
}
|
||||
|
||||
if(temp.size() == 1 && temp.getFirst() == 1) {
|
||||
result.add(elements.get(i));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static LinkedList<Integer> nwdPoly(LinkedList<Integer> p1, LinkedList<Integer> orig, int mod) {
|
||||
|
||||
LinkedList<Integer> temp = new LinkedList<Integer>(p1);
|
||||
|
||||
while(p1.size()>1) {
|
||||
if(p1.size() <= orig.size()) {
|
||||
temp = dividePolynomials(orig,p1,mod);
|
||||
orig = p1;
|
||||
p1 = temp;
|
||||
}
|
||||
|
||||
}
|
||||
return p1;
|
||||
}
|
||||
|
||||
|
||||
public static LinkedList<LinkedList<Integer>> zeroDivisors(LinkedList<LinkedList<Integer>> elements,LinkedList<Integer> expect, int mod) {
|
||||
|
||||
LinkedList<LinkedList<Integer>> result = new LinkedList<LinkedList<Integer>>();
|
||||
LinkedList<Integer> temp = new LinkedList<Integer>();
|
||||
LinkedList<Integer> tempSec = new LinkedList<Integer>();
|
||||
LinkedList<Integer> pfinal = new LinkedList<Integer>();
|
||||
|
||||
result.add(elements.get(0));
|
||||
|
||||
for(int i=1; i<elements.size();i++) {
|
||||
|
||||
temp = elements.get(i);
|
||||
|
||||
for(int j=1; j<elements.size(); j++) {
|
||||
|
||||
tempSec = elements.get(j);
|
||||
|
||||
pfinal = polynomialsMultiplication(temp,tempSec);
|
||||
pfinal = modPolynomial(mod,pfinal);
|
||||
|
||||
if(pfinal.equals(expect)) {
|
||||
result.add(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user