Getting polynomial form from roots of polynomial - java

I would like to expand polynomial from form like this : (x - x1) (x-x2) (x-x3) ...
while I have x1,x2,x3... in form of array, to polynomial form like a x^3 + b x^2 + c , where arguments are in array.

For the logic of this, see what the expansions look like on Wolfram alpha (e.g. expand (x-a)(x-b)(x-c)(x-d)(x-e)).
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main
{
public static void main(String[] args)
{
// (x-5)(x-4)(x-3)(x-2)(x-7)
int[] xs = { 5, 4, 3, 2, 7 };
List<Integer> coefficients = new ArrayList<>();
boolean positive = true;
for (int i = 0; i < xs.length + 1; ++i) {
int coefficient = 0;
if (i > 0) {
List<int[]> combos = combos(xs, i);
for (int[] nums : combos) {
int product = 1;
for (int num : nums) {
product *= num;
}
coefficient += product;
}
} else {
coefficient = 1;
}
coefficients.add(coefficient * (positive ? 1 : -1));
positive = !positive;
}
for (int i = 0; i < coefficients.size(); ++i) {
int coefficient = coefficients.get(i);
int exponenent = (coefficients.size() - i - 1);
System.out.print(coefficient + "*x^" + exponenent + (exponenent == 0 ? "" : " + "));
}
}
// Combinations of xs size k
private static List<int[]> combos(int[] xs, int k)
{
List<int[]> result = new ArrayList<>();
for (ArrayList<Integer> comboIdxs : combine(xs.length, k)) {
int[] combo = new int[comboIdxs.size()];
for (int i = 0; i < comboIdxs.size(); ++i) {
combo[i] = xs[comboIdxs.get(i)];
}
result.add(combo);
}
return result;
}
// Thanks http://www.programcreek.com/2014/03/leetcode-combinations-java/
public static ArrayList<ArrayList<Integer>> combine(int n, int k) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
if (n <= 0 || n < k)
return result;
ArrayList<Integer> item = new ArrayList<Integer>();
dfs(n, k, 0, item, result); // because it need to begin from 1
return result;
}
private static void dfs(int n, int k, int start, ArrayList<Integer> item,
ArrayList<ArrayList<Integer>> res) {
if (item.size() == k) {
res.add(new ArrayList<Integer>(item));
return;
}
for (int i = start; i < n; i++) {
item.add(i);
dfs(n, k, i + 1, item, res);
item.remove(item.size() - 1);
}
}
}

Related

Java finding the smallest integer in a speciofic position in a sets of integer

