Excluding specific integer from java method return - java

I'm just starting java, and have written a simple program for returning factors of input numbers. There are two classes, a tester and a the one you see below.
Unfortunately, my output, say if I input 150, is 2, 3, 0, 5, 5.
I know why this is happening; when the local variable q = i, we obviously get 2, 3, 5, 5, but when the conditional in the first if statement is not met, q is read as 0.
Is there a way to exclude a specific integer, in this case 0, from the output? I've struggled with what should be an easy problem for hours, so obviously I'm not seeing something.
I realize there are easier ways to write this program, but all methods must remain as is...
public class FactorGenerator {
private int y;
private int i;
public FactorGenerator(int numberToFactor)
{
y = numberToFactor;
i = 2;
}
public boolean hasMoreFactors()
{
if (i <= y)
{
return true;
}
else
{
return false;
}
}
public int nextFactor()
{
int q=0;
if( y % i != 0)
i++;
if( y % i == 0)
{
y = y / i;
q = i;
}
return q;
}
}

Quick fix. You need a while loop (to skip all factors that does not clearly divide your y) in here:
if( y % i != 0)
i++;
Like this:
while( y % i != 0){
i++;
}

#MicD has suggested correct answer
Another way:
As you have problem with zero, so just check q is not equal to zero
int nextFactor()
{
int q=0;
if( y % i != 0)
i++;
if( y % i == 0)
{
y = y / i;
q = i;
}
if(q!=0)
return q;
else
nextFactor();
}

Related

Finite Coins - using recursion

Given 1 coin from multiple denominations (E.G. a 1 coin, 5 coin, 16 coin), and a sum, return true or false determining if the sum can be made.
boolean go(int[] coins, int goal)
{
//Will set each time, but shouldn't matter as toggle is at bottom
boolean ans = false;
//loop running in recursion till founds ans
//Really bad time complexity lol
for (int i = 0; i < coins.length && (!ans); i++) {
if ((goal - coins[i] == 0) || goal == 0) {
return true;
}
if (goal > coins[i]) {
int[] red = new int[coins.length - 1];
//it necessary because making list with one less
int it = 0;
//Setting new list to avoid runtime
for(int x = 0; x < coins.length; x++){
if(!(i == x)){
red[it] = coins[i];
it += 1;
}
}
//Run with new list
ans = go(red, goal - coins[i]);
}
}
return ans;
}
This is my code so far. I have made it recursive, yet one of the test cases returns true when it should not. The test case in particular is [111, 1, 2, 3, 9, 11, 20, 30], with the goal doing 8; This should return false (as it cannot add up to 8), but in this case, returns true.
Other test cases work fine, so I believe my code has some sort of an exception.
I have tried to move the base case upward, and make a reverse variation...
boolean go(int[] coins, int goal)
{
boolean ans = false;
if(goal == 0){
return true;
}else if(goal < 0){
return false;
}
for (int i = 0; i < coins.length && (!ans); i++) {
if (goal >= coins[i]) {
int[] red = new int[coins.length - 1];
int it = 0;
for(int x = 0; x < coins.length; x++){
if(!(i == x)){
red[it] = coins[i];
it += 1;
}
}
ans = go(red, goal - coins[i]);
}
}
return ans;
}
is what I've tried, but the base case doesn't seem to affect anything
The bug is in your copying of the coins array: red[it] = coins[i] should really be red[it] = coins[x]...
For time complexity, you don't really have to do a loop inside the method. Each denomination is either part of the sum or not, so you can always remove the first denomination and test with and without it:
boolean go(int[] coins, int goal) {
if(goal == 0)
return true;
else if(coins.length == 0 || goal < 0)
return false;
else {
int[] tailOfCoins = Arrays.copyOfRange(coins, 1, coins.length);
return go(tailOfCoins, goal) || go(tailOfCoins, goal - coins[0]);
}
}

Java program on "friendly numbers "

