GCD of two polynomials - java

In the code below I want to find Greatest Common Divisor of 2 polynomials.
Sometimes I am getting error on " return c.plus( (a.minus(b.times(c)).divides(b)) );". How can I fix it?
public Polynomial divides(Polynomial b) {
Polynomial a = this;
if ((b.deg == 0) && (b.coef[0] == 0))
throw new RuntimeException("Divide by zero polynomial");
if (a.deg < b.deg) return new Polynomial(0,0);
int coefficient = a.coef[a.deg]/(b.coef[b.deg]);
int exponent = a.deg - b.deg;
Polynomial c = new Polynomial(coefficient, exponent);
return c.plus( (a.minus(b.times(c)).divides(b)) );
}
public Polynomial GCD(Polynomial b) {
Polynomial a = this;
Polynomial f = b;
Polynomial x = a.minus((a.divides(f)).times(f));
if (x.deg == 0 && x.coef[0] == 0) {
return b;
}
return f.GCD(x);
}

That runtime exception means: you created an endless recursion.
Most likely, because your method divides() is calling itself on that last row - without proper checking in there to avoid that recursion.
In other words: you want to review your maths and the logic in there to simply avoid that divides() keeps calling itself without any limits!

Related

Finding Greatest Common Divisor using Euclidean Algorithm

I was trying to figure out a solution by which I can find GCD of 2 numbers in most optimal way,
So I need some help here to figure out whether the program I came out works for all possible cases or has any case it will break down or can I improve it more to make it an optimal solution.
Program:
public static void main(String[] args) {
int a= 153;
int b= 81;
boolean flag = true;
int gcd = 1;
while(flag)
{
if(a>b && a%b ==0)
{
flag = false;
gcd = b;
}
else if(b>a && b%a ==0)
{
flag=false;
gcd = a;
}
else if( a>b)
a = a-b;
else
b = b-a;
}
System.out.println(gcd);
}
Kindly help me out in figuring out the proper solution , thanks in advance.
Try something like this. Euclids GCD algorithm basically says this: GCD of 2 numbers (we will call them bigger and smaller) is equal to the GCD of smaller number and difference between bigger and smaller number. Repeat the procedure until two numbers are the same.
The below is iterative solution.
int a= 153 , b = 81, gcd = 1;
while( gcd != a ) {
if( a > b ) a -= b;
else if( b > a) b -= a;
else gcd = a;
}
System.out.println(gcd);
This is recursive solution. Hope this helps.
public static int euclidGCD(int a, int b) {
if (b == a) return a;
if (b > a) return euclidGCD(b - a, a);
else return euclidGCD(a - b, b);
}
Here is a modification of your program.
To test a program the best thing is to write down its conditions and cases.
In this exercise there are two conditions:
1.) Number must be integer
2.) Number must be positive.
Dealing with numbers usually has discrete number of cases. In this exercise there are two cases:
1.) Numbers are equal.
2.) Numbers are different.
Your code is not correct when a is equal to b (try it yourself). When the numbers are different your code works fine. Below is modification.
int a= 55;
int b= 55;
boolean flag = true;
int gcd = b;
while(flag && b != a)
{
if(a>b && a%b ==0)
{
flag = false;
gcd = b;
}
else if(b>a && b%a ==0)
{
flag=false;
gcd = a;
}
else if( a>b)
a = a-b;
else
b = b-a;
}
System.out.println(gcd);

Object oriented programming comparing linkedlists