Algorithm:
Procedure SELECT( k,S)
{ if ISI =1 then return the single element in S
else { choose an element a randomly from S;
let S1,S2,and S3 be he sequences of elements in S
less than, equal to, and greater than m, respectively;
if IS1I >=k then return SELECT(k,S1)
else
if (IS1I + IS2I >=k then return m
else return SELECT(k-IS1I-IS2I , S3);
}
}
The question is to implement the first algorithm for finding the kth smallest integer in a set of integers and test your program for different sets of integers generated by a random number generator.
Below is my solution.
import java.util.Random;
import java.util.Scanner;
public class main {
private static Random rand = new Random();
private static Scanner keyboard = new Scanner(System.in);
public static int firstAlgorithm(int k, int[] S) {
int m = S[rand.nextInt(S.length)];
int[] S1 = new int[S.length];
int[] S2 = new int[S.length];
int[] S3 = new int[S.length];
int p = 0;
int q = 0;
int r = 0;
if (S.length == 1)
return S[0];
for (int i = 0; i < S.length; i++) {
if (S[i] < m) {
S1[p] = S[i];
p++;
} else if (S[i] == m) {
S2[q] = S[i];
q++;
} else {
S3[r] = S[i];
r++;
}
}
S1 = trimToSize(S1, p);
S2 = trimToSize(S2, q);
S3 = trimToSize(S3, r);
if (S1.length >= k)
return firstAlgorithm(k, S1);
else if (S1.length + S2.length >= k)
return m;
else
return firstAlgorithm(k - S1.length - S2.length, S3);
}
private static int[] trimToSize(int[] arr, int size) {
int[] temp = new int[size];
for (int i = 0; i < size; i++) {
temp[i] = arr[i];
}
return temp;
}
public static void printArray(int[] S) {
for (int i = 0; i < S.length; i++) {
System.out.print(S[i] + "\t");
if (i % 10 == 9)
System.out.println();
}
}
// start main method
public static void main(String[] args) {
System.out.print("Enter the size of an array: ");
int size = keyboard.nextInt();
while (size < 1) {
System.out.println("Size of the array should be greater than 0.");
System.out.print("Enter the size of an array: ");
size = keyboard.nextInt();
}
System.out.print("Enter the value of k: ");
int k = keyboard.nextInt();
while (k < 1 || k > size) {
System.out.println("Value of k should be in the range 1-" + size + ".");
System.out.print("Enter the value of k: ");
k = keyboard.nextInt();
}
int[] S = new int[size];
for (int i = 0; i < size; i++) {
S[i] = 100 + rand.nextInt(900);
}
System.out.println("\nRandom values generated in the array:");
printArray(S);
System.out.println();
System.out.println(k + "th smallest value in the array using Algorithm #1: " + firstAlgorithm(k, S));
}
}
But I need to implement the above algorithm without using a temporary array for partitioning. How can I do it?
The algorithm is Dijkstra's 3-way partition.
You will have to modify the original S.
Untested (pseudo) code ahead
public static int partition(int left, int right, int[] S) {
int m = rand.nextInt(right-left); // protect against malicious data
swap(S[left+m], S[right]);
int equal = left;
while (left < right) {
if (a[left] < a[n])
swap(S, left++, equal++)
else if (a[left] == a[n])
swap(S, left, --right);
else
left++;
}
return left, equal;
}
public static int firstAlgorithm(int k, int left, int right, int[] S) {
if (left == right)
return S[left];
int p, e = partition(left, right, S); // returns 2 values. S1=[0,p), S2=[p,e), S3=[e, n)
if (p >= k)
return firstAlgorithm(k, left, p, S);
else if (e >= k) // p < k
return S[p]; // p is the first equal, e is first larger than equal
else // e < k
return firstAlgorithm(k, e, right, S);
}
// test
S = {1, 4, 2, 6, 2};
k = 2;
int result = firstAlgorithm(2, 0, S.length-1, S);
assert(result == 2);
Warning syntax and off-by-one errors guarantied.
See here multiple ways to return 2 values in java.

Is there a test case scenario in which my program will fail?

Problem : You have L, a list containing some digits (0 to 9). Write a function solution(L) which finds the largest number that can be made from some or all of these digits and is divisible by 3. If it is not possible to make such a number, return 0 as the solution. L will contain anywhere from 1 to 9 digits. The same digit may appear multiple times in the list, but each element in the list may only be used once.
Test Cases :
Input:
Solution.solution({3, 1, 4, 1})
Output: 4311
Input:
Solution.solution({3, 1, 4, 1, 5, 9})
Output: 94311
My Program :
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;
public class Solution {
static ArrayList<Integer> al = new ArrayList<Integer>();
static ArrayList<Integer> largest = new ArrayList<Integer>();
static int o = 1;
static int po = 0;
static void combinations(String[] digits, String[] data, int start, int end, int index, int r)
{
if (index == r)
{
String temp = "0";
for (int j = 0; j < r; j++)
{
temp = temp + data[j];
// System.out.print(data[j]);
}
Integer d = Integer.parseInt(temp);
al.add(d);
// System.out.println(al);
}
for (int i = start; i <= end && ((end - i + 1) >= (r - index)); i++)
{
data[index] = digits[i];
combinations(digits, data, i + 1, end, index + 1, r);
}
}
static void printCombinations(String[] sequence, int N)
{
String[] data = new String[N];
for (int r = 0; r < sequence.length; r++)
combinations(sequence, data, 0, N - 1, 0, r);
}
static String[] convert(int[] x)
{
String c[] = new String[x.length];
for(int i=0; i < x.length; i++)
{
Integer k = x[i];
if(k==0)
{
o = o * 10;
continue;
}
c[i] = k.toString();
}
// System.out.println(o);
c = Arrays.stream(c).filter(s -> (s != null && s.length() > 0)).toArray(String[]::new);
po = c.length;
// System.out.println("Come"+ Arrays.asList(c));
return c;
}
public static int solution(int[] l) {
if(l.length==0)
return 0;
if(IntStream.of(l).sum()%3==0)
{
String x = "";
Arrays.sort(l);
for (int i = l.length - 1; i >= 0; i--) {
x = x + l[i];
}
return Integer.parseInt(x);
}
printCombinations(convert(l),po);
al.sort(Comparator.reverseOrder());
al.remove(al.size()-1);
al.removeIf( num -> num%3!=0);
if(al.isEmpty())
return 0;
for(int i=0; i< al.size(); i++)
{
Integer n = al.get(i);
printMaxNum(n);
}
// System.out.println(al);
// System.out.println(largest);
return largest.get(0)*o;
}
static void printMaxNum(int num)
{
// hashed array to store count of digits
int count[] = new int[10];
// Converting given number to string
String str = Integer.toString(num);
// Updating the count array
for(int i=0; i < str.length(); i++)
count[str.charAt(i)-'0']++;
// result is to store the final number
int result = 0, multiplier = 1;
// Traversing the count array
// to calculate the maximum number
for (int i = 0; i <= 9; i++)
{
while (count[i] > 0)
{
result = result + (i * multiplier);
count[i]--;
multiplier = multiplier * 10;
}
}
// return the result
largest.add(result);
}
public static void main(String[] args) {
System.out.println(solution(new int[]{9,8,2,3}));
}
}
My Code passes both given test cases and 3 other hidden test cases except one. I tried all possible input combinations but couldn't get to the exact failure. The return type by default is given as int and therefore they would not pass values which give output that does not fit in int. Any other scenario where my code fails?

Number of Circuits in Directed graph

There are various questions on how to find the number of cycles/circuits in a directed graph.I have mostly visited them, and i did come out with a code which does it.
I am struck at a point where my code doesn't give a cycle/circuit below of length 3.
Code:
public class CyclesInGraph {
// Graph modeled as list of edges
static int[][] graph =
{
{1, 2}, {2, 3}, {3, 4}, {4, 3},
{3, 1}
};
static List<int[]> cycles = new ArrayList<int[]>();
/**
* #param args
*/
public static void main(String[] args) {
for (int i = 0; i < graph.length; i++)
for (int j = 0; j < graph[i].length; j++)
{
findNewCycles(new int[] {graph[i][j]});
}
for (int[] cy : cycles)
{
String s = "" + cy[0];
for (int i = 1; i < cy.length; i++)
{
s += "," + cy[i];
}
o(s);
}
}
static void findNewCycles(int[] path)
{
int n = path[0];
int x;
int[] sub = new int[path.length + 1];
for (int i = 0; i < graph.length; i++)
for (int y = 0; y <= 1; y++)
if (graph[i][y] == n)
// edge refers to our current node
{
x = graph[i][(y + 1) % 2];
if (!visited(x, path))
// neighbor node not on path yet
{
sub[0] = x;
System.arraycopy(path, 0, sub, 1, path.length);
// explore extended path
findNewCycles(sub);
}
else if ((path.length > 2) && (x == path[path.length - 1]))
// cycle found
{
int[] p = normalize(path);
int[] inv = invert(p);
if (isNew(p) && isNew(inv))
{
cycles.add(p);
}
}
}
}
// check of both arrays have same lengths and contents
static Boolean equals(int[] a, int[] b)
{
Boolean ret = (a[0] == b[0]) && (a.length == b.length);
for (int i = 1; ret && (i < a.length); i++)
{
if (a[i] != b[i])
{
ret = false;
}
}
return ret;
}
// create a path array with reversed order
static int[] invert(int[] path)
{
int[] p = new int[path.length];
for (int i = 0; i < path.length; i++)
{
p[i] = path[path.length - 1 - i];
}
return normalize(p);
}
// rotate cycle path such that it begins with the smallest node
static int[] normalize(int[] path)
{
int[] p = new int[path.length];
int x = smallest(path);
int n;
System.arraycopy(path, 0, p, 0, path.length);
while (p[0] != x)
{
n = p[0];
System.arraycopy(p, 1, p, 0, p.length - 1);
p[p.length - 1] = n;
}
return p;
}
// compare path against known cycles
// return true, iff path is not a known cycle
static Boolean isNew(int[] path)
{
Boolean ret = true;
for(int[] p : cycles)
{
if (equals(p, path))
{
ret = false;
break;
}
}
return ret;
}
static void o(String s)
{
System.out.println(s);
}
// return the int of the array which is the smallest
static int smallest(int[] path)
{
int min = path[0];
for (int p : path)
{
if (p < min)
{
min = p;
}
}
return min;
}
// check if vertex n is contained in path
static Boolean visited(int n, int[] path)
{
Boolean ret = false;
for (int p : path)
{
if (p == n)
{
ret = true;
break;
}
}
return ret;
}
}
Output that I am getting:
1,3,2
But i should get 3,4 also as 3-4-3 also make a cycle in graph.

Maximum valid time from 4 digits

I am trying to find the maximum valid time from given 4 digits. I have used digits (2,4,0,0). The code returnS 20:42 while it should return 20:40.
Any Suggestions on how to approach this ?
import java.util.ArrayList;
import java.util.List;
public class MaxTimeCombination {
public static void main(String[] args) {
System.out.println(solution(2, 4, 0, 0));
System.out.println(solution(3, 0, 7, 0));
}
public static String solution(int A, int B, int C, int D) {
// brute force permutation
int[] temp = new int[] {A, B, C, D};
List<List<Integer>> permutation = permute(temp);
int h = Integer.MIN_VALUE;
int m = Integer.MIN_VALUE;
boolean exists = false;
/* System.out.println("Permutations:" + permutation);
for (int i = 0; i < permutation.size(); i++) {
if (permutation.get(i).get(0) > 0 && permutation.get(i).get(0) < 3 ){
List <Integer> output = permutation.get(i);
System.out.println(output);
}
}*/
for (int i = 0; i < permutation.size(); i++) {
//if (permutation.get(i).get(0) > 0 && permutation.get(i).get(0) < 3 ){
List<Integer> k = permutation.get(i);
//System.out.println("Sorted :" + k);
int hh = k.get(0)*10 + k.get(1);
if (hh < 24) {
exists = true;
if (hh > h) {
h = hh;
}
}
int mm = k.get(2)*10 + k.get(3);
if ( mm < 60) {
exists = true;
if (mm > m) {
m = mm;
}
}
}
return (exists ? String.format("%02d:%02d", h, m) : "NOT POSSIBLE");
}
public static List<List<Integer>> permute(int[] num) {
List<List<Integer>> result = new ArrayList<>();
//start from an empty list
result.add(new ArrayList<>());
for (int i = 0; i < num.length; i++) {
//list of list in current iteration of the array num
List<List<Integer>> current = new ArrayList<>();
for (List<Integer> l : result) {
// # of locations to insert is largest index + 1
for (int j = 0; j < l.size()+1; j++) {
// + add num[i] to different locations
l.add(j, num[i]);
List<Integer> temp = new ArrayList<>(l);
current.add(temp);
//System.out.print(temp + " ");
//l.remove(num[i]);
l.remove(j);
}
}
result = new ArrayList<>(current);
}
return result;
}
}
You need to restructure your tests for h and m max. Your current code looks for the max of each independently. What you're getting is the max hour along with the max minute, even when they did not occur together in a permutation, as with 20:42.
Here's a working version of the tests.
int hh = k.get(0) * 10 + k.get(1);
if (hh < 24)
{
if (hh >= h)
{
int mm = k.get(2) * 10 + k.get(3);
if (mm < 60)
{
exists = true;
if (hh > h || mm > m)
{
m = mm;
}
h = hh;
}
}
}
Note that hh>h has become hh>=h. Even if the hour is equal to one we've seen before we need to look for a maximal minute. The code that checks for max minute has been moved within the if clause of the hour test. We need to be sure that the minute we're considering is associated with a maximal hour. Finally, we need to update the max minute when mm>m or we have a new max hour, hh>h
With this change your code gives the expected value: 20:40
I think you are overthinking for this problem. Please find the working solution as follows:
import java.util.ArrayList;
import java.util.Collections;
public class TestClass{
public static void main(String[] args)
{
int maxLimits[] = {2, 3, 5, 9};
ArrayList<Integer> list = new ArrayList<>();
list.add(3);
list.add(2);
list.add(9);
list.add(2);
Collections.sort(list);
int time[] = new int[4];
for(int i = 0; i<4; i++)
{
int index = 0;
for(int j=0; j<list.size(); j++)
{
if (list.get(j) <= maxLimits[i])
{
time[i] = list.get(j);
index = j;
}
}
list.remove(index);
}
}
}
Hope this will be helpful. :-)

