Find prime factors including their total occurrence (Java) - java

I was trying to build a Java program for finding the LCM of 'N' numbers. but first of all i am stuck at finding the total prime factors of a number including their occurrences. For example (6=2x3) and (8=2x2x2). but the output i get is '2' for (6) and only two '2's for (8). Where are the other? I am even checking the integer 's' to be prime.
package lcm;
import java.util.ArrayList;
import java.util.Scanner;
public class LCM {
public static boolean isPrime(int numero){
for (int i = 2; i <= Math.sqrt(numero); i++) {
if (numero % i == 0) {
return false;
}
}
return true;
}
public static void factor(int x){
int s;
int copy = x;
ArrayList<Integer> al = new ArrayList<>();
for(s=2;s<copy;s++){
if(copy%s==0){
if (isPrime(s)){
al.add(s);
copy/=s;
//used for repetition
s--;
}
}
}
for( int p : al){
System.out.println(p);
}
}
public static void main(String[] args) {
// TODO code application logic here
int j,k;
int temp=0;
System.out.println("Enter no. of numbers");
Scanner cin = new Scanner(System.in);
int i = cin.nextInt();
int []a = new int[i];
int []b=new int[100];
System.out.println("Enter numbers one by one");
for(j=0;j<a.length;j++){
a[j] = cin.nextInt();
}
for(j=0;j<a.length;j++){
temp=a[j];
factor(temp);
}
}
}

The reason is when s=2 and copy also becomes 2 in a case at that time it skips the loop so only two 2's are shown. Try putting <=copy in that place