I am working on a assignment about so called "friendly-numbers" with the following definition: An integer is said to be friendly if the leftmost digit is divisible by 1, the leftmost two digits are divisible by 2, and the leftmost three digits are divisible by 3, and so on. The n-digit itself is divisible by n.
Also it was given we need to call a method (as I did or at least tried to do in the code below). It should print whether a number is friendly or not. However, my program prints "The integer is not friendly." in both cases. From what I have tried, I know the counter does work. I just cannot find what I am missing or doing wrong. Help would be appreciated, and preferably with an adaptation of the code below, since that is what I came up with myself.
import java.util.Scanner;
public class A5E4 {
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Please enter an integer: ");
int friendlyNumber = in.nextInt();
boolean result = isFriendly(friendlyNumber);
if (result)
{
System.out.println("The integer is friendly");
}
else
{
System.out.println("The integer is not friendly");
}
}
public static boolean isFriendly(int number)
{
int counter = 1;
while (number / 10 >= 1)
{
counter ++;
number = number / 10;
}
boolean check = true;
for (int i = 1; i <= counter; i++)
{
if (number / Math.pow(10, (counter - i)) % i == 0 && check)
{
check = true;
}
else
{
check = false;
}
}
return check;
}
}
while (number / 10 >= 1){
counter ++;
number = number / 10;
}
In this bit, you are reducing number to something smaller than 10. That is probably not what you want. You should make a copy of number here.
Also, proper software design would recommend that you extract this to a dedicated method.
private int countDigits(int number){
if(number < 1) throw new IllegalArgumentException();
int n = number;
int counter = 1;
while (n / 10 >= 1){
counter ++;
n = n / 10;
}
return counter;
}
You need to copy the number which you use to find out how much digits your number has. Otherwise you change the number itself and don't know anymore what it was.
The second mistake is that you divide an integer by Math.pow() which returns a double. So your result is double. You want to have an integer to use the modulo operator.
public static boolean isFriendly(int number)
{
int counter = 1;
int tmpNumber = number;
while (tmpNumber / 10 >= 1)
{
counter ++;
tmpNumber = tmpNumber / 10;
}
boolean check = true;
for (int i = 1; i <= counter; i++)
{
if ((int)(number / Math.pow(10, (counter - i))) % i == 0 && check)
{
check = true;
}
else
{
check = false;
}
}
return check;
}
The first problem is that you are modifying the value of the number you are trying to check. So, if your method is called with 149, then after the while loop to count the digits, its value will be 1. So, you are always going to find that it is 'unfriendly'. Assuming you fix this so that number contains the number you are checking. Try this instead of your 'for' loop:
while ( counter && !( ( number % 10 / counter ) % counter ) )
{
number = number / 10;
counter--;
}
It works by taking the last digit of your number using the modulus or remainder operator and then divides this by the digit position and checks that the remainder is zero. If all is good, it decrements the counter until it reaches zero, otherwise it terminates before counter is zero.
Try something like this (change your isFriendly() method):
public static boolean isFriendly(int number)
{
String numberAsString = String.valueOf(number); //Convert the int as a String to make it easier to iterate through
for(int i = 0; i < numberAsString.length(); i++) {
int currentDigit = Character.getNumericValue(numberAsString.charAt(numberAsString.length() - i - 1)); //Iterate over the number backwards
System.out.println(currentDigit); //Print the current digit
if(currentDigit % (i + 1) != 0) {
return false;
}
}
return true;
}
The easy way is to convert to string and then check if it is friendly:
public static boolean isFriendly(int number)
{
String num = Integer.toString(number);
for (int i = 0, dividedBy = 1; i < num.length(); i++, dividedBy++)
{
String numToCheck = "";
for (int j = 0; j <= i; j++)
{
numToCheck += num.charAt(j);
}
if (Integer.valueOf(numToCheck) % dividedBy != 0) {
return false;
}
}
return true;
}

finding the sum of number dividsable by x using recursion

