What is wrong with my solution of SPOJ ACTIV? - java

Here is the link for the problem:SPOJ - ACTIV
I came up with the recurrence for the problem as:
F(i) = 1+F(i+1)+F(next(activities[i].endtime))
where next() finds out the index of the activity with start time>= end time of the current activity, while the activities have been sorted in increasing order of their Start time.
This is my java solution, although it passes many test cases of SPOJ toolkit, however it does give WA for some. What is the problem in my concept/solution?
import java.util.*;
import java.io.*;
class Pair<T>{
final T x;
final T y;
Pair(T a, T b){
this.x = a;
this.y = b;
}
}
public class Activities{
private static int search(Pair<Integer> []p,int key, int l, int h)
{
int ll=l;
while(l<h)
{
int mid = (l+h)/2;
if(p[mid].x < key)l=mid+1;
else if(p[mid].x == key){
while(mid>=ll && p[mid].x == key)mid--;
return mid+1;
}
else h=mid;
}
if(l==h && l>=0 && p[l].x>=key)return l;
return -1;
}
public static void main(String[] args)throws IOException {
final long mod = 100000000;
BufferedReader buff = new BufferedReader(new InputStreamReader(System.in));
while(true)
{
int n = Integer.parseInt(buff.readLine());
if(n==-1)return;
Pair <Integer> p [] = new Pair[n];
for(int i=0;i<n;i++){
String [] in = buff.readLine().split(" ");
int x = Integer.parseInt(in[0]), y = Integer.parseInt(in[1]);
p[i] = new <Integer>Pair(x,y);
}
Arrays.sort(p, new Comparator<Pair<Integer>>(){
public int compare(Pair<Integer> p1, Pair<Integer> p2){
if(p1.x == p2.x)return p1.y - p2.y;
else return p1.x - p2.x;
}
});
long dp[] = new long[n];
dp[n-1] = 1;
for(int i=n-2;i>=0;i--)
{
int idx = search(p,p[i].y,i,n-1);
dp[i] = 1+dp[i+1];
if(idx != -1)dp[i]=dp[i]+dp[idx];
}
String res = (dp[0]%mod)+"";
while(res.length()<8)res = '0'+res;
System.out.println(res);
}
}
}

Your code is able to exceed a long type scope. You should perform your calculation with more frequent casting to the [0, mod) range. This should be enough to fix your issue and solve this Spoj's problem:
for(int i=n-2;i>=0;i--)
{
int idx = search(p,p[i].y,i,n-1);
dp[i] = 1+dp[i+1]%mod;
if(idx != -1)dp[i]=(dp[i]%mod+dp[idx]%mod)%mod;
}

Related

Fibonnaci Sequence

I'm a absolutly beginner in java and i want to write a code with the acm.libary, which is about the fibonacci sequence.
The result is very nice for me, but i want only print the last number of the sequence. I don't know how.
If the user type n = 5, the result need to be 8.
If the user type n = 8, the result need to be 21.
In my program it is the last number, but the program also prints all the previous numbers.
I hope you can understand me :D
Thank you in advance!
int a = 1;
int b = 0;
public void run() {
int n = readInt ("n: ");
for(int i = 1; i <= n; i++) {
println (fibonacci (n));
}
}
private int fibonacci(int n) {
int c = (a) + (b);
a = b;
b = c;
return c;
}
Try this code.
import java.util.Scanner;
public class Test {
int a = 1;
int b = 0;
public int run() {
#SuppressWarnings("resource")
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int value =0;
for(int i = 1; i <= n; i++) {
value = fibonacci (n);
}
return value;
}
private int fibonacci(int n) {
int c = (a) + (b);
a = b;
b = c;
return c;
}
public static void main (String arg[])
{
Test t = new Test();
System.out.println(t.run());
}
}
You can replace the body of the loop by this:
if (i == n) {
println (fibonacci (n));
} else {
fibonacci (n);
}

code not printing when trying to find numbers that are both star and triangular numbers

