Prime factorization using GUI (swing/awt) - java

This code uses Swing and awt to compute prime factorization, the code works, but it shows only one prime factor, for example: if i compute 56 the answer is just 7, how can i fix it?
thanks in advance
calculate6.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Get values from text fields
try {
int a = Integer.parseInt(input1.getText());
result.setText(String.valueOf(a + " "));
for (int i = 2; i <= a; i++) {
while (a % i == 0) {
result.setText(String.valueOf(i + " "));
// System.out.println(i + " ");
a = a / i;
}
}
if (a < 1)
result.setText(String.valueOf(a + " "));
// System.out.println(a + " ");
}
catch (Exception f) {
JOptionPane.showMessageDialog(rootPane, "ERROR: " + (f.getMessage()));
}
String aField = input1.getText();
if (e.getSource() == calculate6) {
if ("".equals(aField)) {
String emptyFieldWarning;
emptyFieldWarning = "One field is empty!";
JOptionPane.showMessageDialog(rootPane, emptyFieldWarning);
}
}
}
});
Edit 1: i have changed the operation part

Your Swing part is fine. If you just try to execute
int a = 56;
for(int i = 2; i< a; i++) {
while (a % i == 0) {
a = a / i;
}
}
System.out.println(a);
you get 7,so the problem is in this part, you shoul look over here

Problem is in the while loop. It is not accumulating the factors. Try this getPrimeFactors() in this sample program.
import java.util.*;
public class PrimeFactors {
public static void main(String[] args) {
System.out.println("56 -> " + PrimeFactors.getPrimeFactors(56));
System.out.println("30 -> " + PrimeFactors.getPrimeFactors(30));
System.out.println("154 -> " + PrimeFactors.getPrimeFactors(154));
}
public static List<Integer> getPrimeFactors(int input) {
List<Integer> factors = new ArrayList<>();
for (int i = 2; i <= input; i++) {
while (input%i == 0) {
input = input/i;
factors.add(i);
}
}
return factors;
}
}

public static final IntFunction<String> getPrimeFactorsAsString = num -> {
List<Integer> res = new ArrayList<>();
for (int i = 2, sqrt = (int)Math.sqrt(num); i <= sqrt; i++) {
while (num % i == 0) {
res.add(i);
num /= i;
}
}
return res.stream().map(String::valueOf).collect(Collectors.joining(" "));
};
Demo
System.out.println(getPrimeFactorsAsString.apply(56)); // 2 2 2 7
System.out.println(getPrimeFactorsAsString.apply(660)); // 2 2 3 5 11

Related

How to format multiplication table into 4 rows and columns respectively and test for even number multiplication table between 1 and 9?

This is the code I atempted with the guide of external video which didnt cover expected output in terms of formatting
public class Lab3Class {
public static void main(String[] args) {
// TODO Auto-generated method stub
int table = 1;
while(table<10) {
int i = 1;
while(i<=10)
{
System.out.println(table+ " * "+i+" = "+(table*i));
i++;
}
System.out.println(" ");
table++;
}
}
}
You are just missing a check for even numbers i.e. if (table % 2 == 0).
public class Main {
public static void main(String[] args) {
int table = 1;
while (table < 10) {
if (table % 2 == 0) {
int i = 1;
while (i <= 10) {
System.out.println(table + " * " + i + " = " + (table * i));
i++;
}
}
System.out.println();
table++;
}
}
}
Alternatively, you can start table with 2 and increment it by 2 in each iteration as follows:
public class Main {
public static void main(String[] args) {
int table = 2;
while (table < 10) {
int i = 1;
while (i <= 10) {
System.out.println(table + " * " + i + " = " + (table * i));
i++;
}
System.out.println();
table += 2;
}
}
}
If you need to print it in a tabular structure, you can write the loops as follows:
public class Main {
public static void main(String[] args) {
for (int line = 1; line <= 10; line++) {
for (int i = 2; i <= 10; i += 2) {
System.out.print(i + "*" + line + "=" + (i * line) + "\t");
}
System.out.println();
}
}
}
Output:
2*1=2 4*1=4 6*1=6 8*1=8 10*1=10
2*2=4 4*2=8 6*2=12 8*2=16 10*2=20
2*3=6 4*3=12 6*3=18 8*3=24 10*3=30
2*4=8 4*4=16 6*4=24 8*4=32 10*4=40
2*5=10 4*5=20 6*5=30 8*5=40 10*5=50
2*6=12 4*6=24 6*6=36 8*6=48 10*6=60
2*7=14 4*7=28 6*7=42 8*7=56 10*7=70
2*8=16 4*8=32 6*8=48 8*8=64 10*8=80
2*9=18 4*9=36 6*9=54 8*9=72 10*9=90
2*10=20 4*10=40 6*10=60 8*10=80 10*10=100
As you can see, it looks cleaner by using a for loop. However, I recommend you also practice it with a while loop. Once you gain more confidence, I also recommend you use String::format or System.out.printf for better formatting.
This is a very small data set but if the dataset is huge, you can improve the performance by reducing the I/O operation. For this, you can append the result to a StringBuilder and print it just once at the end.
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for (int line = 1; line <= 10; line++) {
for (int i = 2; i <= 10; i += 2) {
sb.append(i).append('*').append(line).append('=').append(i * line).append('\t');
}
sb.append('\n');
}
System.out.println(sb);
}
}