I want to find the sum of numbers that is divisible by x using recursive method
Ex if n= 10, x=3, the code should return sum of 3+6+9
Write a recursive method sumDivByX(n, x), which finds the sum of all
numbers from 0 to n that are divisible by x.
I asked my teacher about it and he told me "Firstly, total should be global. You should return 0 if n or x == 0. I only care if n is divisible by x. So I only add n to total (total+=n) if (n%x==0) otherwise do nothing. And do recursion sumDivByX(n-1,x) and return total as usual." I tried to correct it.
public static int sumDivByX(int n, int x) {
int total = 0;
if (n == 0 || x == 0) {
return -1;
}
if (n % x >= 1) {
return total = 0;
} else if (n % x == 0) {
return total += n;
}
return total + sumDivByX(n - 1, x);
}
When I run the program I get 0.
Eliminate the returns inside your second and third if statements
public static int sumDivByX(int n, int x) {
int total = 0;
if (n == 0 || x == 0) {
return 0;
}
if (n % x >= 1) {
total = 0;
} else if (n % x == 0) {
total += n;
}
return total + sumDivByX(n - 1, x);
}
For a cuter, more compact version
public static int sumDivByX(int n, int x) {
if (n == 0 || x == 0) {
return 0;
}
return (n % x == 0 ? n : 0) + sumDivByX(n - 1, x);
}
Note - depending on the semantics you intend, you might want to have separate checks for x<=0 (possibly and error?) and n==0 (base case).
Step through your code and you'll see that it never recurses when n ==10 and x==3, since (10 % 3 == 1)
When a method gets to a "return" statement it ends, in your case at the second if.
Your total is initialized by 0 everytime the method runs, so you should consider making it global.
Your method generates an exception if you try to use negative numbers as paramethers
Try this:
int total=0;
public static int subDivByX(int n, int X) {
if (n>0 && x>0) {
if (n%x==0){
total += n;
}
return sumDivByX(n-1,x);
}
else return -1;
}
This seems to work
private static int sumDivByX(int n,int x) {
if (n < x || x < 1 ) {
return 0;
}
int d = n/x;
return (x * d) + sumDivByX(n - x , x);
}
Recursion could cause a stackoverflow.

Finding factors of a given integer