Im trying to write the code for a program that prints values that are both star and triangle numbers. Although the code just doesnt seem to work and wont print out any values, the function for the starNumbers is working fine although i think that the function for the triangle number is a bit iffy, im not really sure where the problem is.
All help would be greatly appreciated
thanks
public class TriangularNumbers {
public static void main(String[] args) {
int n = 1;
int i = 1;
int star = starNumbers(n);
int triangle = triangleNumbers(i, n);
while (star > 0)
{
while (star < triangle)
{
n++;
star = starNumbers(n);
}
while (triangle < star)
{
triangle = triangleNumbers(i, n);
}
if (star==triangle)
{
System.out.println(star);
}
}
}
private static int starNumbers (int n) {
int s = ((6*n)*(n-1)+1);
return s;
}
private static int triangleNumbers( int i, int n){
int star = starNumbers(n);
int t = 0;
while (t<=star)
{
t = t + i;
i++;
}
return t;
}
}
This is an empty loop:
while (star > 0);
Should be
while(star > 0)
However, I see that if(star==traingle) condition is never true, so no output is seen.
//try this
public class TriangularNumbers {
public static void main(String[] args) {
int n = 1;
int i = 1;
int star = starNumbers(n);
int triangle = 0;
while (star > 0){
star = starNumbers(n++);
triangle=0;
//System.out.println("Star "+star);
while(triangle < star){
triangle = triangleNumbers(i,star);
if(star == triangle){
System.out.println("match at "+star);
}
}
}
}
private static int starNumbers (int n) {
int s = ((6*n)*(n-1)+1);
return s;
}
private static int triangleNumbers( int i, int star){
int t = 0;
while (t<star){
t = i*(i+1)/2; //get next triangle
i++;
}
return t;
}
}

Optimization of a Java code