Combinations of integers

I'd appreciate any help on the following problem. I have n integers from 0 to n-1, and I'm trying to generate a list of all possible combinations of length k (i.e. k concatenated integers) such that every pair of consecutive integers are not equal. So, for example, (1)(2)(3)(2) would be valid with k = 4, but (1)(2)(3)(3) would not be valid. Any ideas on how to approach this most efficiently? (I don't care much about length/degree of complexity of the code, just efficiency)
It is the code:
void Generate(int[] source, List<int[]> result, int[] build, int k, int num) {
if (num == k) {
int[] a = (int[])build.clone();
result.add(a);
return;
}
for (int i = 0; i < source.length; i++)
if (num == 0 || source[i] != build[num - 1])
{
build[num] = source[i];
Generate(source, result, build, k, num + 1);
}
}
How to call:
int k = 2;
List<int[]> a = new ArrayList<int[]>();
Generate(new int[]{1,2,3}, a, new int[k], k, 0);
public class Generator {
final int k = 2;
final char[] n = new char[]{'0','1','2','3','4','5','6','7','8','9'};
final char[] text = new char[k];
public void gen(int i, int not_n) {
if(i == k) {
System.out.println(text);
return;
}
for(int j = 0; j < n.length; j++) {
if(j == not_n) continue;
text[i] = n[j];
gen(i+1, j);
}
}
public static void main(String[] args) {
new Generator().gen(0, -1);
}
}
public static void recursiveOutput(Integer n, int k, int limit, String prints){
k++;
if(k>limit)
return;
String statePrints = prints;
//cycle through all available numbers
for(Integer i = 1; i<=n; i++)
{
statePrints = prints;
//First cycle
if(k==1){
statePrints+= "(" + i.toString() + ")";
recursiveOutput(n, k, limit, statePrints);
}
//check if predecessor is not the same
if(i != Integer.parseInt(statePrints.substring(statePrints.length()-2,statePrints.length()-1))){
statePrints += "(" + i.toString() + ")";
recursiveOutput(n, k, limit, statePrints);
}
}
//Check if the length matches the combination length
if(statePrints.length() == 3 * limit)
System.out.println(statePrints);
}
call :recursiveOutput(3,0,4,"");

Categories