Why is my recursive memoized Fibonacci code wrong?

Something in the main function is wrong, but I don't know what. If I go through the code with a debugger I can see that my code isn't even reaching the fibonacci function right now.
public class Fibonacci {
public static void main(String[] args) {
for (int n=1; n<50; n++) {
System.out.println("Element "+ n + " of the sequence: " + newFib(n));
}
}
public static ArrayList<BigInteger> memo = new ArrayList<BigInteger>();
static BigInteger newFib(int n){
assert n >= 1: "the fibonacci sequence starts at 1";
BigInteger result=BigInteger.valueOf(1);
if (memo.get(n) != null) {
return memo.get(n);
}
else if( n == 1 || n == 2 ) {
memo.add(n, BigInteger.valueOf(1));
return BigInteger.valueOf(1);
}
else {
result= newFib(n-1).add(newFib(n-2));
memo.add(n,result);
return result;
}
}
}
Your code was throwing some exceptions. You simply needed to debug the exceptions and implement the proper checks. Using the code with these changes should work as intended:
import java.math.*;
import java.util.ArrayList;
public class Fibonacci {
public static void main(String[] args) {
for (int n=1; n<50; n++) {
System.out.println("Element "+ n + " of the sequence: " + newFib(n));
}
}
public static ArrayList<BigInteger> memo = new ArrayList<BigInteger>();
static BigInteger newFib(int n){
assert n >= 1: "the fibonacci sequence starts at 1";
BigInteger result=BigInteger.valueOf(1);
if (memo.size() - 1 >= n && memo.get(n) != null) {
return memo.get(n);
}
else if( n == 1 || n == 2 ) {
memo.add(n-1, BigInteger.valueOf(1));
return BigInteger.valueOf(1);
}
else {
result= newFib(n-1).add(newFib(n-2));
memo.add(n,result);
return result;
}
}
}
Your current code does not handle out of bounds correctly and as I mentioned in the comments, the fibonacci sequence does not necessarily start at one and the logic can be simplified. I would use a HashMap<Integer, BigInteger> for storing the memoization and I would also prefer to populate the initial constants once (and as constants). For example,
private static Map<Integer, BigInteger> memo = new HashMap<>();
static {
memo.put(0, BigInteger.ZERO);
memo.put(1, BigInteger.ONE);
}
static BigInteger newFib(int n) {
if (!memo.containsKey(n)) {
if (n < 0) {
memo.put(n, newFib(n + 2).subtract(newFib(n + 1)));
} else {
memo.put(n, newFib(n - 2).add(newFib(n - 1)));
}
}
return memo.get(n);
}
Which can then be tested like
public static void main(String[] args) {
for (int i = -8; i < 9; i++) {
if (i != -8) {
System.out.print(" ");
}
System.out.printf("%-5s", String.format("F(%d)", i));
}
System.out.println();
for (int i = -8; i < 9; i++) {
if (i != -8) {
System.out.print(" ");
}
System.out.printf("%-5s", newFib(i));
}
}
To reproduce the example given in the Fibonacci number Wikipedia entry.
F(-8) F(-7) F(-6) F(-5) F(-4) F(-3) F(-2) F(-1) F(0) F(1) F(2) F(3) F(4) F(5) F(6) F(7) F(8)
-21 13 -8 5 -3 2 -1 1 0 1 1 2 3 5 8 13 21