This is a code in an online contest I've been trying. The time limit set at the online judge is 1 sec and the order of test cases is 10^5.
import java.util.Scanner;
class My_Number {
int primeNo;
boolean divisible[] = new boolean [60];
My_Number(int primeNo) {
this.primeNo = primeNo;
}
void setDivisible() {
for (int i=0; i<60; i++) {
if(i%primeNo == 0) {
divisible[i] = true;
}
}
}
}
class BestWorse {
My_Number gb [] = {
new My_Number(2), new My_Number(3), new My_Number(5), new My_Number(7), new My_Number(11),
new My_Number(13), new My_Number(17), new My_Number(19), new My_Number(23), new My_Number(29),
new My_Number(31), new My_Number(37), new My_Number(41), new My_Number(43), new My_Number(47),
new My_Number(53), new My_Number(59)
};
boolean master_list [] = new boolean [86400];
void initialize() {
for (My_Number gb1 : gb) {
gb1.setDivisible();
}
}
private boolean isBad(int hh, int mm, int ss) {
for(My_Number gb1: gb) {
if(gb1.divisible[hh] && gb1.divisible[mm] && gb1.divisible[ss]) {
return true;
}
}
return false;
}
private int findGCD(int a, int b) {
int r, i;
while(b!=0){
r = a % b;
a = b;
b = r;
}
return a;
}
void fillUpTheMasterList() {
int hh =0, mm = 0, ss = 1;
while( !(hh==0 && ss==0 && mm==0)) {
if (isBad(hh, mm, ss)) {
master_list[hh*60*60+mm*60+ss] = true;
}
ss++;
if(ss == 60) {
ss = 0;
mm++;
if(mm == 60) {
mm = 0;
hh++;
if(hh == 24) {
hh = 0;
}
}
}
}
}
String countBestAndWorse(int hh, int mm, int ss) {
int good = 0, bad = 0;
for(int i=hh*60*60+mm*60+ss; i<86400; i++) {
if(master_list[i]) {
bad++;
}
else {
good++;
}
}
if(good != 0 && bad != 0)
{
int gcd = findGCD(good, bad);
good /= gcd;
bad /= gcd;
}
return bad + ":" +good;
}
public static void main(String[]args) {
int n;
Scanner scn = new Scanner(System.in);
BestWorse best_worse = new BestWorse();
best_worse.initialize();
best_worse.fillUpTheMasterList();
n = scn.nextInt();
for(int i=0; i<n;i++) {
int hh = scn.nextInt();
int mm = scn.nextInt();
int ss = scn.nextInt();
System.out.println(best_worse.countBestAndWorse(hh, mm, ss));
}
}
}
For some reason, I am continuously getting the error as 'Time limit exceeded'.
Things I tried:
Using BufferedReader instead of Scanner
Maintaining a master_list of the answer(already implemented in my solution).
I tried the Netbeans profiler and it's output for input of 5000 (hh=0 mm=0 ss=1) numbers is pasted here. Also, the question is posted here.
From the profiler, it seems like findGCD is taking up majority of the time. But I googled around and found out that this is indeed the fastest algorithm to calculate GCD. I also tried to maintain a lookup table for GCD; perhaps the same GCD is calculated again and again. Still no luck!
I've reached my limit for this question and need help. Can anyone please help me out here?
Its all about using the correct algorithm.
Check out this approach:
import java.util.Scanner;
public class GoodBadTime
{
private int goodTimeCounter[][][];
private int badTimeCounter[][][];
private static final int primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23 };
public GoodBadTime ()
{
initializeGoodBadTimes ();
try (Scanner scanner = new Scanner (System.in))
{
int testCases = scanner.nextInt ();
for (int i = 0; i < testCases; ++i)
{
int h = scanner.nextInt ();
int m = scanner.nextInt ();
int s = scanner.nextInt ();
System.out.println (badTimeCounter[h][m][s] + ":" + goodTimeCounter[h][m][s]);
}
}
}
private void initializeGoodBadTimes ()
{
goodTimeCounter = new int[24][60][60];
badTimeCounter = new int[24][60][60];
int cumulativeGoodCounter = 0;
int cumulativeBadCounter = 0;
for (int h = 23; h >= 0; --h)
{
for (int m = 59; m >= 0; --m)
{
for (int s = 59; s >= 0; --s)
{
boolean isBadTime = false;
int prime;
for (int p = 0; p < primes.length && ((prime = primes[p]) <= h); ++p)
{
if (h % prime == 0 && m % prime == 0 && s % prime == 0)
{
isBadTime = true;
break;
}
}
if (isBadTime)
{
++cumulativeBadCounter;
}
else
{
++cumulativeGoodCounter;
}
int gcd = GCD (cumulativeGoodCounter, cumulativeBadCounter);
goodTimeCounter[h][m][s] = cumulativeGoodCounter / gcd;
badTimeCounter[h][m][s] = cumulativeBadCounter / gcd;
}
}
}
}
private int GCD (int p, int q)
{
if (p == 0 || q == 0)
{
return 1;
}
while (q != 0)
{
int temp = q;
q = p % q;
p = temp;
}
return p;
}
public static void main (String[] args)
{
new GoodBadTime ();
}
}
Let me know if there's something I need to explain in my code that isn't obvious, so that I can edit my answer and explain it to you.
This was just my first attempt to solve it, there can be better ways to do it as well.
But this approach should give out the output within 1 second, so I guess, I don't cross the threshold limit with this approach.
Update
Here's an update to the answer:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class GoodBadTime
{
private int goodTimeCounter[];
private int badTimeCounter[];
private static final int primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23 };
public GoodBadTime ()
{
initializeGoodBadTimes ();
try (BufferedReader reader = new BufferedReader (new InputStreamReader (System.in)))
{
int testCases = Integer.parseInt (reader.readLine ());
for (int i = testCases; i > 0; --i)
{
String[] hms = reader.readLine ().split ("\\s+");
int h = Integer.parseInt (hms[0]);
int m = Integer.parseInt (hms[1]);
int s = Integer.parseInt (hms[2]);
int index = h + 24 * (m + 60 * s);
System.out.printf ("%d:%d\n", badTimeCounter[index], goodTimeCounter[index]);
}
}
catch (IOException e)
{
e.printStackTrace ();
}
}
private void initializeGoodBadTimes ()
{
goodTimeCounter = new int[24 * 60 * 60];
badTimeCounter = new int[24 * 60 * 60];
int cumulativeGoodCounter = 0;
int cumulativeBadCounter = 0;
for (int h = 23; h >= 0; --h)
{
for (int m = 59; m >= 0; --m)
{
for (int s = 59; s >= 0; --s)
{
boolean isBadTime = false;
int prime;
for (int p = 0; p < primes.length && ((prime = primes[p]) <= h); ++p)
{
if (h % prime == 0 && m % prime == 0 && s % prime == 0)
{
isBadTime = true;
++cumulativeBadCounter;
break;
}
}
if (!isBadTime)
{
++cumulativeGoodCounter;
}
int gcd = GCD (cumulativeGoodCounter, cumulativeBadCounter);
// Original[h, m, s] = Flat[h + 24 * (m + 60 * s)]
int index = h + 24 * (m + 60 * s);
goodTimeCounter[index] = cumulativeGoodCounter / gcd;
badTimeCounter[index] = cumulativeBadCounter / gcd;
}
}
}
}
private int GCD (int p, int q)
{
if (p == 0 || q == 0)
{
return 1;
}
while (q != 0)
{
int temp = q;
q = p % q;
p = temp;
}
return p;
}
public static void main (String[] args)
{
new GoodBadTime ();
}
}
This should be faster than the previous one, since I'm using 1D array and BufferedReader this time.
Here's a C equivalent:
#include <stdio.h>
int goodTimeCounter[24 * 60 * 60];
int badTimeCounter[24 * 60 * 60];
const int primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23 };
int GCD (int p, int q)
{
if (p == 0 || q == 0)
{
return 1;
}
while (q != 0)
{
int temp = q;
q = p % q;
p = temp;
}
return p;
}
void initializeGoodBadTimes ()
{
int cumulativeGoodCounter = 0;
int cumulativeBadCounter = 0;
for (int h = 23; h >= 0; --h)
{
for (int m = 59; m >= 0; --m)
{
for (int s = 59; s >= 0; --s)
{
int isBadTime = 0;
int prime;
for (int p = 0; p < 9 && ((prime = primes[p]) <= h); ++p)
{
if (h % prime == 0 && m % prime == 0 && s % prime == 0)
{
isBadTime = 1;
++cumulativeBadCounter;
break;
}
}
if (!isBadTime)
{
++cumulativeGoodCounter;
}
int gcd = GCD (cumulativeGoodCounter, cumulativeBadCounter);
// Original[h, m, s] = Flat[h + 24 * (m + 60 * s)]
int index = h + 24 * (m + 60 * s);
goodTimeCounter[index] = cumulativeGoodCounter / gcd;
badTimeCounter[index] = cumulativeBadCounter / gcd;
}
}
}
}
int main (int argc, const char * argv[])
{
initializeGoodBadTimes();
int testCases;
scanf("%d", &testCases);
for(int i = testCases; i > 0; --i)
{
int h, m, s;
scanf("%d %d %d", &h, &m, &s);
int index = h + 24 * (m + 60 * s);
printf("%d:%d\n", badTimeCounter[index], goodTimeCounter[index]);
}
return 0;
}
Note: GCD is calculated constant number of times, irrespective of the input size.
Also, int is sufficient for this program, since no counter ever exceeds 86400 since that's the maximum number of good or bad times that can happen.
Its equally strange for me that Online Judge is calling it as "Wrong Answer", since I think I am following every constraint set by the question.
Also, while testing for the two inputs, the program gave the correct answer despite the input being far apart in time. Induction would say that it should keep giving correct answers. Do you happen to know which output is wrong?
Also, can you put a link to this question which is present on the Online Judge site, so that I can check it out myself, and provide a correct answer to you?
The contest is rather unclear; at least to me. It says "none of them was divisible by the same prime number" which makes no sense, and if it did, I'd interpret it as that all the numbers must be co-prime. The next sentence sounds more like gcd(h, gcd(m, s)) <= 1 for good days.
I'm offering some untested potential improvements to Aman Agnihotri's algorithms. By creating the cumulative table, the biggest optimization is already done.
There is a faster GDC algorithm, but I wouldn't bother as all you need is to fill a 60x60 table. This could be done even without GCD by something like
int[] gcdTable = new int[60*60];
Arrays.fill(gcdTable, 1);
for (int p=2; p<60; ++p)
for (int i=0; i<60; i+=p)
for (int j=0; j<60; j+=p)
gcdTable[60*i+j] = Math.max(gcdTable[60*i+j], p);
Then use it as
int gcd(int a, int b) {
return gcdTable[60*a+b];
}
in
boolean isGood(int h, int m, int s) {
return gcd(h, gcd(m, s)) <= 1;
}
to fill the cumulative table. I guess, using a 1D array via
int secondOfDay(int h, int m, int s) {
return 3600*h + 60*m + s;
}
should be a bit faster than a 3D array. You don't need to store both remaining good and bad seconds, as their sum equals to 24*3600 - secondOfDay. My above table is too small for use for the expressing of the B:G ratio in smallest common terms, so you'll need one proper GCD per sample.