I have objects of class Bit which is basically a class that has one field called value and it's boolean.
public class Bit {
private boolean value;
public Bit() {
this.value = false;
}
public Bit(boolean value) {
this.value = value;
}
public boolean getValue() {
return value;
}
}
and it has some more methods.
and then I have a class called number which is supposed to represent large number in their binary representation using a linked list where the firstlink is the LSB and the lastlink is the MSB.
for instance if I call the constructor
Number num1 = new Number(6);
then I'll have a linked list like the following : 0 1 1 (null)
Now I wanna know how to be able to compare two Number objects.
so for example: if I have num1, and Number num2 = new Number (7); [ 1 1 1 ]
then I want a method to tell me that num2 is larger than num1
to compare two binary numbers simply I would start with the MSB and compare each bit and once one is larger than the other that means the number is larger.
I could easily get the integer value of each Link(Bit) using Bit.toInt();
So I was thinking of iterating over the list and comparing the bits one by one , problem is that my iterator stars before firstlink (LSB) , I know I could move it all the way to the end and start iterating using hasPrevious() but I don't have that method.
I wanna be able to do that while only going over each list once.
Any ideas?
public static boolean lessEq(Number num1, Number num2){
Iterator<Bit> it1 = num1.bitIterator().;
Iterator<Bit> it2 = num2.bitIterator();
}
Number constructors:
public Number(){
list = new LinkedList<Bit>();
list.add(new Bit(false));
}
/**
* Constructs a new Number from an int.
* #param number an int representing a decimal number
*/
public Number(int number) { // assignment #1
list = new LinkedList<Bit>();
if(number == 0) list.add(new Bit(false));
if (number < 0) throw new IllegalArgumentException("number cannot be negative");
else {
while (number > 0) {
if (number % 2 == 0) {
list.add(new Bit(false));
}else list.add(new Bit(true));
number = number / 2;
}
}
}
Edit: it Works Thanks very much for the comments !
Initially you assume that both numbers are equal.
You get bits from both numbers. Use zero if either was exhausted.
If both bits are equal, you don't alter the result.
If bit from number A is 1, then set number A to be larger.
If bit from number B is 1, then set number B to be larger.
If both lists are exhausted, return result.
Otherwise repeat from step 2.
This takes into account the case where you allow lists with unnecessary zero bits as MSB.
If you want to submit fancy homework you can start from the end, keep track of the index you're at and stop at the first comparison where the bits are not equal.
You can do an obvious thing: collect the bits in an array, then walk the two arrays backwards. Or, you can use recursion, and use the stack for storage:
public int compareTo(Number other) {
Iterator<Bit> it1 = this.bitIterator();
Iterator<Bit> it2 = other.bitIterator();
return bitCompareTo(it1, it2);
}
private static int bitCompareTo(Iterator<Bit> it1, Iterator<Bit> it2) {
if (!it1.hasNext() && !it2.hasNext()) return 0;
boolean b1 = it1.hasNext() ? it1.next().getValue() : false;
boolean b2 = it2.hasNext() ? it2.next().getValue() : false;
int cmp = bitCompareTo(it1, it2);
if (cmp != 0) return cmp;
else return Boolean.compare(b1, b2);
}
This traverses each iterator only once, but since the comparison logic is after the recursive call, you get the comparisons done as they are popped off the call stack - in reverse order, just like we want them.
Basically: If we reach the end of both iterators at the same time, we're undecided on length alone, and signal that with 0, and we kick off our recursive decision-making. (If we reach the end of one iterator sooner, we assume false to left-pad that number with zeroes.) In each recursive step, if we've decided (whether on length or on a higher bit pair), we just pass that decision along. If the higher bits were undecided, we try to compare the current bit pair (and if it's equal, Boolean.compareTo will return 0, telling the next level down that we're still undecided). If we inspected all bits and we're still undecided, we'll just say 0 now stands for "equal" - precisely what compareTo should return in that case.
Once you have compareTo, it is trivial to define the other relational operators.
I think you should try this:
public static boolean lessEq(Number num1, Number num2) {
LinkedList<Bit> bits1 = num1.list;
LinkedList<Bit> bits2 = num2.list;
if(bits1.size() == bits2.size()) {
for(int i = bits1.size() - 1; i >= 0; i++) { // reversed loop since the MSB is at the end of the list
Bit bit1 = bits1.get(i);
Bit bit2 = bits2.get(i);
if(bit1.getValue() != bit2.getValue()) {
if(bit1.getValue()){ // can be replaced with return !bit1.getValue() if you want
return false; // bit1's actual bit is true, bit2 is false, so bit1 is greater
} else {
return true;
}
}
}
return true; // all bits are the same
} else {
if(bits1.size() > bits2.size()) { // can be replaced with return bits1.size() <= bits2.size() if you want
return false; // first number has more elements, so it's greater
} else {
return true;
}
}
}
EDIT
According to comments you can do the following instead (using iterators)
public static boolean lessEq(Number num1, Number num2) {
Iterator<Bit> bits1 = num1.list.descendingIterator();
Iterator<Bit> bits2 = num2.list.descendingIterator();
while(bits1.hasNext() && bits2.hasNext()){
Bit bit1 = bits1.next();
Bit bit2 = bits2.next();
if(bit1.getValue() != bit2.getValue()) {
return !bit1.getValue();
}
}
return bits2.hasNext();
}
There’s no real problem in comparing from the least significant bit. You just need to keep track of the difference found so far, and discard it if you find a difference on a higher-order (more significant) bit. It’s easiest to do it recursively:
public class Number implements Comparable<Number> {
/** Linked list of bits, least significant bit first */
Node lsb;
public Number(int n) {
if (n < 0) {
throw new IllegalArgumentException("Negative numbers not supported, got " + n);
}
if (n == 0) {
lsb = null;
} else {
lsb = new Node(new Bit(n % 2 != 0));
n /= 2;
Node tail = lsb;
while (n > 0) {
Node newNode = new Node(new Bit(n % 2 != 0));
n /= 2;
tail.setNext(newNode);
tail = newNode;
}
}
}
#Override
public int compareTo(Number other) {
return compare(lsb, other.lsb, 0);
}
private int compare(Node left, Node right, int diffSoFar) {
if (left == null) {
if (nonZero(right)) {
return -1;
} else {
return diffSoFar;
}
}
if (right == null) {
if (nonZero(left)) {
return 1;
} else {
return diffSoFar;
}
}
int localDiff = Boolean.compare(left.getData().getValue(), right.getData().getValue());
if (localDiff != 0) {
diffSoFar = localDiff;
}
return compare(left.getNext(), right.getNext(), diffSoFar);
}
private boolean nonZero(Node list) {
if (list == null) {
return false;
}
if (list.getData().getValue()) {
return true;
}
return nonZero(list.getNext());
}
}
Example use:
Number six = new Number(6);
Number seven = new Number(7);
System.out.println("Comparing 6 and 7: " + six.compareTo(seven));
System.out.println("Comparing 15 and 6: " + new Number(15).compareTo(six));
Output:
Comparing 6 and 7: -1
Comparing 15 and 6: 1
I am assuming the following Node class:
public class Node {
private Node next;
private Bit data;
// Constructor, getters, setters
}