I think one of the best way to approach this problem is to use recursion since you continuously have to divide in order to find all the prime factors.
package leastcommonmultiple;
import java.util.ArrayList;
import java.util.Scanner;
public class Runner {
private static LeastCommonMultiple lcm;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Enter numbers and separate them with a comma: ");
Scanner cin = new Scanner(System.in);
String[] inputs;
String lineInput;
try {
lineInput = cin.nextLine();
while (lineInput.isEmpty()) {
System.out.println("Enter at least 2 numbers separated by a comma ");
lineInput = cin.nextLine();
}
inputs = lineInput.split(",");
int length = inputs.length;
int[] numbers = new int[length];
int temp = 0;
for (int i = 0; i < length; i++) {
if (inputs[i] != null && !inputs[i].isEmpty()) {
if ((temp = Math.abs(Integer.valueOf(inputs[i].trim()))) == 0) {
throw new IllegalArgumentException("No number should be 0");
}
numbers[i] = temp;
}
}
ArrayList<Integer> list = new ArrayList<>();
lcm = new LeastCommonMultiple();
System.out.println("The Least Common Multiple is: " + lcm.getLeastCommonMultipleOfListOfNumbers(numbers));
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
package leastcommonmultiple;
import java.util.ArrayList;
public class LeastCommonMultiple {
public LeastCommonMultiple() {
}
/**
* #param numbers array of numbers whose LCM should be found.
* #assure numbers.length > 1
* #return LCM of numbers contained in numbers array
*/
public int getLeastCommonMultipleOfListOfNumbers(int[] numbers) throws IllegalArgumentException {
int leastCommonMultiple;
int length = numbers.length;
if ( length <= 1) {
throw new IllegalArgumentException("Please enter at least 2 numbers separated by a comma.");
} else {
leastCommonMultiple = getLeastCommonMultipleOfTwoNumbers(numbers[0], numbers[length-1]);
length = length-1;
for ( int i=1; i<length; i++ ) {
leastCommonMultiple = getLeastCommonMultipleOfTwoNumbers(leastCommonMultiple, numbers[i]);
}
}
return leastCommonMultiple;
}
private int getLeastCommonMultipleOfTwoNumbers(int number1, int number2) {
int leastCommonMultiple = 0;
int maxOfTheTwoNumbers = Math.max(number1, number2);
int minOfTheTwoNumbers = Math.min(number1, number2);
int quotient = 0;
if (number1 % number2 == 0 || number2 % number1 == 0) {
leastCommonMultiple = maxOfTheTwoNumbers;
} else {
ArrayList<Integer> primeFactors = getPrimeFactors(minOfTheTwoNumbers, new ArrayList<>());
for (int primeFactor : primeFactors) {
if (maxOfTheTwoNumbers % primeFactor == 0) {
maxOfTheTwoNumbers = (maxOfTheTwoNumbers / primeFactor);
}
leastCommonMultiple = minOfTheTwoNumbers * maxOfTheTwoNumbers;
}
}
return leastCommonMultiple;
}
// recursive methods that finds all the prime factors for a given number
/**
* #param numero positive number whose prime factors has to be found
* #param primeFactors an empty ArrayList where the prime factors will be
* stored
* #return the ArrayList containing the found prime factors
*/
private static ArrayList<Integer> getPrimeFactors(int numero, ArrayList<Integer> primeFactors) {
int sqrt = (int) Math.sqrt(numero);
int quotient;
if (isPrime(numero)) {
primeFactors.add(numero);
} else {
if (numero % sqrt == 0) {
quotient = numero / sqrt;
if (isPrime(sqrt)) {
primeFactors.add(sqrt);
} else {
primeFactors = getPrimeFactors(sqrt, primeFactors);
}
} else {
quotient = numero / (sqrt - 1);
if (isPrime(sqrt - 1)) {
primeFactors.add(sqrt - 1);
} else {
primeFactors = getPrimeFactors((sqrt - 1), primeFactors);
}
}
if (!isPrime(quotient)) {
primeFactors = getPrimeFactors(quotient, primeFactors);
} else {
primeFactors.add(quotient);
}
}
return primeFactors;
}
// Make sure a number is prime
public static boolean isPrime(int numero) {
int length = (int) Math.sqrt(numero);
for (int i = 2; i <= length; i++) {
if (numero % i == 0) {
return false;
}
}
return true;
}
}

Here's a solution which is faster by using binary splitting on the Euclidean algorithm:
private static int gcd(int a, int b) {
if (a == 0) return b;
if (b == 0) return a;
return gcd(b, a%b);
}
private static int lcm(int a, int b) {
return a / gcd(a, b) * b;
}
public static int LCM(int[] numbers) {
int len = numbers.length;
if (len == 2) return lcm(numbers[0], numbers[1]);
if (len == 1) return numbers[0];
if (len == 0) return 1;
int[] left = Arrays.copyOfRange(numbers, 0, len/2);
int[] right = Arrays.copyOfRange(numbers, len/2+1, len);
return lcm(LCM(left), LCM(right));
}

Related

Give amount of happy numbers in a given (input) range

As an exercise I need to make a code that will give the amount of happy numbers* in a given range. As a test I need to insert the code in a program that checks 10 different outcomes, for every good outcome you get 4 points. I want the full 40 points and my teacher said that I need to change only a little bit in my code. So far I have this:
*A happy number is a number which eventually reaches 1 when replaced by the sum of the square of each digit. For instance, 13 is a happy number because 1^2 + 3^2 = 10 and 1^2 + 0^2 = 1
Important to know: When you end up with a 4, it is definitely not a happy number.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String st1 = scan.nextLine().trim();
String st2 = scan.nextLine().trim();
int min = Integer.parseInt(st1);
int max = Integer.parseInt(st2);
Set<Integer> happyNumbers = getHappyNumbers(min, max);
System.out.println(happyNumbers.size());
}
public static Set<Integer> getHappyNumbers(int min, int max) {
Set<Integer> out = new HashSet<>();
for (int i = min; i < max; i++) {
if (isHappy(i)) {
out.add(i);
}
}
return out;
}
private static boolean isHappy(int i) {
int sum = 0;
while (i != 0) {
sum += Math.pow((i % 10), 2);
i /= 10;
}
if (sum == 4) return false;
else if(sum == 1) return true;
else if (sum !=1) {return isHappy(sum);}
else return true;
}
}
My teacher also said the mistake is in the following part:
if (sum == 4) return false;
else if(sum == 1) return true;
else if (sum !=1) {return isHappy(sum);}
else return true;
Please help :)
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class HappyNumbersMain {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Lower limit (>0): ");
String st1 = scan.nextLine().trim();
System.out.print("Upper limit: ");
String st2 = scan.nextLine().trim();
int min = Integer.parseInt(st1);
int max = Integer.parseInt(st2);
Set<Integer> happyNumbers = getHappyNumbers(min, max);
System.out.println("Happy numbers between " + min + " and " + max + ":" + happyNumbers);
}
public static Set<Integer> getHappyNumbers(int min, int max) {
Set<Integer> out = new TreeSet<>();
for (int i = min; i <= max; i++) {
if (isHappy(i)) {
out.add(i);
}
}
return out;
}
private static boolean isHappy(int i) {
// Stopping conditions
if (i == 4) {
return false;
} else if (i == 1) {
return true;
}
int sum = 0;
while (i > 0) {
sum += Math.pow((i % 10), 2);
i /= 10;
}
return isHappy(sum);
}
}
Above works as expected, some notes:
When doing recursive functions, put stopping conditions as the first thing it checks
Adding some feedback to the user helps in understanding how to use your program
TreeSet will sort values, HashSet does not, better for display purposes
You should always verify user input (I did not do that, but you should)
if (sum == 4)
return false;
else
if(sum == 1)
return true;
else
return isHappy(sum);
Alternative:
switch ( sum ): {
case 4: return false; break;
case 1: return true; break;
default: return isHappy(sum); break;
}
The break isn't needed, since the return in all control paths.