Java: Count Inversions Algorithm logic went wrong

I am trying to write the Count inversion algorithm. It works on an array of size 10. However, things went terribly wrong, when I tried to test on an array of size 100000. I was still able to sort the array but the number of inversions is NEGATIVE, which is wrong. I don't understand which part of my logic went wrong.
My main logic: I created an array object called myArray and it has a CountSplitInv instance method that is suppose to sort the sub-arrays and return number of inversions involved.
Please help me out. I have been stuck in this for a long time now and I still wasn't able to figure out what went wrong.
I have a feeling that I don't understand Recursion concept fully.
import java.io.*;
import java.util.*;
import java.math.*;
class myArray{
private int[] input_array;
private int nElems;
public myArray(int max){
input_array = new int[max];
nElems = 0;
}
public void insert(int value){
input_array[nElems++] = value;
}
public void display(){
for(int j = 0; j < nElems; j++){
System.out.print(input_array[j] + " ");
}
System.out.println("");
}
public void SortAndCount(){
int[] output_array = new int[nElems];
int ans = SortNInversionCounts(output_array,0, nElems -1);
System.out.println("number of inversions IS: " + ans);
}
public int SortNInversionCounts(int[] output_array, int lowerBound, int upperBound){
if(lowerBound == upperBound){
return 0;
} else{
int mid = (lowerBound + upperBound)/2;
int x, y , z;
x = SortNInversionCounts(output_array, lowerBound, mid);
y = SortNInversionCounts(output_array, mid+1, upperBound);
z = CountSplitInv(output_array, lowerBound, mid+1, upperBound);
return x + y + z;
}
}
public int CountSplitInv(int[] output_array, int lowPtr, int highPtr, int upperBound){
int j = 0;
int lowerBound = lowPtr;
int mid = highPtr - 1;
int n = upperBound - lowerBound + 1;
int numOfInversions = 0;
while(lowPtr <= mid && highPtr <= upperBound){
if( input_array[lowPtr] < input_array[highPtr]){
output_array[j++] = input_array[lowPtr++];
} else{
output_array[j++] = input_array[highPtr++];
// WHERE I count number of inversions
numOfInversions = numOfInversions + (mid - lowPtr + 1);
}
}
while(lowPtr <= mid){
output_array[j++] = input_array[lowPtr++];
}
while(highPtr <= upperBound){
output_array[j++] = input_array[highPtr++];
}
for(j = 0; j < n; j++){
input_array[lowerBound+j] = output_array[j];
}
return numOfInversions;
}
}
class NumOfInversionsApp{
public static void main(String[] args) throws IOException{
// Read input file
FileInputStream fil = new FileInputStream("IntegerArray.txt");
BufferedReader br = new BufferedReader( new InputStreamReader(fil));
myArray in_array = new myArray(100000);
String element = null;
while( ( element = br.readLine()) != null){
in_array.insert( Integer.parseInt(element) );
}
// input_array.display();
in_array.SortAndCount();
// input_array.display();
}
}

