Questions about moduls and return statement - java

I have two questions about this of code.
Can someone explain me, what the if statement is doing exactly. I know that count has to increment every time the test is true, but I'm not sure what the this n % i == 0 is doing.
My second question is, how can I print the return statement's answer on the console?
int n = 10;
countFactors(n);
}
public static int countFactors(int n){
int count = 0;
for (int i = 1; i <= n; i++){
if (n % i == 0) //this line
count++;
}
return count;
}
}

It count the number of divisor in your range 1-n so for example :
if n = 10 the result will be 4 because there are 4 divisor:
1
2
5
10
and about how you print in console :
for (int i = 1; i <= n; i++) {
if (n % i == 0) {
count++;
System.out.println(i);
}
}
System.out.println("Number or disivor = " + count);
You can learn here : Table of divisors

Well, as the name of the method suggests, the count represents the number of divisors that n has.
The if statement tests the following: Is n divisible by i?. in other words: Is n/i a whole number?
if you were to use:
if(n%i == 1)
instead, then it would count the numbers for which: n/i has a remainder of 1.
in order to print the return statement, you can add this line just before the return:
public static int countFactors(int n){
int count = 0;
for (int i = 1; i <= n; i++){
if (n % i == 0)
count++;
}
System.out.println(count);//adding this
return count;
}

The % operator (known as the remainder or Modulus operator) basically divides a number by another and gives you the remainder and nothing else. For instance, if you do 4 % 2, it would give you 0 because 2 goes into 4 evenly. If you would do 4 % 3 it would give you 1 because that's the remainder of 4 / 3. Also look at this website: http://www.cafeaulait.org/course/week2/15.html
The countFactors method loops 1 to n and includes n. If you do 10 % 1, you would get 0 because one goes into 10 evenly so the count would be incremented.

Related

Solution codewars to car Mileage problem, running out of ideas?