Binary search algorithm isn't returning variable

I'm very new to binary search and I attempted a code that would read values from a document and then the user can input a number to search for from the document, and through binary search, the number would be found. I'm having trouble now because the "low" variable that I initialize in the binary search section of my code is not being returned to my main code and there's an error that says "low can not be resolved to a variable".
Here is the code for my binary search:
static public int search (int[]numbers,int target, int count)
{
int high = numbers.length;
int low = -1;
int middle = (high+low)/2;
while(high-low>1)
{
count++;
middle = (high+low)/2;
if(numbers[middle]>target)
{
high = middle;
}
else if(numbers[middle]<target)
{
low = middle;
}
else
{
break;
}
System.out.println(numbers[middle]);
System.out.println(middle);
}
if(low == -1 || numbers[low]!=target)
{
low=-1;
return low;
}
else
{
return low;
}
}
And here is the code from my main code. The part with the if statements is where the error is showing up:
public static void main(String[] args) throws IOException {
DataInputStream input = new DataInputStream(System.in);
int [] numbers = new int [50000];
int target;
int count=0;
try
{
BufferedReader br = new BufferedReader(new FileReader("randNums.txt"));
for(int i=0;i<50000;i++)
{
numbers[i]=Integer.parseInt(br.readLine());
}
br.close();
Arrays.sort(numbers);
System.out.print("Choose a number between 1-100000000 to search for: ");
target = Integer.parseInt(input.readLine());
search(numbers, target,count);
if(low==-1)
{
System.out.println("The number was not on the list.");
}
else
{
System.out.println("The number is at position " + low);
System.out.println("It took " + count + " comparisons to find the number.");
}
}
You have to initialize low in main:
int low=search(numbers, target,count);
I have Already resolved this algorithm.
Try my code :
public static int guessNumber(int number) {
int first = 0;
int last = 1_000_000;
if (verify(first) == 0) {
count++;
return first;
}
if (verify(last) == 0) {
count++;
return last;
}
while (last > first && count <= 50) {
count += 1;
// get the middle of the range
int middle = (first + last) / 2;
if (verify(middle) == 0) {
return middle;
}
if (verify(middle) == 1) {
first = middle + 1;
if (verify(first) == 0) {
return first;
}
}else {
last = middle - 1;
if (verify(last) == 0)
return last;
}
}
return 0;
}
//Function verify(integer) => integer
public static int verify(int guess){
if (numberTobeGuessed > guess ) {
return 1;
}else if (numberTobeGuessed < guess) {
return -1;
}
return 0;
}
I recently found a solution for lazy peoples like me use below code
int position = Arrays.binarySearch(numbers , target);
here no need to sort, and array variable number integer variable target.

How to reverse 1000 so that the output will be 1 (not 0001) using recursion or else normal in JAVA

As I have already made the code just I have to add the required condition(1000 == 1 ! 0001). Can anybody help me out.
public class ReverseNum {
static void reverseInteger(int n) {
// Write your code here
if (n <= 0) {
System.out.print("-");
reverseInteger(n * -1);
} else if (n < 10) {
System.out.println(n);
}
else {
System.out.print(n % 10);
reverseInteger(n / 10);
}
}
public static void main (String args[]){
Scanner s = new Scanner(System.in);
int num = s.nextInt();
reverseInteger(num);
}
}
Be careful with negative numbers: they need special consideration (and also will break string reversal and parsing).
A solution that works with any int:
public static int reverse(int value) {
if (value < 0) {
// special handling for negative numbers
return 0 - reverse(-value);
}
int reversed = 0;
while (value > 0) {
reversed = reversed * 10 + (value % 10);
value /= 10;
}
return reversed;
}
Test cases:
assertEquals(0, reverse(0));
assertEquals(321, reverse(123));
assertEquals(98765, reverse(567890000));
assertEquals(-91, reverse(-19));
assertEquals(-2, reverse(-20000));
Try this code :
private static int reverseInteger(int n) {
if (n == 0) {
return n;
}
int symbol = n / Math.abs(n);
n = Math.abs(n);
String str = new StringBuilder(String.valueOf(n)).reverse().toString();
return symbol * Integer.parseInt(str);
}
Test cases:
#Test
public void test_reverseInteger() {
assertEquals(0, reverseInteger(0));
assertEquals(321, reverseInteger(123));
assertEquals(98765, reverseInteger(567890000));
assertEquals(-91, reverseInteger(-19));
assertEquals(-2, reverseInteger(-20000));
}

Multiply objects in an array witrh another object recursively in Java

Hello there I am learning Java and after doing some tasks to learn recursion I was giving my self some exercises to learn it a bit more but now I am struggeling with some..
So the main Problem is that I dont know how I can multiply every element in an Array recursively when the elements in that array are object (Maybe there is at the end no difference if objects are in there or not). So the exercise I gave myself was: check if 1 / 3 is in the given Array. If Yes then multiply everything in that array with 2 / 1.
This is Fraction:
private int numerator; // Zaehler
private int denominator; // Nenner
public Fraction ( int num, int denom )
{
if ( denom != 0 )
{
if ( denom < 0 )
{
numerator = -num;
denominator = -denom;
}
else
{
numerator = num;
denominator = denom;
}
reduce();
}
else
{
// error: division by zero
throw new IllegalArgumentException();
}
}
public Fraction()
{
numerator = 0;
denominator = 1;
}
public Fraction( int num )
{
numerator = num;
denominator = 1;
}
So I got it done by doing it with an for loop:
public static Fraction[] mulWithFor(Fraction[] arr)
{
for (int i = 0; i<arr.length; i++)
{
arr[i] = arr[i].multiply(new Fraction(2,1));
}
return arr;
}
But thats not my Main goal I want to do it recursively so that was my approach:
public static Fraction[] mulAus(Fraction[] arr, int i)
{
if (i>= 0 && i<arr.length)
{
rekurMul(arr,i);
//return mulAus(rekurMul(arr,i-1));
}
return arr;
}
public static Fraction rekurMul(Fraction[] arr, int i)
{
if (i>= 0 && i<arr.length)
{
return arr[i].multiply(new Fraction(2,1));
return arr[i].multiply(new Fraction(2, 1)); // Does Not Work!!!
}
throw new IndexOutOfBoundsException();
}
Maybe there is someone who can Help me! Thank you for your attention.
OK Thanks to #Chaï Sarfati and also to the others trying to help me out. I now know how to multiply recursive things in an Array! I used the Methods from #Chaï Sarfati but wrote an alternative method for his "oneThirdIsPresent" which is also a recursive method : So now my working code looks like this
public static Fraction[] mulAus(Fraction[] arr)
{
if(contains(arr,arr.length-1,new Fraction(1,3)))
{
rekurMul(arr,0);
return arr;
}
throw new IllegalArgumentException("1/3 does not exist in the Input-Array");
}
public static void rekurMul(Fraction[] arr, int i)
{
if(i == arr.length)
{
return ;
}
arr[i] = arr[i].multiply(new Fraction(2,1));
rekurMul(arr,i+1);
}
The Method to check if 1 / 3 exists in the given Array.
public static boolean contains(Fraction[] arr, int i, Fraction x)
{
if (i>= 0 && i < arr.length)
{
if (arr[i].equals(x))
{ return true;}
else
{ return contains(arr, i-1,x); }
}
return false;
}
I hope other People can learn from the code.. Maybe there are better solutions but I am just starting Programming so I dont know them for now.
Bye
Assuming you have a multiplyBy(Fraction f) method that works properly in you Fraction class.
Moreover, it will be better (more readable, more time & space complexity saving) to do it iteratively.
For the sake of the example, I would do like this:
First define:
private static boolean oneThirdIsPresent(Fraction[] arr){
for (int i = 0; i < arr.length; i++) {
if(arr[i].numerator == 1 && arr[i].denominator == 3) {
return true;
}
}
return false;
}
private static void recursivelyMultBy2(Fraction[] arr, int index){
if(index == arr.length){
return;
}
arr[index] = arr[index].multiplyBy(new Fraction(2));
recursivelyMultBy2(arr, index+1);
}
In order to solve finally:
public static void multBy2IfOneThirdIsPresent(Fraction[] arr){
if(oneThirdIsPresent(arr)){
recursivelyMultBy2(arr, 0);
}else{
return;
}
}
Here's a quick example of just the recursive multiplication part:
public static void main(String[] args)
{
Fraction[] fractions = new Fraction[] {new Fraction(1,2), new Fraction(2,3), new Fraction(3,1)};
System.out.println("Fractions:");
for(Fraction f: fractions)
{
System.out.println(f);
}
System.out.println("Multiplying array by 2...");
Fraction.mulAus(fractions, new Fraction(2, 1));
for(Fraction f: fractions)
{
System.out.println(f);
}
}
Modified Fraction Class (multiplication code at the bottom):
public class Fraction
{
private int numerator; // Zaehler
private int denominator; // Nenner
public Fraction(int num, int denom)
{
if (denom != 0)
{
if (denom < 0)
{
numerator = -num;
denominator = -denom;
}
else
{
numerator = num;
denominator = denom;
}
reduce();
}
else
{
// error: division by zero
//throw new IllegalArgumentException();
}
}
private void reduce()
{
// ...
}
public Fraction()
{
numerator = 0;
denominator = 1;
}
public Fraction(int num)
{
numerator = num;
denominator = 1;
}
public String toString()
{
return numerator + " / " + denominator;
}
public void MultiplyBy(Fraction F)
{
if (F != null)
{
numerator = numerator * F.numerator;
denominator = denominator * F.denominator;
reduce();
}
}
public static void mulAus(Fraction[] arr, Fraction F)
{
if(arr != null && F != null)
{
rekurMul(arr, 0, F);
}
}
private static void rekurMul(Fraction[] arr, int i, Fraction F)
{
arr[i].MultiplyBy(F);
if (i < (arr.length - 1))
{
rekurMul(arr, ++i, F);
}
}
}
Output:

Recursive method to add odd numbers

I have the below snippet of code to use a recursive method to add the sum of odd numbers.
I have already coded the iterative method successfully that adds the sum of all odd numbers between n and m which are entered by the user. I'd like to reach that goal but am started slow to make sure I understand what is happening.
I know that it makes more sense to do it iteratively, however I am experimenting with the two types to see which is more efficient. I am stuck on the below as it is not doing what i want it to and i can't understand why.
import java.util.*;
public class SumofOdd
{
public static void main (String [] args)
{
int n = 0;
Scanner sc = new Scanner(System.in);
System.out.println("Please enter an odd number");
n = sc.nextInt();
int x = add(n);
}
public static int add(int x)
{
if (x == 0)
{
return 0;
}
else
{
return (x + add(x-1));
}
}
}
I have changed the above to the below. It compiles however stops after I enter the number.
import java.util.*;
public class SumofOdd
{
public static void main (String [] args)
{
int n = 0;
Scanner sc = new Scanner(System.in);
System.out.println("Please enter an odd number");
n = sc.nextInt();
if (n%2 == 0)
{
System.out.println("The number entered is even");
}
else
{
int x = add(n);
}
}
public static int add(int x)
{
if (x <= 0)
{
return 0;
}
else
{
return (x + add(x-2));
}
}
}
import java.util.*;
public class OddR{
public static void main (String Args [])
{
Scanner s = new Scanner(System.in);
System.out.println("Enter an odd number");
int max = s.nextInt();
if((max% 2) == 0) {
System.out.println(max + " is Even number and therefore is invalid");
}
else{
System.out.println("Enter a greater odd number");
int m = s.nextInt();
if (m <max){
System.out.println("Invalid data");
}
else{
if((m % 2) == 0) {
System.out.println(m + " is Even number and therefore is invalid");
}
else{
int data = (addodd(m)- addodd(max))+max;
System.out.print("sum:"+data);
}
}
}
}
public static int addodd(int m)
{
if(m<=0)
{
return 0;
}
if(m%2 != 0)
{
return (m+addodd(m-1));
}
else
{
return addodd(m-1);
}
}
}
This is the answer recursively of the sum of odd numbers from n to m
public int addOdds(int n) {
if (n <= 0) {
return 0;
}
if (n % 2 == 0) {
return addOdds(n - 1);
}
return x + addOdds(n - 1);
}
Take care, I never tested the code.
class Oddsum {
public int addodd(int n)
{
if(n<=0)
{
return 0;
}
if(n%2 != 0)
{
return (n+addodd(n-1));
}
else
{
return addodd(n-1);
}
}
}
public class Xyz {
public static void main (String[] v)
{
int n = 9;
Oddsum o = new Oddsum();
int data = o.addodd(n);
System.out.print("sum:"+data);
}
}
This is working fine
public static void main (String[] args){
public static int oddSum(int s){
if (s <= 0)
return 0;
else
return s + oddSum(s -2);
}
}

Categories

Resources