I have something like this down:
int f = 120;
for(int ff = 1; ff <= f; ff++){
while (f % ff != 0){
}
Is there anything wrong with my loop to find factors? I'm really confused as to the workings of for and while statements, so chances are they are completely wrong.
After this, how would I go about assigning variables to said factors?
The following code will return a list of all factors of a given number:
public ArrayList<Integer> findFactors(int num) {
ArrayList<Integer> factors = new ArrayList<Integer>();
// Skip two if the number is odd
int incrementer = num % 2 == 0 ? 1 : 2;
for (int i = 1; i <= Math.sqrt(num); i += incrementer) {
// If there is no remainder, then the number is a factor.
if (num % i == 0) {
factors.add(i);
// Skip duplicates
if (i != num / i) {
factors.add(num / i);
}
}
}
// Sort the list of factors
Collections.sort(factors);
return factors;
}
This answer improves Sharad Dargan's answer in two ways:
Based on an idea used in this answer, you can speed up the solution by determining the value to increment by, based on whether the number is even or odd.
Add the following line of code before the for loop:
int incrementer = num % 2 == 0 ? 1 : 2;
Then change the last part of the loop to:
i += incrementer
If the number is odd, it then will skip all even numbers, rather than always incrementing by one no matter what.
Sharad stores the upper limit value in a variable and then uses that variable in the for loop:
int upperlimit = (int)(Math.sqrt(a));
...
for(int i = 1; i <= upperlimit; i+= 1)
Instead, place Math.sqrt(num) directly in the for loop and skip the upper limit variable:
for (int i = 1; i <= Math.sqrt(num); i += incrementer) {
This will allow you to skip the casting part of the code, creating cleaner code.
Some JUnit test cases you can then use:
#Test
public void test12() {
FindFactors find = new FindFactors();
int num = 12;
List<Integer> factors = Arrays.asList(1, 2, 3, 4, 6, 12);
assertEquals(factors, find.findFactors(num));
}
#Test
public void test1000000() {
FindFactors find = new FindFactors();
int num = 1000000;
List<Integer> factors = Arrays.asList(1, 2, 4, 5, 8, 10, 16, 20, 25, 32, 40, 50, 64, 80, 100, 125, 160, 200,
250, 320, 400, 500, 625, 800, 1000, 1250, 1600, 2000, 2500, 3125, 4000, 5000, 6250, 8000, 10000, 12500,
15625, 20000, 25000, 31250, 40000, 50000, 62500, 100000, 125000, 200000, 250000, 500000, 1000000);
assertEquals(factors, find.findFactors(num));
}
#Test
public void test1() {
FindFactors find = new FindFactors();
int num = 1;
List<Integer> factors = Arrays.asList(1);
assertEquals(factors, find.findFactors(num));
}
#Test
public void test0() {
FindFactors find = new FindFactors();
int num = 0;
List<Integer> factors = new ArrayList<Integer>();
assertEquals(factors, find.findFactors(num));
}
Here is how to get all factors of the given number.
public class Factors {
public static void main(String[] args){
int n = 420;
for(int i=2; i<=n; i++){
while(n%i==0){
System.out.println(i + "| " + n);
System.out.println(" -----");
n = n/i;
}
}
}
}
Output:
2| 420
-----
2| 210
-----
3| 105
-----
5| 35
-----
7| 7
-----
public class Solution {
public ArrayList<Integer> allFactors(int a) {
int upperlimit = (int)(Math.sqrt(a));
ArrayList<Integer> factors = new ArrayList<Integer>();
for(int i=1;i <= upperlimit; i+= 1){
if(a%i == 0){
factors.add(i);
if(i != a/i){
factors.add(a/i);
}
}
}
Collections.sort(factors);
return factors;
}
}
The above solution simply works like calculating prime factors.
The difference being for every prime factor we keep calculating the other part of the product i.e the reqd number.
In order to find the factors of a given number, you only need to check upto the square root of the given number.
For example, in order to find the factors of 6, you only need to check till 2.45 (√6). The factors of 6 will be 1 and 2, and their converse numbers, i.e. 3 and 6.
I have made a program that determines the factors of a given number and displays them. Here is the necessary code:
Scanner input = new Scanner(System.in);
System.out.print("Enter integer: ");
long num = input.nextLong();
for(long i = 1; i <= Math.sqrt(num); i++) {
if(num % i == 0) {
System.out.println(i);
if(i != num/i) {
System.out.println(num/i);
}
}
}
You just need this program to find the factors of a given number. However, if you want to take it a step further and display the factors arranged in ascending order, then the necessary code is as follows:
Scanner input = new Scanner(System.in);
System.out.print("Enter integer: ");
long num = input.nextLong();
ArrayList<Long> list1 = new ArrayList<>(), list2 = new ArrayList<>();
long currentTime = System.currentTimeMillis();
for(long i = 1; i <= Math.sqrt(num); i++) {
if(num % i == 0) {
list1.add(i);
if(i != num/i) {
list2.add(num/i);
}
}
}
int n1 = list1.size() - 1;
int n2 = list2.size() - 1;
for(int i = 0; i <= n1; i++) {
System.out.println(list1.get(i));
}
for(int i = n2; i >= 0; i--) {
System.out.println(list2.get(i));
}
What this does: This program stores the factors of the number upto the number's square root in one list (list1), and the converse of these numbers in another list (list2). It then prints the elements of both lists (as shown).
There's nothing wrong with your for loop, but a while loop is the wrong thing to be using here.
The logic of your for loop is:
Set ff to 1.
Keep going while ff <= f.
After you've done everything in the for loop, add 1 to ff.
This looks like it is exactly as you want.
The while loop isn't right, though. It will continue to do whatever code you write there for as long as ff is a factor of f, so unless you change them in the while code, you'll get an infinite loop. However, changing that to an if statement will give you what you want.
Since you're checking for factors, you don't actually need to check all possibilities up to f - only up to the square root of f. Whenever you find that ff is a factor, output both ff and f/ff as factors, unless f is a sqare number.
public static void printFactors(int number) {
if (number < 1 )
System.out.println("Invalid Value");
for (int i = 1 ; i <= number ; ++i) {
if ( number % i == 0)
System.out.println(i);
}
}
}
It looks like you are not going to do something with either f or ff in your while loop? If so, the expression f%ff != 0 is either false (and then it will go to the next in the for loop), or it is true, and it will end up in an infinite loop.
Are you sure you need the while like this?
Slightly modified solution: You can first check if variable x is divisible by variable y. If yes, we will count 1 and will repeat this process. For the loop counter, x/y is used and you should check x>0 to avoid repetition when x becomes zero but loop is not finished yet.
public class Factor {
public static void main(String[] args) {
int x = 48;
int x1 = x;
int y = 2;
int k = x / y;
int j = 0;
for (int i = 1; i < k; i++) {
if ((x % y) == 0 && x > 0)
j++;
x = x / 2;
}
System.out.println(+x1 + " is a factor of " + y + " for " + j
+ " times.");
}
}
I got all the factors just fine with this (I just modified the algorithm in the question).
int num1 = 120;
for(int num2=1;num2<=num1;num2++)
{
if (num1%num2 != 0)
System.out.println(num2);
}
import java.util.Scanner;
public class Factors
{
Scanner scn=new Scanner(System.in);
int num=scn.nextInt();
public void findFactor()
{
System.out.println("Factors are");
System.out.println("1");
for(int i=2;i<=num;i++)
{
if(num%i==0)
{
num=num/i;
System.out.println(i);
i=2;
}
}
}
public static void main(String[] args)
{
while(1==1)
{
System.out.println("Enter a Number");
Factors fct=new Factors();
fct.findFactor();
}
}
}
Utilizing Streams introduced in Java 8, the following will print the factors for a given number.
int input = 1500;
IntStream.rangeClosed(1, input)
.filter(e -> input % e == 0)
.forEach(System.out::println);
This is how you write it yourself like a boss. Needs to add if statements to handle one and two, but besides that; this method is as sexy as it gets
public static void primerize(int n){
boolean reduced = false;
while(n > 2){
if(n%2 == 0){
System.out.println(2 + "," + n/2);
n /= 2;
}
else{
int i = isPrime(n);
if(i == n && reduced == false){
System.out.println(1 + "," + n);
n /= n;
}
else if(i == n){
n/= n;
}
else{
System.out.println(i + "," + n/i);
n = i;
reduced = true;
}
}
}}
public static int isPrime(int n){
for(int i = (n/3); i > 0; i--){
if(i == 1){
return n;
}
else if(n%i == 0){
return i;
}
}
return 0;}
This code will give you the factors.
ArrayList<Integer> arr = new ArrayList<>();
int x=48;
int y=1;
while(x!=1)
{
if(x%y==0)
{
x=x/y;
arr.add(y);
if(y==1)
{
y++;
}
}
else
{
y+=1;
}
}
System.out.println(arr);
Easiest way using recursive function
public static int factorial(int n){
if(n!=1)
return n*factorial(n-1);
return 1;
}

Summing integers recursive with Java

I have to calculate a sum of two integers by using a recursive algorithm, but sincerely i have no idea how to do so. Here are the conditions:
sum(x,y) = ?
if x = 0 then sum (x,y) = y otherwise sum(x,y) = sum(predecessor(x),successor(y)).
Does someone have an idea how i could write this in an algorithm? I would be glad about any advice.
I won't give you the code since this seems to be a homework but here is the rough algorithm:
predecessor(x) = x - 1
successor(x) = x + 1
sum(x, y) =
if x = 0
then y
otherwise sum(predecessor(x), successor(y))
That's the simplest I could immagine
public static void main(String[] args) {
System.out.println("4+5 = " + sum(4, 5));
System.out.println("4+(-5) = " + sum(4, -5));
System.out.println("-4+5 = " + sum(-4, 5));
System.out.println("-4+5 = " + sum(-4, -5));
}
public static int sum(int x, int y) {
if (x < 0) {
x *= -1;
y *= -1;
}
return (x == 0 ? y : sum(--x, ++y));
}
Here is my solution for i&j both >= 0. set sum = 0; and subtract 1 until it is <= 0
public static int sum(int i, int j){
return sum(i,j,0);
}
private static int sum(int i, int j, int sum) {
if (i <= 0 && j <= 0) {
return sum;
} else if (i <= 0) {
return sum(0, j - 1, sum + 1);
} else if (j <= 0) {
return sum(i - 1, 0, sum + 1);
} else {
return sum(i - 1, j - 1, sum + 2);
}
}
public static void main(String[] args) {
System.out.println(sum(60, 7));
}
To handle negative numbers based on #aioobe's answer.
sum(x, y): return x == 0 ? y : x < 0 ? ~sum(~x, -y) : sum(x-1, y+1)
Note: the rather optimisic use of ~ to avoid blowing up on x=MIN_VALUE. ;)
Javaish pseudo code corresponding to your code in your question
sum(x, y): return x == 0 ? y : sum(x-1, y+1)
Works for any pair of numbers where x is a non-negative integer.

Categories