CombSort implementation in java

I am using Comb Sort to sort out a given array of Strings. The code is :-
public static int combSort(String[] input_array) {
int gap = input_array.length;
double shrink = 1.3;
int numbOfComparisons = 0;
boolean swapped=true;
//while(!swapped && gap>1){
System.out.println();
while(!(swapped && gap==1)){
gap = (int)(gap/shrink);
if(gap<1){
gap=1;
}
int i = 0;
swapped = false;
String temp = "";
while((i+gap) < input_array.length){
numbOfComparisons++;
if(Compare(input_array[i], input_array[i+gap]) == 1){
temp = input_array[i];
input_array[i] = input_array[i+gap];
input_array[i+gap] = temp;
swapped = true;
System.out.println("gap: " + gap + " i: " + i);
ArrayUtilities.printArray(input_array);
}
i++;
}
}
ArrayUtilities.printArray(input_array);
return numbOfComparisons;
}
The problem is that while it sorts many arrays , it gets stuck in an infinite loop for some arrays, particularly small arrays. Compare(input_array[i], input_array[i+gap]) is a small method that returns 1 if s1>s2, returns -1 if s1
try this version. The string array is changed to integer array (I guess you can change it back to string version). The constant 1.3 is replaced with 1.247330950103979.
public class CombSort
{
private static final int PROBLEM_SIZE = 5;
static int[] in = new int[PROBLEM_SIZE];
public static void printArr()
{
for(int i=0;i<in.length;i++)
{
System.out.print(in[i] + "\t");
}
System.out.println();
}
public static void combSort()
{
int swap, i, gap=PROBLEM_SIZE;
boolean swapped = false;
printArr();
while ((gap > 1) || swapped)
{
if (gap > 1)
{
gap = (int)( gap / 1.247330950103979);
}
swapped = false;
for (i = 0; gap + i < PROBLEM_SIZE; ++i)
{
if (in[i] - in[i + gap] > 0)
{
swap = in[i];
in[i] = in[i + gap];
in[i + gap] = swap;
swapped = true;
}
}
}
printArr();
}
public static void main(String[] args)
{
for(int i=0;i<in.length;i++)
{
in[i] = (int) (Math.random()*PROBLEM_SIZE);
}
combSort();
}
}
Please find below implementation for comb sort in java.
public static void combSort(int[] elements) {
float shrinkFactor = 1.3f;
int postion = (int) (elements.length/shrinkFactor);
do {
int cursor = postion;
for(int i=0;cursor<elements.length;i++,cursor++) {
if(elements[i]>elements[cursor]) {
int temp = elements[cursor];
elements[cursor] = elements[i];
elements[i] = temp;
}
}
postion = (int) (postion/shrinkFactor);
}while(postion>=1);
}
Please review and let me know your's feedback.

Can anyone tell me how to improve the run time of this code?