I am trying to work out a solution to the CodeWars challenge Catching Car Mileage Numbers:
Write the function that parses the mileage number input, and returns a 2 if the number is "interesting" (see below), a 1 if an interesting number occurs within the next two miles, or a 0 if the number is not interesting.
Interesting numbers are 3-or-more digit numbers that meet one or more of the following criteria:
Any digit followed by all zeros: 100, 90000
Every digit is the same number: 1111
The digits are sequential, incementing†: 1234
The digits are sequential, decrementing‡: 4321
The digits are a palindrome: 1221 or 73837
The digits match one of the values in the awesomePhrases array
† For incrementing sequences, 0 should come after 9, and not before 1, as in 7890.
‡ For decrementing sequences, 0 should come after 1, and not before 9, as in 3210.
I can pass all tests in the first batch, but fail to pass the second batch.
Any feedback would be very much appreciated, not only on a possible solution but also to the way I'm thinking about the exercise.
public static int isInteresting(int number, int[] awesomePhrases) {
for (int offSet = 0; offSet <= 2; offSet++) {
int testNumber = number;
testNumber += offSet;
boolean isYellow = testNumber != number;
int yellowOffset = 0;
if (isYellow) {
yellowOffset = 1;
}
//check three or more digit number
boolean greaterThan99 = testNumber > 99;
int[] numbers = Integer.toString(testNumber).chars().map(c -> c - '0').toArray();
int zeroCounter = 0;
int identicalCounter = 0;
int incrementingCounter = 0;
int decrementingCounter = 0;
int palindromeCounter = 0;
boolean endsInZero = numbers[numbers.length - 1] == 0;
for (int i = 0; i < numbers.length; i++) {
//check digit followed by zeros
if (numbers[i] == 0) {
zeroCounter++;
}
if (i + 1 < numbers.length) {
//check every digit is the same
if (numbers[i] == numbers[i + 1]) identicalCounter++;
//check ascending order
if (numbers[i + 1] - numbers[i] == 1) incrementingCounter++;
//check descending order
if (numbers[i] - numbers[i + 1] == 1) decrementingCounter++;
}
}
if (greaterThan99) {
//check awesomePhrases
for (int phrase : awesomePhrases) {
if (phrase == testNumber) return 2 - yellowOffset;
}
//check palindrome
int reversedIndex = numbers.length - 1;
for (int i = 0; i < numbers.length; i++) {
if (numbers[reversedIndex] == numbers[i]) {
palindromeCounter++;
}
reversedIndex--;
}
if (zeroCounter == numbers.length - 1) return 2 - yellowOffset;
if (identicalCounter == numbers.length - 1) return 2 - yellowOffset;
if (incrementingCounter == numbers.length - 1) return 2 - yellowOffset;
if (incrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
if (decrementingCounter == numbers.length - 1) return 2 - yellowOffset;
if (decrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
if (palindromeCounter == numbers.length) return 2 - yellowOffset;
}
}
return 0;
}
I've tried pretty much all I know but to no result, all the tests I try pass, would love to know what I'm doing wrong.
The problem is in how your code tests for increasing sequences that end in a zero. It is not enough to test that the sequence has n-2 increments and the last digit is a zero, because that will give a false positive on numbers like 6780. It is required that the one-but-last digit is a 9.
A similar issue exist for the decreasing sequence logic, however, there you would not need a special test for an ending zero at all. This condition is covered by counting n-1 decrements, where the ending could be a 1 followed by a zero. There is no special case to be handled here.
To fix the first problem, I would suggest you not only check whether the last digit is a zero, but whether the last two digits are 9 and 0, or in other words, that the number modulo 100 is equal to 90.
You could replace this:
boolean endsInZero = numbers[numbers.length - 1] == 0;
by this:
boolean endsInNinety = testNumber % 100 == 90;
and then replace:
if (incrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
by:
if (incrementingCounter == numbers.length - 2 && endsInNinety) return 2 - yellowOffset;
and finally remove this test:
if (decrementingCounter == numbers.length - 2 && endsInZero) return 2 - yellowOffset;
This will fix it.
Note that it can be helpful to have your function print the input it gets, so that when a test fails, at least you can know for which input there was a problem:
System.out.println("input " + number);

The loop has no output?

The code below has no output when I run it, I think somehow it is infinite loop? How to fix it?
Write a method named getEvenDigitSum with one parameter of type int called number.
The method should return the sum of the even digits within the number.
If the number is negative, the method should return -1 to indicate an invalid value.
EXAMPLE INPUT/OUTPUT:
getEvenDigitSum(123456789); → should return 20 since 2 + 4 + 6 + 8 = 20
getEvenDigitSum(252); → should return 4 since 2 + 2 = 4
getEvenDigitSum(-22); → should return -1 since the number is negative
public class getEvenDigitSum {
public static int getEvenDigitSum(int number) {
int sum = 0;
int lastDigit=0;
if (number < 0) {
return -1;
}
while (number >0) {
lastDigit = number % 10;
if (number % 2 == 0)
{
sum += lastDigit;
number = number / 10;
}
}
return sum;
}
}
while (number >0) {
lastDigit = number % 10;
if (number % 2 == 0)
{
sum += lastDigit;
number = number / 10;
}
}
OK, and what happens if the number isn't even? You didn't make an else/else if statement after; if your number is odd, it stays the same, the loop is infinite, and hence your code does nothing.
Your condition only handles even digits, but think about what happens when you get a number that contains odd digit, like 1221 for example.
Try adding the missing else statement:
while (number >0) {
lastDigit = number % 10;
if (number % 2 == 0)
{
sum += lastDigit;
number = number / 10;
}
else {
// Deal with odd digit, leaving for you to implement
{
}
General tip: The best way to find errors in your code is to write tests and debug your code.
These are two skills every developer should poses and practice regularly

Prime numbers - I need clarification on code implementation

This is the code I know:
bool checkPrime(int n) {
bool prime = true;
for (int i = 2; i < n; i++) {
if ((n%i) == 0) {
prime = false;
}
}
return prime;
}
But is this ok if you’re looking for prime numbers:
List<int> arr = [2, 3, 5, 7]; // Already known
int n = 30; // Between 1 to 30. It could be any number
for (int i = 2; i < n; i++) {
if (i % 2 != 0 && i % 3 != 0 && i % 5 != 0 && i % 7 != 0) {
arr.add(i);
}
// Then maybe some code for numbers less than 8
}
print(arr);
Output:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
And also is there much difference in time complexity?
Your code is incorrect.
This code only works because you are taking the value of n as 30, for a greater number like 1000 this will produce an incorrect result.
List arr = [2,3,5,7]; // already known
int n = 1000; // between 1 to 1000 it could be any number
List<int> arr = [2,3,5,7];
for (int i = 2; i < n; i++) {
if (i % 2 != 0 && i % 3 != 0 && i % 5 != 0 && i % 7 != 0){
arr.add(i);
}
//Then maybe some code for numbers less than 8
}
print(arr);
Your code will return 231 prime numbers when there are actually only 168 prime numbers.
This is because you are not considering the future prime numbers that can only be divided by a prime number between 7 to that number.
eg: 121 will be returned by you as prime but it is a multiple of 11
Extending your pattern.
Though this will be faster since it has reduced a number of division operations but due to two loops, it will still be N square.
Here I am simply only dividing numbers from the existing prime numbers collection and adding them in the collection if prime is found tobe used in next iteration for division.
List < int > arr = [2]; // taking 2 since this is the lowerst value we want to start with
int n = 30; // n can between 2 to any number
if (n < 3) {
print(arr); // can return from here.
}
// since we already have added 2 in the list we start with next number to check that is 3
for (int i = 3; i < n; i++) {
bool isPrime = true;
for (int j = 0; j < arr.length; j++) { // we iterate over the current prime number collection only [2] then [2,3]...
if (i % arr[j] == 0) { // check if number can be divided by exisiting numbers
isPrime = false;
}
}
if (isPrime) { // eg: 2 cant divide 3 so we 3 is also added
arr.add(i)
}
}
print(arr);
You can look a faster pattern here.
Which is the fastest algorithm to find prime numbers?

Java - 3 or More Distinct Numbers

In my code, the user enters how many numbers they want to test, and then enters the numbers. If a number can be divided by 3 distinct numbers, it prints a "1". Otherwise, it prints a "0". When I run my code, it only prints "0". I tried fixing some of the brackets to see if messed up somewhere in the syntax.
int distinct = 0;
int T = input.nextInt();
int [] nums = new int [T];
for (int n : nums) {
distinct = 0;
n = input.nextInt();
for (int m = nums.length; m == 0; m--) {
if (n % m == 0) {
distinct++;
}
}
if (distinct < 3) {
System.out.println("0");
}
else
System.out.println("1");
}
}
}
By "three distinct numbers", I mean a number like "4" which can be divided by "4, 2, and 1".
When I enter this:
3
2 3 4
It returns:
0
0
0
When it should return:
0
0
1
In the for loop, you initiate the variable with int m = nums.length.
As the length of nums is defined at the beginning by the user as 3, the first factor you check is 3 before checking all positive integers less than this. So, for n = 4 you check 3, 2 and 1; only 2 and 1 are factors so distinct will be 2. I suspect this should be int m = n;
for (int m = n; m == 0; m--) {
if (n % m == 0) {
distinct++;
}
}
Assuming you are ignoring negative integers (as this would mean negative integers could be considered), the only time this will fail is when n is 1 or n is prime; 1 and n itself will always be a factor. As such, you could ignore the check for these values.

Largest prime factor of a number in Java

I am trying to find the Largest prime factor of a number while solving this problem here. I think that I am doing everything right, however one of the test case (#2) is failing and I can't think of any corner case where it might fail. Here's my code, please have a look and try to spot something.
public class ProblemThree
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
int T = scanner.nextInt();
for (int i = 0; i < T; i++)
{
System.out.println(largestPrime(scanner.nextLong()));
}
}
private static long largestPrime(long n)
{
while (n % 2 == 0)
{
n = n / 2; // remove all the multiples of 2
}
while (n % 3 == 0)
{
n = n / 3; // remove all the multiples of 2
}
// remove multiples of prime numbers other than 2 and 3
while (n >= 5)
{
boolean isDivisionComplete = true;
for (long i = 5; i < Math.ceil(Math.sqrt(n)); i++)
{
if (n % i == 0)
{
n = n / i;
isDivisionComplete = false;
break;
}
}
if (isDivisionComplete)
{
break;
}
}
return n;
}
}
Basically, what I am doing is:
Largest_Prime(n):
1. Repeatedly divide the no by any small number, say x where 0 < x < sqrt(n).
2. Then set n = n/x and repeat steps 1 and 2 until there is no such x that divides n.
3 Return n.
It seems you have some bug in your code as as when you input 16 largestPrime function return 1. and this is true for when input is the power of 3.
Detailed Algorithm description:
You can do this by keeping three variables:
The number you are trying to factor (A)
A current divisor store (B)
A largest divisor store (C)
Initially, let (A) be the number you are interested in - in this case, it is 600851475143. Then let (B) be 2. Have a conditional that checks if (A) is divisible by (B). If it is divisible, divide (A) by (B), reset (B) to 2, and go back to checking if (A) is divisible by (B). Else, if (A) is not divisible by (B), increment (B) by +1 and then check if (A) is divisible by (B). Run the loop until (A) is 1. The (3) you return will be the largest prime divisor of 600851475143.
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for(int a0 = 0; a0 < t; a0++){
long n = in.nextLong();
long A=n;
long B=2;
long C=0;
while(Math.pow(B,2)<=A)
{
if(A%B==0)
{
C=B;
A=A/B;
B=2;
}
else
B++;
}
if(A>=C)
C=A;
if(A==1)
{ C=2;
break;
}
System.out.println(C);
}
}
Why are you removing multiples of 2 and multiples of 3? This way if you have a number that is any combination of powers of 2 and 3 you will get your answer as 1 which is clearly wrong.
For this problem you can do the naive way of looping from 2 to sqrt(n) and store the largest number which divides n, when you finish your loop just return the highest divisor you found.
1 drop your loop for 2 and 3. If not, you dont get 2, 2x2, 3, 2x3, ... all multiples of 2 and 3
2 change your loop to stop at 2 (and not 5):
while (n >= 2)
{
3 stop if 2
if (n==2) return 2;
4 loop from 2
and
5 loop until sqrt(n), with <= and not only < (if not, you dont get prime X Prime)
for (long i = 2; i <= Math.ceil(Math.sqrt(n)); i++)
One easy way of extracting prime factors is like this:
/**
* Prime factors of the number - not the most efficient but it works.
*
* #param n - The number to factorise.
* #param unique - Want only unique factors.
* #return - List of all prime factors of n.
*/
public static List<Long> primeFactors(long n, boolean unique) {
Collection<Long> factors;
if (unique) {
factors = new HashSet<>();
} else {
factors = new ArrayList<>();
}
for (long i = 2; i <= n / i; i++) {
while (n % i == 0) {
factors.add(i);
n /= i;
}
}
if (n > 1) {
factors.add(n);
}
return new ArrayList<>(factors);
}
Those first loops are a problem. They will reduce all even numbers to 1 - thus missing 2 as the factor. Changing your code to use:
while (n > 2 && n % 2 == 0) {
n = n / 2; // remove all the multiples of 2
}
while (n > 3 && n % 3 == 0) {
n = n / 3; // remove all the multiples of 2
}
You still have further issues - e.g. you report the largest prime factor of 25 to be 25 and the largest prime factor of 49 to be 49.
Just run this code using yours and mine to see where yours fails:
for (long i = 1; i < 1000; i++) {
long largestPrime = largestPrime(i);
List<Long> primeFactors = primeFactors(i, true);
if (primeFactors.size() > 0) {
Collections.sort(primeFactors, Collections.reverseOrder());
long highestFactor = primeFactors.get(0);
if (largestPrime != highestFactor) {
System.out.println("Wrong! " + i + " " + largestPrime + " != " + primeFactors);
}
} else {
System.out.println("No factors for " + i);
}
}

Categories

Resources