Why is Integer.MIN_VALUE failing on Balanced Binary Tree? What's the bug?

https://leetcode.com/problems/balanced-binary-tree/
Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as a binary
tree in which the depth of the two subtrees of every node never differ
by more than 1.
public class Solution {
public boolean isBalanced(TreeNode root) {
int ret = getLevel(root);
if(ret < 0)
return false;
return true;
}
public int getLevel(TreeNode node) {
if(node == null)
return 0;
int l = getLevel(node.left);
int r = getLevel(node.right);
if(Math.abs(l - r) > 1)
return -99;
return Math.max(l + 1, r + 1);
}
}
This code is Accepted.
However if I replace -99 with Integer.MIN_VALUE, my code fails. What's the bug?
e.g.
Input: [1,2,null,3,null,4,null,5]
Output: true
Expected: false
Your code is failing because of integer arithmetic which is overflowing. The following code snippet will demonstrate this:
int val = Integer.MIN_VALUE;
System.out.println(val);
val -= 3;
System.out.println(val);
Output:
-2147483648
2147483645
Now consider what is happening in your actual code:
int l = getLevel(node.left);
// l == -2147483648 == Integer.MIN_VALUE assuming your base case is hit
int r = getLevel(node.right);
// assuming positive r, then Math.abs() will return a massively positive number
if (Math.abs(l - r) > 1)
return -99;
In other words, the above if statement will be firing true when it really should have fired false.
Solution:
If you modify the getLevel() method to the following, you should skirt the problems you are having:
public int getLevel(TreeNode node) {
if(node == null)
return 0;
int l = getLevel(node.left);
int r = getLevel(node.right);
if ( (l < 0 ^ r < 0) || Math.abs(l - r) > 1) {
// you can simply return -1 here, since an actual
// level should never have a negative value
return -1;
}
else {
return Math.max(l + 1, r + 1);
}
}
It may fail under some circumstances due to overflow. If l is zero and r is Integer.MIN_VALUE, l-r is actually negative because it overflows. As a result, the condition will fail and the next statement returns max of MIN_VALUE+1 and zero+1.

Probability of multiple dice rolls with recursion