Quadratic in Java

Could any help me start?
Using a class that I created before, I need to make a new class that specifically deals with QuadPoly. I think I have the constructors made correctly but i'm not a hundred percent sure.
public class Poly {
private float[] coefficients;
public static void main (String[] args){
float[] fa = {3, 2, 4};
Poly test = new Poly(fa);
}
public Poly() {
coefficients = new float[1];
coefficients[0] = 0;
}
public Poly(int degree) {
coefficients = new float[degree+1];
for (int i = 0; i <= degree; i++)
coefficients[i] = 0;
}
public Poly(float[] a) {
coefficients = new float[a.length];
for (int i = 0; i < a.length; i++)
coefficients[i] = a[i];
}
public int getDegree() {
return coefficients.length-1;
}
public float getCoefficient(int i) {
return coefficients[i];
}
public void setCoefficient(int i, float value) {
coefficients[i] = value;
}
public Poly add(Poly p) {
int n = getDegree();
int m = p.getDegree();
Poly result = new Poly(Poly.max(n, m));
int i;
for (i = 0; i <= Poly.min(n, m); i++)
result.setCoefficient(i, coefficients[i] + p.getCoefficient(i));
if (i <= n) {
//we have to copy the remaining coefficients from this object
for ( ; i <= n; i++)
result.setCoefficient(i, coefficients[i]);
} else {
// we have to copy the remaining coefficients from p
for ( ; i <= m; i++)
result.setCoefficient(i, p.getCoefficient(i));
}
return result;
}
public void displayPoly () {
for (int i=0; i < coefficients.length; i++)
System.out.print(" "+coefficients[i]);
System.out.println();
}
private static int max (int n, int m) {
if (n > m)
return n;
return m;
}
private static int min (int n, int m) {
if (n > m)
return m;
return n;
}
public Poly multiplyCon (double c){
int n = getDegree();
Poly results = new Poly(n);
for (int i =0; i <= n; i++){ // can work when multiplying only 1 coefficient
results.setCoefficient(i, (float)(coefficients[i] * c)); // errors ArrayIndexOutOfBounds for setCoefficient
}
return results;
}
public Poly multiplyPoly (Poly p){
int n = getDegree();
int m = p.getDegree();
Poly result = null;
for (int i = 0; i <= n; i++){
Poly tmpResult = p.multiByConstantWithDegree(coefficients[i], i); //Calls new method
if (result == null){
result = tmpResult;
} else {
result = result.add(tmpResult);
}
}
return result;
}
public void leadingZero() {
int degree = getDegree();
if ( degree == 0 ) return;
if ( coefficients[degree] != 0 ) return;
// find the last highest degree with non-zero cofficient
int highestDegree = degree;
for ( int i = degree; i <= 0; i--) {
if ( coefficients[i] == 0 ) {
highestDegree = i -1;
} else {
// if the value is non-zero
break;
}
}
float[] newCoefficients = new float[highestDegree + 1];
for ( int i=0; i<= highestDegree; i++ ) {
newCoefficients[i] = coefficients[i];
}
coefficients = newCoefficients;
}
public Poly differentiate(){
int n = getDegree();
Poly newResult = new Poly(n);
if (n>0){ //checking if it has a degree
for (int i = 1; i<= n; i++){
newResult.coefficients[i-1]= coefficients[i] * (i); // shift degree by 1 and multiplies
}
return newResult;
} else {
return new Poly(); //empty
}
}
public Poly multiByConstantWithDegree(double c, int degree){ //used specifically for multiply poly
int oldPolyDegree = this.getDegree();
int newPolyDegree = oldPolyDegree + degree;
Poly newResult = new Poly(newPolyDegree);
//set all coeff to zero
for (int i = 0; i<= newPolyDegree; i++){
newResult.coefficients[i] = 0;
}
//shift by n degree
for (int j = 0; j <= oldPolyDegree; j++){
newResult.coefficients[j+degree] = coefficients[j] * (float)c;
}
return newResult;
}
}
Out of this, I need to create a method that factors a Quadratic in two factors (if it has real roots), or in a constant ”1” polynomial factor and itself, if there are no real roots. The method should return an array of two QuadPoly objects, containing each factor.
public class QuadPoly extends Poly
{
private float [] quadcoefficients;
public QuadPoly() {
super(2);
}
public QuadPoly(float [] a) {
quadcoefficients = new float[a.length];
for (int i = 0; i <a.length; i ++){
quadcoefficients[i] = a[i];
if (quadcoefficients.length > 2){
throw new IllegalArgumentException ("Must be Quadratic");
}
}
}
public QuadPoly(Poly p){
if (quadcoefficients.length > 2){
throw new IllegalArgumentException ("Must be Quadratic");
}
}
public QuadPoly addQuad (QuadPoly p){
return new QuadPoly(super.add(p));
}
public Poly multiplyQuadPoly (Poly p){
if (quadcoefficients.length > 2){
throw new IllegalArgumentException ("Must be Quadratic");
}
Poly newResult = null;
new Result = multiplyPoly(p);
}
}
}
Edit:
Sorry. This is what I have going on for the factoring so far. The big problem with it is that I'm not too sure how to get the inheritance to work properly.
This is my New Factoring. It doesn't work. Can anyone give me some hints to get on the right path? I understand that I need to return Poly so i'm replacing the arrays there as you can tell by the first if statement but it won't let me progress as its says it requires (int, float). I've casted it but it still won't allow me. Thanks
public QuadPoly factor(){
double a = (double) getCoefficient(0);
double b = (double) getCoefficient(1);
double c = (double) getCoefficient(2);
QuadPoly newCoefficients = new QuadPoly(4);
double equa = Math.sqrt((b*b) - (4*a*c));
if (equa > 0){
newCoefficients.setCoefficient(0, (float) (-b + equa)/(2*a));
newCoefficients.setCoefficient(1, (float) (-b - equa)/(2*a));
}
if (equa ==0){
newCoefficients[0] = 1;
newCoefficients[1] = (-b + equa)/(2*a);
}
if (equa < 0){
newCoefficients[0] = 0;
newCoefficients[1] = 1;
}
return (QuadPoly) newCoefficients;
}
OK you have made a reasonable attempt. Inheritance is simple here, all you need is the constructors:
class QuadPoly extends Poly{
public QuadPoly(){ super(2); }
public QuadPoly(float[] f){
super(f);
if(coefficients.length!=2) throw new IllegalArgumentException("not quad");
}
}
and that's pretty much all! I hope you can see, that the same code as Poly is used for everything else, and the same field coefficients does all the same work as it did before.
Now, in the factorisation
you have dimmed your double[] newCoefficients as size 1. too small!
you have tried to square-root your discriminant without knowing that it is positive!
you are returning an array of 2 doubles as your answer. you need two Polys. You haven't provided a method return type for factor
I suggest you use
public QuadPoly[] factor(){
}
as the signature. The rest is just maths!
The idea of subclassing Poly into QuadPoly is so that you can reuse as many of the old Poly methods as possible. Now, all your old methods use the array float[] coefficients, and your new QuadPoly inherits this field.
Why have you created a new field quadcoefficients[] ? It suffices to check in any constructor that there are only 3 members in the array, but to still harness the existing field coefficients[].
If you do this, all your old methods will still work! Only, they will return generic Poly. Since the QuadPoly must conform to the contract of a Poly, this is probably OK. The method multiplyCon is the only one that could be guaranteed to return another QuadPoly anyway.
You don't seem to have attempted a factorisation yet. Do you have any ideas? Well, here's a clue: you'll need to use something like
if (DISCRIMINANT >= 0) {
} else{
}

Categories

Resources