How can I improve this code for Project Euler 7? - java

By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10 001st prime number?
My solution:
public class Prime_Number {
public static boolean isPrime(long n) {
if ((n > 2 && n % 2 == 0) || (n > 3 && n % 3 == 0) || (n > 5 && n % 5 == 0) || n == 0 || n == 1) {
return false;
}
return true;
}
public static void main(String[] args) {
int count = 0;
int prime = 0;
while (prime <= 10001) {
if (isPrime(count) == true) {
prime++;
if (prime == 10001) {
System.out.println(count + " is a prime number" + "(" + prime + ")");
}
}
count++;
}
}
}
But it does not give a correct answer. Please help me to upgrade my code. For instance, program defines a 91 as a prime number, but it is not a prime number. How to improve it?

You need to test the number against every prime less than its square root to ensure it is prime.
You're only testing against 2,3 and 5.
Because storing all the primes is not always space-feasable, a common technique is to test for 2, and then test all odd numbers starting at 3. This requires a loop.
consider:
boolean isPrime(long n) {
if (n < 2) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
if (n < 9) return true;
if (n % 3 == 0) return false;
long max = (long)(Math.sqrt(n + 0.0)) + 1;
for (int i = 5; i <= max; i += 6) {
if (n % i == 0) return false;
if (n % (i + 2) == 0) return false;
}
return true;
}

A number p is prime if it only divides by itself and 1. You are checking only for divison by 2, 3 and 5. This is not enough. Check for every number till p / 2, or better till sqrt(p).

The following solution checks only the odd numbers to be prime, but it counts 2 as prime from the beginning:
public class A {
static int N = 10001;
private static boolean isOddPrime(long x) {
for ( int i = 3 ; i*i <= x ; i+=2 ) {
if ( x % i == 0 ) {
return false;
}
}
return true;
}
public static void main(String[] args) throws Exception {
long start = System.nanoTime();
int x;
int i = 2; // 3 is the 2nd prime number
for ( x = 3 ; ; x+=2 ) {
if ( isOddPrime(x) ) {
if ( i == N )
break;
i++;
}
}
System.out.println(x);
long stop = System.nanoTime();
System.out.println("Time: " + (stop - start) / 1000000 + " ms");
}
}
Output:
104743
Time: 61 ms

I would comment, but I just joined.
You don't have to check every number between 1 and a numbers square root for potential divisors, you just have to check all previous primes (assuming you start at 1 and iterate up), as any other divisor that is not prime will itself be divisible by a prime of a lower value. the higher the number of primes, the more checks against non prime numbers this saves. the example is in C# but that's more to demonstrate the concept.
//store found primes here, for checking subsequent primes
private static List<long> Primes;
private static bool IsPrime(long number)
{
//no number will have a larger divisor withou some smaller divisor
var maxPrime = Math.Sqrt(number);
// takes the list of primes less than the square root and
// checks to see if all of that list is not evenly
// divisible into {number}
var isPrime = Primes
.TakeWhile(prime => !(prime > maxPrime))
.All(prime => number % prime != 0);
if (isPrime)
Primes.Add(number);
return isPrime;
}
private static long GetNthPrime(int n)
{
//reset primes list to prevent persistence
Primes = new List<long> { 2, 3, 5, 7 };
//prime in starting set
if (Primes.Count >= n)
{
return Primes[n - 1];
}
//iterate by 6 to avoid all divisiors of 2 and 3
// (also have to check i + 2 for this to work)
// similar to incrementing by 2 but skips every third increment
// starting with the second, as that is divisible by 3
for (long i = 11; i < long.MaxValue; i += 6)
{
// only check count if is prime
if ((IsPrime(i) && Primes.Count >= n) || (IsPrime(i + 2) && Primes.Count >= n))
{
break;
};
}
//return end of list
return Primes[n - 1];
}

Related