I have written a program to solve Diophantine equations in the form
A5 + B5 + C5 + D5 + E5 = 0;
It should run in N3long(N) time, but it usually takes about 10 minutes for an input size of 100. Can anyone tell me whats wrong?
public class EquationSolver {
//Solves Equations of type: A^5 + B^5 + C^5 + D^5 + E^5 = F^5
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a max value: ");
int N = input.nextInt();
long START_TIME = System.nanoTime();
SLinkedList test = new SLinkedList();
SLinkedList test2 = new SLinkedList();
test = setupLeftList(N);
test2 = setupRightList(N);
System.out.println("Note: This program takes about 7 minutes to complete for input of 100");
test = mergeSort(test);
test2 = mergeSort(test2);
long END_TIME2 = System.nanoTime() - START_TIME;
System.out.println("Total Time:" + END_TIME2/1000000000.0);
checkEquality(test, test2);
long END_TIME3 = System.nanoTime() - START_TIME;
System.out.println("Total Time:" + END_TIME3/1000000000.0);
}
public static SLinkedList setupLeftList(long boundary)
{
//Creates and returns an linkedList of all possible A,B,C values and their sums
SLinkedList leftSums = new SLinkedList();
for(long c = 0; c < boundary; c++)
{
for(long b = 0; b < c; b++)
{
for(long a = 0; a < b; a++)
{
long sum = (long)(Math.pow(a+1,5)) + (long)(Math.pow(b+1, 5)) + (int)(Math.pow(c+1, 5));
Node current = new Node (sum, a+1, b+1, c+1, null);
//System.out.println(sum);
leftSums.addLast(current);
}
}
}
return leftSums;
}
public static SLinkedList setupRightList(long boundary)
{
//Creates and returns an linkedList of all possible D,E,F values and their sums
SLinkedList rightSums = new SLinkedList();
for(int f = 0; f < boundary; f++)
{
for(int e = 0; e < f; e++)
{
for(int d = 0; d < e; d++)
{
long sum = (long)(Math.pow(f+1, 5)) - ((long)(Math.pow(d+1, 5)) + (long)(Math.pow(e+1,5)));
Node current = new Node (sum, d+1, e+1, f+1, null);
//System.out.println(current.getSum());
rightSums.addLast(current);
}
}
}
return rightSums;
}
public static SLinkedList mergeSort(SLinkedList sums)
// Sorts each list by the value of the sum
{
if (sums.length() > 1 )
{
SLinkedList[] splitList = split(sums);
SLinkedList s1 = mergeSort(splitList[0]);
SLinkedList s2 = mergeSort(splitList[1]);
sums = merge(s1, s2);
}
return sums;
}
public static SLinkedList[] split(SLinkedList sums)
{
// Splits a linked list into two (somewhat) equal halves
long midpoint = sums.length()/2;
Node midPoint = sums.elementAt(midpoint);
SLinkedList s1 = new SLinkedList(sums.head, midPoint, midpoint);
SLinkedList s2 = new SLinkedList(midPoint, sums.tail, midpoint);
SLinkedList[] both = new SLinkedList[]{s1, s2};
return both;
}
public static SLinkedList merge(SLinkedList s1, SLinkedList s2)
{
// Merges two sorted lists of elements
SLinkedList sMerged = new SLinkedList();
while(!s1.isEmpty() && !s2.isEmpty())
{
if (s1.getFirst().getSum() < s2.getFirst().getSum())
{
sMerged.addLast(s1.removeFirst());
}
else
{
sMerged.addLast(s2.removeFirst());
}
}
while(!s1.isEmpty())
{
sMerged.addLast(s1.removeFirst());
}
while(!s2.isEmpty())
{
sMerged.addLast(s2.removeFirst());
}
return sMerged;
}
public static void checkEquality(SLinkedList left, SLinkedList right)
{
// Checks two linked lists for nodes that contain the same Sum value
boolean ans = false;
while (left.isEmpty() == false && right.isEmpty() == false)
{
long currentLeft = left.getFirst().getSum();
long currentRight = right.getFirst().getSum();
if (currentLeft > currentRight)
{
right.removeFirst();
}
else if(currentLeft < currentRight)
{
left.removeFirst();
}
else
{
if (left.getFirst().getC() <= right.getFirst().getA())
{
System.out.println("Answer Found: " + "A: " + left.getFirst().getA() + " B: " + left.getFirst().getB() + " C: "
+ left.getFirst().getC() + " D: " + right.getFirst().getA() + " E: " + right.getFirst().getB() + " F: " + right.getFirst().getC());
ans = true;
}
Node temp = left.getFirst().getNext();
while (temp.getSum() == currentRight)
{
if (temp.getC() <= right.getFirst().getA())
{
System.out.println("Answer Found: " + "A: " + left.getFirst().getA() + " B: " + left.getFirst().getB() + " C: "
+ left.getFirst().getC() + " D: " + right.getFirst().getA() + " E: " + right.getFirst().getB() + " F: " + right.getFirst().getC());
ans = true;
}
temp = temp.getNext();
}
right.removeFirst();
left.removeFirst();
}
}
if (ans == false)
{
System.out.println("No answer found.");
}
}
}
The definitive answer is: use a profiler and see what causes a bottleneck...
But I see you have Math.pow() calls, all with longs, and their 5th power.
You could do it quicker, while even detecting the overflow:
public static long pow5(long base) {
if(base <=6208 && base >=-6208) {
return base*base*base*base*base;
} else {
throw new IllegalArgumentException("Overflow!");
}
}
(Magic number disclaimer: 62085 is ~263, is a number is bigger than that, the 5th power won't fit into 64 bits...)
Math.pow uses doubles, which means a lot of conversion in itself...
Also, #Floris pointed out that it is not even worth computing this over and over again - it could be put into a nice array, and just index that
public static long[] pow5 = getPow5(100);
public static long[] getPow5(long numElements) {
long[] toReturn = new long[numElements];
for(long i=0;long<numElements;long++) {
toReturn[i] = i*i*i*i*i;
}
return toReturn;
}
And where needed, instead of Math.pow(x, 5) just use pow5[x]

Android - Simplifying Radicals

I am trying to make a calculator that performs the quadratic formula.
Currently if my result would be a decimal it returns NaN. (EDIT: Resolved)
Preferably I would like the result to be in an simplified radical form (i.e. √(99) = 3√(11) ).
How would I go about achieving this?
This is what I have so far.
// Do the math
private double mathCalcPlus(double varA,double varB,double varC) {
return ((-varB + Math.sqrt(varB * varB - 4 * varA * varC)) / 2 * varA);
}
private double mathCalcMinus(double varA,double varB,double varC) {
return ((-varB - Math.sqrt(varB * varB - 4 * varA * varC)) / 2 * varA);
}
Any help will be greatly appreciated.
This works great! However, I decided to add the top bar of the radical sign just for fun :D
import java.util.Scanner;
public class Radical {
public static void main(String[] args) {
System.out.print("Enter the unsimplified radical: ");
Scanner scan = new Scanner(System.in);
int input = scan.nextInt();
recurse(input);
}
public static void recurse(int x) {
System.out.println(" ______");
System.out.println("Attempting to simplify -/" + x);
int a = 0;
int b = 0;
int count = 0;
for (int i = 1; i < x; i++) {
if ((i * (x/i)) == x) {
//System.out.println(i + "<i rest>" + (x/i));
a = i;
b = x/i;
if (Math.sqrt(a)%1==0) {
if (a != 1) {
System.out.println(" ______");
System.out.println(" " + (int)Math.sqrt(a) + "-/" + b);
count = 1;
}
}
}
}
if (count>0) {
recurse(b);
} else if (count==0) {
System.out.println(" ______");
System.out.println("Cannot simplify -/" + x);
}
}
}
Here's something that might help as far as simplifying radicals go. Give it the unsimplified radical (let's say 850) and it should return the correct answer (5-/34). It also tries to recursively simplify what's left in the radical in case it needs to be broken down again.
This was written quickly so I'm sure there are edge cases I missed that will throw off the calculations but I hope it helps at least a little. Best of luck!
import java.util.Scanner;
public class Radical {
public static void main(String[] args) {
System.out.print("Enter the unsimplified radical: ");
Scanner scan = new Scanner(System.in);
int input = scan.nextInt();
recurse(input);
}
public static void recurse(int x) {
System.out.println("Attempting to simplify -/" + x);
int a = 0;
int b = 0;
int count = 0;
for (int i = 1; i < x; i++) {
if ((i * (x/i)) == x) {
//System.out.println(i + "<i rest>" + (x/i));
a = i;
b = x/i;
if (Math.sqrt(a)%1==0) {
if (a != 1) {
System.out.println((int)Math.sqrt(a) + "-/" + b);
count = 1;
}
}
}
}
if (count>0) {
recurse(b);
} else if (count==0) {
System.out.println("Cannot simplify -/" + x);
}
}
}

Categories