How would I go about using recursion to calculate the probability of rolling a certain number, r, with a given number of dice? I tried to treat this as a choose problem but am still quite confused as to how the algorithm should work.
For example, it should work out to be something like this:
P(4,14)=(1/6)P(3,13)+(1/6)P(3,12)+(1/6)P(3,11)+(1/6)P(3,10)+(1/6)P(3,9)+(1/6)P(3,8)
P(3,8)=(1/6)P(2,7)+(1/6)P(2,6)+(1/6)P(2,5)+(1/6)P(2,4)+(1/6)P(2,3)+(1/6)P(2,2)
P(2,4)=(1/6)P(1,3)+(1/6)P(1,2)+(1/6)P(1,1)+(1/6)P(1,0)+(1/6)P(1,-1)+(1/6)P(1,-2)
=(1/6)(1/6)+(1/6)(1/6)+(1/6)(1/6)+(1/6)(0)+(1/6)(0)+(1/6)(0)
I'm just having trouble converting it into code.
static double P(int dice, int r) {
int ret = 1;
for (int i = 2; i < 7; i++) {
ret = (1/6)(ret*(dice-i))/(i+1);
}
return ret;
}
static double RollDice(int dice,int r) {
if (dice==1 && (r<1 || r>6)){
return 0;
}
if (dice==1 && (r>=1 && r<=6)){
return (1.0/6);
}
else {
return ((1.0/6)*P(dice-1,r-1));
}
I do not understand why you have to separate methods P() and RollDice(), since in your formulae you (correctly) describe everything with P.
If you were to put your formulae into code, it should look something like this:
EDIT: changed the base case to 0 dice, since then it becomes even simpler.
static double P(int dice, int r) {
if (dice == 0) {
// Zero dice: probabiliy 1 to get 0
if (r == 0) {
return 1.0;
} else {
return 0.0;
}
else {
// Multiple dice: recursion
double sum = 0.0;
for (/* TODO */) {
sum += //TODO
}
}
}
For the recursion part, try working it out by looking at the formula:
P(4, 14) = (1/6)P(3, 13) + (1/6)P(3, 12) + ... + (1/6)P(3, 8)
i.e. in the general case
P(dice, r)=(1/6)P(dice-1, r-1) + (1/6)P(dice-1, r-2) + ... + (1/6)P(dice-1, r-6)
meaning that you have to loop from r-6 to r-1.
And since you are taking a sum over multiple recursive calls, you have to use an accumulator initialized to 0. (The variable I called sum)
EDIT: Click here for a complete example, compare to WolframAlpha to verify the result.

Java Exponential Method

I need to write a method that will take a base and raises it to any integer power, positive or negative. It can be assumed that the base will not be 0.
In the method I need to call a recursive method and use it.
Here is the previous recursive method I need to use:
public static double nonNegInt(double base, int pow)
{
if (pow == 0)
return 1;
else
return base * nonNegInt(base,pow-1);
}
So my question is, can someone please help or show me how to write the method I need?
I know the current method is fine, but I need to call it in another method. When I do this I am getting a runtime error
Your method is a good start, although you will need to handle negative exponents as stated in your requirements. Take advantage of the fact that x^(-n) = 1.0 / x^n.
This is how you handle negative values too:
public static double nonNegInt(double base, int pow)
{
if (pow == 0)
return 1;
else if(pow < 0)
return (1 / nonNegInt(base, -pow));
else
return base * nonNegInt(base,pow-1);
}
Running it:
public static void main(String args[])
{
double result = nonNegInt(4,-1);
System.out.println(result); //Will print 0.25
}
Of course you should give it a meaningful name, since now it does handle negative cases.
public BigDecimal exp(BigDecimal base, BigInteger pow) {
if(base == null || base.intValue() == 0 ) return BigDecimal.ZERO;
BigInteger absPow = pow.abs();
if(absPow.intValue() == 0) return BigDecimal.ONE;
if(absPow.intValue() == 1) return pow.intValue() > 0 ? base :
BigDecimal.ONE.divide(base, MathContext.DECIMAL128);
if(absPow.intValue() == 2) return pow.intValue() > 0 ? base.multiply(base):
BigDecimal.ONE.divide(base.multiply(base), MathContext.DECIMAL128);
BigInteger i = BigInteger.ONE;
BigDecimal result = base;
HashMap<BigInteger, BigDecimal> history = new HashMap<>();
history.put(i, result);
while (i.compareTo(absPow) < 0) {
if(i.add(i).compareTo(absPow) <= 0) {
i = i.add(i);
result = result.multiply(result);
history.put(i, result);
} else {
BigInteger diff = absPow.subtract(i);
for (; diff.intValue() > 0 && !history.containsKey(diff); diff = diff.subtract(BigInteger.ONE));
i = i.add(diff);
result = result.multiply(history.get(diff));
history.put(i, result);
}
}
return pow.intValue() > 0 ? result : BigDecimal.ONE.divide(result, MathContext.DECIMAL128);
}

Categories

Resources