Calculate the number of Primes that are less than the given Number [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 months ago.
Improve this question
I'm getting desired output, but I'm not able to submit the code on the Leetcode.
The link of question on the Leetcode
Problem statement:
Given an integer n, return the number of prime numbers that are
strictly less than n.
Constraints:
0 <= n <= 5 * 10 ^ 6
My code:
class Solution {
public static int count = 1;
public int countPrimes(int n) {
if (n == 0 || n == 1 || n == 2)
return 0;
else
for (int i = 3; i < n; i++) {
for (int j = 2; j < i; j++) {
if (i % j == 0) {
break;
} else if (j == i - 1 && i % j != 0) {
count++;
}
}
}
return count;
}
}
It gives the desired result all the time but when I try to submit it, it shows that only 4/66 tests cases are passed.
Can someone please tell me what's wrong here and why I'm not able to submit the solution?
Don't use static variables without any good reason. count will live in memory until the application runs and will be effected by every invocation of countPrimes() with argument n greater than 3. Even if Leetcode creates a new instance of the Solution for every test (can't check it because I'm not registered there), static variable would maintain the previously assigned value because it doesn't belong to any instances of Solution, but shared among them all.
You will definitely not encounter this issue (but potentially there could be others related to performance) if variable count would be local - i.e. declared inside the countPrimes().
Condition if (n == 0 || n == 1 || n == 2) can be simplified to if (n <= 2). And there's no need to use else clause because you are returning if condition matches.
Similarly, there's no need for the else clause in the nested loop after the break.
So your code can be written like this:
public int countPrimes(int n) {
if (n <= 2) {
return 0;
}
int count = 1;
for (int i = 3; i < n; i++) {
for (int j = 2; j < i; j++) {
if (i % j == 0) break;
if (j == i - 1 && i % j != 0) {
count++;
}
}
}
return count;
}
There are several enhancements we can make to improve performance.
Not every Number is Prime - reducing the number of iterations
As obvious, not every number is prime. The most simple observation we can make is that 2 is the only even number among primes. And if the candidate number is greater than 2 we can skip all even numbers by incrementing the index of the loop by 2.
The next interesting property of primes that we can make use of is that there's no gap between the two first primes - the next prime after 2 is 3. Which means if the candidate number is greater than 3 we don't need to check numbers that are divisible by 2 and by 3.
I.e. we can omit 4 of every 6 consecutive numbers, in other words the candidate number can be represented as N * 6 - 1 and N * 6 + 1, these pair of number will not be divisible neither by 2, no by 3.
To achieve that, we can initialize the loop variable to 6 - int i = 6 and increment it at each iteration step by 6 - i += 6, and at every step of iteration (which would represent the next range of 6 number) we need to check the candidate number against two values: i - 1 and i + 1.
Another improvement we can make is connected with condition j < i. For a large input value n this condition will cause a lot of fruitless iterations because there would be no prime divisors for any given number i greater than sqrt(i) see.
And solution will be more readable if we split the method into two logical parts based on responsibilities: a method that is responsible for checking whether a candidate number is prime, and a method that tracks the number of discovered primes.
public int countPrimes(int n) {
if (n < 3) return 0;
if (n == 3) return 1;
if (n == 4) return 2;
int count = 2;
for (int i = 6; i <= n + n % 6; i += 6) {
if ((i - 1) < n && isPrime(i - 1)) {
count++;
}
if ((i + 1) < n && isPrime(i + 1)) {
count++;
}
}
return count;
}
public boolean isPrime(int candidate) {
if (candidate % 2 == 0 || candidate % 3 == 0) return false;
if (candidate == 5) return true;
if (candidate % 5 == 0) return false;
boolean isPrime = true;
double sqrt = Math.sqrt(candidate);
for (int i = 6; i <= sqrt; i += 6) {
if (candidate % (i - 1) == 0 || candidate % (i + 1) == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
This solution will be faster than the initial version, but we can do better.
Don't recalculate the same Primes
There's no need to recalculate the same prime numbers over and over while checking a candidate number.
Instead, we can store every discovered prime number into a list and then check every candidate number against the previously encountered primes from the list.
public int countPrimes(int n) {
if (n < 3) return 0;
if (n == 3) return 1;
if (n == 4) return 2;
List<Integer> primes = new ArrayList<>();
Collections.addAll(primes, 2, 3); // this line will be executed only if n > 4, hence we need to add primes 2 and 3 into the list
// we don't need variable `count` anymore, instead we can check the size of primes
for (int i = 6; i <= n + n % 6; i += 6) {
if (i - 1 < n && isPrime(i - 1, primes)) {
primes.add(i - 1);
}
if (i + 1 < n && isPrime(i + 1, primes)) {
primes.add(i + 1);
}
}
return primes.size();
}
public boolean isPrime(int candidate, List<Integer> primes) {
boolean isPrime = true;
double sqrt = Math.sqrt(candidate);
for (int i = 0; i < primes.size() && primes.get(i) < sqrt; i++) {
if (candidate % primes.get(i) == 0) {
isPrime = false;
break;
}
}
return isPrime;
}

Display all prime numbers based on range inputted in java

I am trying to solve a sample exercise which is to display Prime numbers based on the range inputted. For example if I inputted 10 it should output 2 3 5 7 11 13 17 19 23 29.
Here is my code:
System.out.print("Enter Range: ");
int range = input.nextInt();
int r = 0;
for(int ctr1 = 2; ctr1 <= range; ctr1++){
for(int ctr2 = 1; ctr2 <= ctr1; ctr2++){
if(ctr1%ctr2 == 0){
r++;
}
}
if(r == 2){
System.out.println(ctr1);
}
}
What happens is when I input 10 it just outputs 2. Can anyone please tell me the error in my codes?
Thanks...
Using nested loop in this case could make things more complicated. I would suggest you to divide the solution into two steps:
create a function to determine if a number is prime.
private static boolean isPrime(int n) {
//check if n is a multiple of 2
if (n % 2 == 0) return false;
//if not, then just check the odds
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0)
return false;
}
return true;
}
find the first N prime numbers with a loop:
System.out.print("Enter Range: ");
int range = input.nextInt();
int count = 0;
for (int number = 2; count < range; number++) {
if (isPrime(number)) {
count++;
System.out.println(number);
}
}
I didnt understand your code. Try to give reasonable parameter names. Anyway this the code that you are looking for.
public static void main(String args[]) {
//get input till which prime number to be printed
System.out.println("Enter the amount of prime numbers to be printed: ");
int limit = new Scanner(System.in).nextInt();
int count=1;
//printing primer numbers till the limit ( 1 to 100)
System.out.println("Printing prime number from 1 to " + limit);
for(int number = 2; count<=limit; number++){
//print prime numbers only
if(isPrime(number)){
System.out.println(number);
count++;
}
}
}
/*
* Prime number is not divisible by any number other than 1 and itself
* #return true if number is prime
*/
public static boolean isPrime(int number){
for(int i=2; i<number; i++){
if(number%i == 0){
return false; //number is divisible so its not prime
}
}
return true; //number is prime now
}
One more solution)
public static boolean checkPrime(int i) {
if (i <= 1)
return false;
else if (i <= 3)
return true;
else if (i % 2 == 0 || i % 3 == 0)
return false;
int n = 5;
while (n * n <= i) {
if (i % n == 0 || i % (n + 2) == 0)
return false;
n = n + 6;
}
return true;
}
public static void main(String[] args) throws Exception {
int isPrime = 0;
int counter = 0;
int size = 10;
while (isPrime < size) {
counter++;
if (checkPrime(counter)) {
isPrime++;
System.out.println(counter);
}
}
}

identify prime number using recursive method [java]

the problem is below. main() checks numbers 1-10 by calling isPrime(). I think I have the math right however every number other than 2 comes back as not prime.
I have checked some of the solutions and questions on SO, however, I can't seem to achieve the same results.
original problem:
public class PrimeChecker {
// Returns 0 if value is not prime, 1 if value is prime
public static int isPrime(int testVal, int divVal) {
// Base case 1: 0 and 1 are not prime, testVal is not prime
// Base case 2: testVal only divisible by 1, testVal is prime
// Recursive Case
// Check if testVal can be evenly divided by divVal
// Hint: use the % operator
// If not, recursive call to isPrime with testVal and (divVal - 1)
return 0;
}
public static void main(String[] args) {
int primeCheckVal = 0; // Value checked for prime
// Check primes for values 1 to 10
for (primeCheckVal = 1; primeCheckVal <= 10; ++primeCheckVal) {
if (isPrime(primeCheckVal, (primeCheckVal - 1)) == 1) {
System.out.println(primeCheckVal + " is prime.");
}
else {
System.out.println(primeCheckVal + " is not prime.");
}
}
}
}
My solution so far:
public class PrimeChecker {
// Returns 0 if value is not prime, 1 if value is prime
public static int isPrime(int testVal, int divVal) {
int resultVal = 0;
if ((testVal == 0) || (testVal == 1)){
resultVal = 0;
}// Base case 1: 0 and 1 are not prime, testVal is not prime
else if (divVal == 1) {
resultVal = 1;
}// Base case 2: testVal only divisible by 1, testVal is prime
else {
if((testVal % divVal != 0) && (testVal / divVal == 1)) {
isPrime(testVal, (divVal-1));
}
else {
resultVal = 1;
}
}
return resultVal;
}
public static void main(String[] args) {
int primeCheckVal = 0; // Value checked for prime
// Check primes for values 1 to 10
for (primeCheckVal = 1; primeCheckVal <= 10; ++primeCheckVal) {
if (isPrime(primeCheckVal, (primeCheckVal - 1)) == 1) {
System.out.println(primeCheckVal + " is prime.");
}
else {
System.out.println(primeCheckVal + " is not prime.");
}
}
}
}
Change the if/else block
if((testVal % divVal != 0) && (testVal / divVal == 1)) {
isPrime(testVal, (divVal-1));
}
else {
resultVal = 1;
}
to
if (testVal % divVal != 0) {
return isPrime(testVal, (divVal-1));
} else {
resultVal = 0;
}
Basically, you've forgotten to return the result of your recursion, so the code carries on to return the wrong thing. If testVal % divVal == 0, the number is non-prime so you return zero. Also, don't use ints that only take the value of zero or one; use a boolean.
According your question, I think the following code would be easier.
public class PrimeChecker {
// Returns 0 if value is not prime, 1 if value is prime
public static int isPrime(int testVal, int divVal) {
// Base case 1: 0 and 1 are not prime, testVal is not prime
if (testVal <= 1) {
return 0;
}
// Base case 2: testVal only divisible by 1, testVal is prime
if (divVal == 1) {
return 1;
}
// Recursive Case
// Check if testVal can be evenly divided by divVal
// Hint: use the % operator
if (testVal % divVal == 0) {
return 0;
}
// If not, recursive call to isPrime with testVal and (divVal - 1)
return isPrime(testVal, divVal - 1);
}
public static void main(String[] args) {
int primeCheckVal; // Value checked for prime
// Check primes for values 1 to 10
for (primeCheckVal = 1; primeCheckVal <= 10; ++primeCheckVal) {
if (isPrime(primeCheckVal, (primeCheckVal - 1)) == 1) {
System.out.println(primeCheckVal + " is prime.");
}
else {
System.out.println(primeCheckVal + " is not prime.");
}
}
}
}

Codingbat- Recursion1- count7

Can anybody help me programming the next problem (taken from Codingbat- Recursion1- count7)
Given a non-negative int n, return the count of the occurrences of 7 as a digit, so for example 717 yields 2. (no loops). Note that mod (%) by 10 yields the rightmost digit (126 % 10 is 6), while divide (/) by 10 removes the rightmost digit (126 / 10 is 12).
count7(717) → 2
count7(7) → 1
count7(123) → 0
There are some solutions which includes number of "returns".
I would like to program the problem with only 1 "return".
Well here's the solution I wrote and let's see how to do it with only one return
public int count7(int n)
{
int c = 0;
if (7 > n)
{
return 0;
}
else
{
if ( 7 == n % 10)
{
c = 1;
}
else
{
c = 0;
}
}
return c + count7(n / 10);
}
the same with only one return
public int count7(int n)
{
return (7 > n) ? 0 : ( ( 7 == n % 10) ? 1 + count7(n / 10) : 0 + count7(n / 10));
}
public int count7(int n) {
int counter = 0;
if( n % 10 == 7) counter++;
if( n / 10 == 0) return counter;
return counter + count7(n/10);
}
Sure PFB my solution in JAVA for the same
public int count7(int n) {
if((n / 10 == 0) && !(n % 10 == 7)) //First BASE CASE when the left most digit is 7 return 1
return 0;
else if((n / 10 == 0) && (n % 10 == 7)) //Second BASE CASE when the left most digit is 7 return 0
return 1;
else if((n % 10 == 7))
//if the number having 2 digits then test the rightmost digit and trigger recursion trimming it there
return 1 + count7(n / 10);
return count7(n / 10);
}
public int count7(int n) {
if(n == 0)
return 0;
else{
if(n%10 ==7)
return 1+count7(n/10);
return 0+count7(n/10);
}
}
public static int count7(int n){
if(n == 7)
return 1;
else if(n > 9){
int a = count7(n%10);
int b = count7(n/10);
return a + b;
}else
return 0;
}
public int count7(int n)
{
if(n==0)return 0;
if(n%10==7)return 1+count7(n/10);
else return count7(n/10);
}
public int count7(int n) {
if (n != 7 && n < 10) return 0;
else if (n == 7) return 1;
else if (n%10 == 7) return count7(n/10) + 1 ;
else return count7(n/10);
}
public int count7(int n){
if(n < 7)
return 0;
else if(n % 10 == 7)
return 1 + count7(n / 10);
else
return count7(n / 10);
}
the first if-statement is the base case that we would want to terminate on. The second checks to see if the rightmost digit is 7. If it is, chop the rightmost digit off and try again. When the recursive calls terminate and and values start getting returned up the chain, add 1 to include this successful check. In the case that neither of the above statements are true, chop off the rightmost digit and try again.
I know this is 2 years old, but hope this is a bit more readable and intuitive, and thus helpful.
Here is how I did it.
public int count7(int n) {
return (n==0?0:(count7(n/10)+(n%10==7?1:0)));
}
Recursion goes to 0 and it returns 0, when it comes back out checks if each number is 7, returns 1 if it is else 0. It continues adding those until all the way out.
Using one return will likely make it harder to read. If you are counting occurrences in recursion, an easy formula is to create a base case to terminate on, then provide an incremental return, and finally a return that will aid in reaching the base case without incrementing. For example..
public int count7(int n) {
if(n == 0) return 0;
if(n % 10 == 7) return 1 + count7(n / 10);
return count7(n / 10);
}
Using a one liner return like the one below in my opinion is harder to read or update because of the double ternary..
public int count7(int n)
{
return (n == 0) ? 0 : (n % 10 == 7) ? 1 + count7(n / 10) : count7(n / 10);
}
My solution works backwards from the nth digit to the first digit, by taking the modulus of the input. we add the number of sevens found into the return, for the final output.
Then checking whether the input is less than 7 can be the next step. If the input is less than 7 then there have never been any 7s in the input to begin with.
public int count7(int n) {
int sevens_found = 0;
if( n % 10 == 7 ) sevens_found ++;
return ( n < 7) ? 0 : ( n % 10 == 7 ) ? sevens_found + count7 ( n / 10 ) : count7 ( n / 10 );
}
#include<bits/stdc++.h>
using namespace std;
int count_occurences(int k){
int r;
if(k==0){
return 0;
}
r = k%10;
k = k/10;
if(r!=7){
return count_occurences(k);
}
return 1+count_occurences(k);
}
int main()
{
int x;
cin>>x;
cout<<" "<<count_occurences(x);
return 0;
}
public int count7(int n) {
int length = 0;
int counter = 0;
if ((n / 10) * 10 != n || (n / 10) != 0) {
if (n % 10 != 7) {
counter++;
}
length += 1 + count7(n / 10);
}
return length - counter;
}
The base case of n == 0 just "breaks" us out of the recursive loop, the n % 10 == 7 allows us to actually count the amount of 7s in an integer, and the return statement iterates through the given argument.
public int count7(int n) {
if (n == 0)
return 0;
if (n % 10 == 7)
return 1 + count7(n / 10);
return count7(n / 10);
}
public int count7(int n)
{
return occurrencesCounting(n, 0);
}
private int occurrencesCounting(int n, int count)
{
int counter = n % 10 == 7 ? count + 1 : count;
if (n / 10 == 0)
{
return counter;
}
return occurrencesCounting(n / 10, counter );
}

Count the number of '8's Problem in Java

Im stuck with the below problem.
Problem Statement:
Given a non-negative int n, return the count of the occurrences of 8 as a digit, except that an 8 with another 8 immediately to its left counts double, so 8818 yields 4.
Note: mod (%) by 10 yields the rightmost digit (126 % 10 is 6), while divide (/) by 10 removes the rightmost digit (126 / 10 is 12).
The above problem has to be solved without using Recursion and without the usage of any formulas.
The function signature is public int count8(int n)
Examples are:
count8(8) → 1
count8(818) → 2
count8(8818) → 4
I got this problem from one of the Programming Forums. I dont know how to start with this problem, I want to solve it, but I am really confused on where to begin.
the way to do this using the mod operator is to use %10 to get the last digit and /10 to remove the last digit in essence iterating through the number. If you %10 and get an 8 you can incremement a count, you can also keep a flag that lets you know if the last digit you saw was an 8 or not so you know how to increment your count
boolean lastWas8 = false;
int count = 0;
while (n != 0)
{
int digit = n % 10;
if (digit == 8)
{
if (lastWas8) count++;
count++;
lastWas8 = true;
}
else lastWas8 = false;
n/=10;
}
return count;
As none of the answers until now was recursive, here is my try at a recursive solution.
public int count8(int n) {
return
n <= 0 ? 0 :
( n%100 == 88 ? 2 :
n%10 == 8 ? 1 : 0)
+ count8(n/10);
}
Here the same program in a longer version:
public int count8(int n) {
Numbers without digits have no eights in them.
if(n <= 0) {
return 0;
}
Count the last digit:
int last;
If the last digit is an 8 and the digit before, too, count the last 8 doubled:
if(n % 100 == 88) {
last = 2;
}
If the last digit is an 8 (and the one before not), count it once.
else if(n % 10 == 8) {
last = 1;
}
Otherwise, the last digit is not an 8:
else {
last = 0;
}
The number without the last digit:
int withoutLast = n/10;
The number of eights in n is the number of eights in the last digit + the number of eights in the number without its last digit:
return last + count8(withoutLast);
}
Since I misread the question, here a iterative version of the same algorithm:
public int count8(int n) {
int count = 0;
while(n > 0) {
count += ( n%100 == 88 ? 2 : n%10 == 8 ? 1 : 0);
n/= 10;
}
return count;
}
Or with a for-loop:
public int count8(int n) {
int count = 0;
for( ; n > 0; n/=10) {
count += ( n%100 == 88 ? 2 : n%10 == 8 ? 1 : 0);
}
return count;
}
I saw that all the other solutions have used mods or divs but you could also just process it as a String I guess (I don't see anything in the question that says you can't despite the hints they give you). This is just an alternative solution.
I apologise in advance if I have missed some of the "rules" around the answer to this question but here we go anyway:
private int count8(int n) {
String nString = Integer.toString(n);
boolean isPrevChar8 = false;
int total = 0;
for (int i = 0; i < nString.length(); i++) {
char nextChar = nString.charAt(i);
if (nextChar == '8') {
total += (isPrevChar8 ? 2 : 1);
isPrevChar8 = true;
} else {
isPrevChar8 = false;
}
}
return total;
}
try this :
public static int count8(int num) {
int count=0;
boolean doubl = false;
while(true) {
int n = num%10;
num = num/10;
if(n==8) {
if(doubl) {
count = count+2;
} else {
count++;
}
doubl=true;
}
else {
doubl=false;
}
if(num == 0) break;
}
return count;
}
EDIT: Check this out for no recursion and no formula.
public static int count8(int num) {
int count=0;
boolean doubl = false;
String str = "" + num;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == '8') {
if (doubl) {
count = count + 2;
} else {
count++;
}
doubl = true;
} else {
doubl = false;
}
}
return count;
}
Here is my solution:
public int count8(int n) {
int count = 0;
if(n == 0)
return 0;
if(n % 100 == 88)
{
count = 3;
return count + count8(n/100);
}
else if(n % 10 == 8)
{
count++;
return count + count8(n/10);
}
else
return count8(n/10);
}
However, for the case: count8(88888) → 9, I get 7, and I can't figure out why.
What I also find strange is that a double 8 yields 3 so for the case: count8(8818) → 4 instead of 5, which is what I thought it would be. Hence, why I have count = 3 for the (n % 100 == 88)
Here is my code . The solution to this problem is very simple . I have done it with pure recursion . :)
public int count8(int n) {
if (n==8) return 1;
if (n<10) return 0;
if (n%100==88)
return 2 + count8(n/10);
if (n%10==8)
return 1 + count8(n/10);
return count8(n/10);
}
The catch of the problem is that when a pair of 88 comes total count = 1 + 2 ; 1 for 8 at right and 2 for 8 at left because the previous digit(which is digit at its adjacent right) was also 8 .
So for 88 the total occurances of 8 is equal to 3. For implementing this logic (n%100 ==88) condition is added .
This is the another recursion technique which I have used to solve this problem :-
public int count8(int n) {
int a,b;
if(n==0)
return 0;
a=n%10;
b=(n/10)%10;
if(a==8&&b==8)
return 2+count8(n/10);
else if(a==8&&b!=8)
return 1+count8(n/10);
else
return count8(n/10);
}
This code also works;
public int count8(int n) {
if(n/10 == 0 && n%10 != 8){
return 0;
}
if(n % 10 == 8 && (n/10)%10 == 8){
return 2 + count8(n/10);
}
if(n/10 == 0 && n%10 == 8){
return 1 + count8(n/10);
}
if(n % 10 != 8){
return 0 + count8(n/10);
}else{
return 1 + count8(n/10);
}
}
Here is simple solution
public int count8(int n) {
//base case if n becomes 0 then return 0
if(n==0) return 0;
//checking for two consecutive 8's in a row
if((n%10) == 8 && (n/10)%10 == 8){
return 2 + count8(n/10);
}
else if(n%10 == 8){ // there is only one 8
return 1 + count8(n/10);
}
//no 8 found
return count8(n/10);
}
Here's my solution, albeit the function names aren't nicely named, just think of them as abstract (not in the Java abstract keyword sense) functions that perform their task.
public int count8(int n) {
return g(n, 0);
}
public int g(int n, int prev) {
int rest = n/10;
int digit = n % 10;
if (rest == 0) {
return h(digit, prev);
}
int toAdd = h(digit, prev);
return toAdd + g(rest, digit);
}
public int h(int digit, int prev) {
return prev == 8 && digit == 8 ?
2 : digit == 8 ?
1 : 0;
}

Categories