count number of digit using recursive method - java

Given a non-negative int n, compute recursively (no loops) 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 that mod (%) by 10 yields the rightmost digit (126 % 10 is 6), while divide (/) by 10 removes the rightmost digit (126 / 10 is 12).
count8(8) → 1
count8(818) → 2
count8(8818) → 4
my program seems not able to count double '8's. Here's the code.
public int count8(int n) {
boolean flag = false;
if(n<10)
{
if (n==8)
{
if(flag == true)
return 2;
else
{
flag = true;
return 1;
}
}
else
{
flag = false;
return 0;
}
}
else
return count8(n%10)+count8(n/10);
}
I was wondering if the last line goes wrong but I don't know how to check it. Looking forward to your help. Thanks!

Pass the state (is the previous digit eight) to the method:
private static int count8(int n, boolean eight) {
if (n <= 0)
return 0;
else if (n % 10 == 8)
return 1 + (eight ? 1 : 0) + count8(n / 10, true);
else
return count8(n / 10, false);
}
public static int count8(int n) {
return count8(n, false);
}

Your flag variable is only local. There's only one time you read it: if (flag == true) and since you never change it's value before that it will always be false.
You make this a lot more complicated than it has to be though. No need for an additional parameter at all.
public int count8(int n)
{
if (n % 100 == 88) return count8(n/10) + 2;
if (n % 10 == 8) return count8(n/10) + 1;
if (n < 10) return 0;
return count8(n/10);
}

You can try smth like this:
public int count8(int n) {
if (n < 10)
return n == 8: 1 ? 0;
int count = 0;
String num = Integer.toString(n);
int numLength = num.length();
if (numLength % 2 != 0)
num += "0";
if ((num.charAt(numLength / 2) == num.charAt(numLength / 2 - 1)) && (num.charAt(numLength / 2) == "8"))
count++;
String left = num.substring(0, numLength / 2);
int leftInt = Integer.parseInt(left);
String rigth = num.substring(numLength / 2);
int rigthInt = Integer.parseInt(rigth);
return count + count8(leftInt) + count8(rigthInt);
}

C++
int count8(int n) {
return n == 0 ? 0 : (n % 10 == 8) + (n % 100 == 88) + count8(n/10);
}
Java & C#
int count8(int n) {
if (n==0) return 0;
if(n % 100 == 88)
return 2 + count8(n / 10);
if(n % 10 == 8)
return 1 + count8(n / 10);
return count8(n / 10);
}

Related

Coding challenge: Solution debugging

A picture of code and test cases:
This is the problem:
Given a non-negative number "num", return true if num is within 2 of a multiple of 10. Note: (a % b) is the remainder of dividing a by b, so (7 % 5) is 2. See also: Introduction to Mod
My code fails nearTen(1) for some reason. please open the picture for details.
public boolean nearTen(int num) {
if (num < 8)
return false;
if (num % 10 == 0)
return true;
while (num / 10 != 0) {
num = num - 10;
}
if (num == 8 || num == 9 || num == 1 || num == 2)
return true;
return false;
}
public boolean nearTen(int num) {
if(num < 8) {
return false;
} else if(num % 10 == 0) {
return true;
}
while(num / 10 != 0) {
num = num - 10;
}
if(num == 8 || num == 9 || num == 1 || num == 2) {
return true;
}
return false;
}
this is your code, but in first if condition you are doing
if(num < 8)
return false
//so 100% you will fail case => input is 1
And your logic has some issues. Instead of using "/", we can use "%". Reason is you only consider number multiplied by 10.
for example:
1 / 11 / 21 / 111 / 555551 / 1000001 => last digit is 1
2 / 12 / 122 / 12342 / 5124512 / 1000002 => last digit is 2
for all those numbers we can ignore previous digits, and only consider last digit. Because previous digits are numbers used to multiply 10.
so this answer can be simplified to following code
public boolean nearTen(int num) {
if(num < 0) {
return false;
}
num %= 10;
return num == 8 || num == 9 || (num >= 0 && num <= 2);
}

In If condition explanation

Given a signed 32-bit integer x, return x with its digits reversed. If reversing x causes the value to go outside the signed 32-bit integer range [-231, 231 - 1], then return 0.
In this code I want to know about (rev == Integer.MAX_VALUE / 10 && pop > 7) and (rev == Integer.MIN_VALUE / 10 && pop < -8)
Why do they use pop>7 and pop<-8?
class Solution {
public int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
rev = rev * 10 + pop;
}
return rev;
}
}
class Solution {
public int reverse(int x) {
int ans=0;
while(x!=0)
{
int digit=x%10;
if( (ans>Integer.MAX_VALUE/10) || (ans<Integer.MIN_VALUE/10) )
{
return 0;
}
ans=(ans*10)+digit;
x=x/10;
}
return ans;
}
public void main(String[] args)
{
int x=120;
System.out.print("Reversed Number is "+ reverse(x));
}
}
-2147483648 to 2147483647 signed integer range if condition true when the rev integer is equal to maximum integer value ,rev==(2147483647) and the last digit of given integer is greater then 7 than only enters in the if condition return 0.
same as above next if also do check the same condition with (-2147483648).

Take the frequency of each digit in a randomly generated number with while loops and if statements

This is in java. I am trying to write a method that randomly generates a number 1000000 - 2000000, then takes the frequency of each digit. We cannot use arrays or for loops.
For example, if the number is 1880500, the output would be:
(1, 1), (8, 2), (5, 1), (0, 3).
However, my output looks like this: (1, 1), (8, 2), (8, 1), (0, 3), (0, 2), (5, 1), (0, 1).
So my problem is that I don't know how to stop a digit from printing twice if that digit was already printed. Thanks
This is my code for the method:
int num = 1000000 + (int)(Math.random() * (2000000 - 1000000 + 1));
System.out.println("The generated number is: " + num);
int oneDigit = num % 10;
while (num > 0) {
int oneDigitCount = 0;
int num2 = num;
while (num2 > 0) {
if (num2 % 10 == oneDigit) {
oneDigitCount++;
}
num2 /= 10;
}
if (num < 10 && oneDigit != newDigit) {
System.out.printf("(%d, %d)", oneDigit, oneDigitCount);
}
else {
System.out.printf("(%d, %d), ", oneDigit, oneDigitCount);
}
num /= 10;
oneDigit = num % 10;
You're currently parsing your number n times, where n is the number of digits. So, if the number is 1880500, you're counting the number of 0's in 1880500, then you're counting the number of 0's in 188050, then you're counting the number of 5's in 18805, then the number of 0's in 1880, etc.
Since you apparently can't use arrays, maps, or for loops, we need a slightly different approach. Fortunately, since we're dealing with a known set of digits, we can kind of invert the logic here. Instead of getting the digits from the number itself (which is ultimately what's causing the duplication), we can use a while loop to loop through the digits 0 - 9, and look for them in the original number.
int num = 1000000 + (int) (Math.random() * (2000000 - 1000000 + 1));
System.out.println("The generated number is: " + num);
int i = 0;
while (i < 10) {
int count = 0;
int temp = num;
while (temp > 0) {
int digit = temp % 10;
if (digit == i) {
count++;
}
temp /= 10;
}
if (count > 0) {
System.out.printf("(%d, %d), ", i, count);
}
i++;
}
You'll notice that this is essentially identical to a for loop. For the most part, loops are loops, and the distinction between while and for loops is just a convenience.
Converting your random number to a String, we are able to get the character in that string and count how many times the character appears then remove it from the string. Loop through the string until there are no characters left.
public void printFrequency(int number) {
//convert the number to a string
String numString = String.valueOf(number);
//loop until the string length is replaced
while (numString.length() > 0) {
// get the first "character" in the string
String char1 = String.valueOf(numString.charAt(0));
//check to see how many of the characters were replaced with empty
int count = numString.length() - numString.replaceAll(char1, "").length();
//print
System.out.println(String.format("(%s, %d)", char1, count));
//trim the string
numString = numString.replaceAll(char1, "");
}
}
Output
(1, 1)
(8, 2)
(0, 3)
(5, 1)
I think, in general, it's better to create a method and retrieve a String as a result instead of using System.out. In case you have restrictions, just be simple:
public static String calc(int num) {
int zero = 0;
int one = 0;
int two = 0;
int three = 0;
int four = 0;
int five = 0;
int six = 0;
int seven = 0;
int eight = 0;
int nine = 0;
while (num > 0) {
int n = num % 10;
if (n == 0)
zero++;
else if (n == 1)
one++;
else if (n == 2)
two++;
else if (n == 3)
three++;
else if (n == 4)
four++;
else if (n == 5)
five++;
else if (n == 6)
six++;
else if (n == 7)
seven++;
else if (n == 8)
eight++;
else
nine++;
num /= 10;
}
StringBuilder buf = new StringBuilder();
if (zero > 0)
buf.append("(0,").append(zero).append("),");
if (one > 0)
buf.append("(1,").append(one).append("),");
if (two > 0)
buf.append("(2,").append(two).append("),");
if (three > 0)
buf.append("(3,").append(three).append("),");
if (four > 0)
buf.append("(4,").append(four).append("),");
if (five > 0)
buf.append("(5,").append(five).append("),");
if (six > 0)
buf.append("(6,").append(six).append("),");
if (seven > 0)
buf.append("(7,").append(seven).append("),");
if (eight > 0)
buf.append("(8,").append(eight).append("),");
if (nine > 0)
buf.append("(9,").append(nine).append("),");
if (buf.length() > 0)
buf.setLength(buf.length() - 1);
return buf.toString();
}
Demo. Buy the way, you have a sorted result.
System.out.println(calc(1880500)); // (0,3),(1,1),(5,1),(8,2)

Miller-Rabin Primality Test Often Returns Composite for Prime Numbers

I have been trying to implement a Miller-Rabin primality test from scratch (only primitives and Strings) that works for 64 bit integers (longs). I've tried the Java and pseudocode from Wikipedia, as well as various other websites. So far, only very small numbers have worked correctly. Most numbers are incorrectly marked composite, such as 53 or 101. I have tried tracking various sections of the code to see where the problem is. It seems to be in the innermost loop. I don't know what the specific issue is. Any help is appreciated. Thanks!
Here is my code:
public class PrimeTest
{
public static void main(String[] args)
{
PrimeTest app = new PrimeTest();
}
private PrimeTest()
{
long n = 53; // Change to any number. 53 is prime, but is reported as composite
if (checkPrime(n, 10))
{
System.out.println(n + " is prime.");
}
else
{
System.out.println(n + " is not prime.");
}
}
// Check if n is prime with 4^(-k) change of error
private boolean checkPrime(long n, int k)
{
// Factor n-1 as d*2^s
long d = n - 1;
int s = 0;
while (d % 2 == 0)
{
d /= 2;
s++;
}
// Repeat k times for 4^-k accuracy
for (int i = 0; i < k; i++)
{
long a = (long) ((Math.random() * (n - 3)) + 2);
long x = modPow(a, d, n);
if (x == 1 || x == (n - 1))
{
continue;
}
int r;
for (r = 0; r < s; r++)
{
x = modPow(x, 2, n);
if (x == 1)
{
return false;
}
if (x == (n - 1))
{
break;
}
}
if (r == s)
{
return false;
}
}
return true;
}
// Return (base^exp) % mod
private long modPow(long base, long exp, long mod)
{
if (mod == 1)
{
return 0;
}
long result = 1;
base = base % mod;
while (exp > 0)
{
if ((exp & 1) == 0)
{
result = (result * base) % mod;
}
exp = exp >> 1;
base = (base * base) % mod;
if (base == 1)
{
break;
}
}
return result;
}
}
This line in modPow:
if ((exp & 1) == 0)
is wrong and should instead be
if ((exp & 1) == 1)

Writing A Recursive Function That Counts Zeros

It is possible to count the number of zeros in an integer through a recursive method that takes a single int parameter and returns the number of zeros the parameter has.
So:
zeroCount(1000)
Would Return:
3
You can remove the last digit from an integer by doing: "12345 / 10" = 1234
You can get the last digit from an integer by doing: "12345 % 10" = 5
This is what I have so far:
public static int zeroCount(int num)
{
if(num % 10 == 0)
return num;
else
return zeroCount(num / 10);
}
Does anyone have any suggestions or ideas for helping me solve this function?
public static int zeroCount(int num)
{
if(num == 0)
return 0;
if(num %10 ==0)
return 1 + zeroCount(num / 10);
else
return zeroCount(num/10);
}
this would work
Run through your code in your head:
zeroCount(1000)
1000 % 10 == 0, so you're going to return 1000. That doesn't make sense.
Just pop off each digit and repeat:
It sounds like homework, so I'll leave the actual code to you, but it can be done as:
zeroes(0) = 1
zeroes(x) = ((x % 10 == 0) ? 1 : 0) + zeroes(x / 10)
Note that without the terminating condition, it can recurse forever.
There are three conditions here:
1. If number is single digit and 0 , then return 1
2. If number is less than 10 i.e. it is a number 1,2,3...9 then return 0
3. call recursion for zeros(number/10) + zeros(n%10)
zeros(number){
if(number == 0 ) //return 1
if(number < 10) //return 0
else
zeros(number/10) + zeros(number%10)
}
n/10 will give us the n-1 digits from left and n%10 gets us the single digit.
Hope this helps!
Check this out for positive integers:
public static int zeroCount(int number) {
if (number == 0) {
return 1;
} else if (number <= 9) {
return 0;
} else {
return ((number % 10 == 0) ? 1 : 0) + zeroCount(number / 10);
}
}
it is a simple problem and you don't need to go for recursion
I think a better way would be converting the integer to a string and check for char '0'
public static int zeroCount(int num)
{
String s=Integer.toString(num);
int count=0;
int i=0;
for(i=0;i<s.length;i++)
{
if(s.charAt(i)=='0')
{
count++;
}
}
return count;
}
You have to invoke your recursive function from both if and else. Also, you were missing a Base Case: -
public static int zeroCount(int num)
{
if(num % 10 == 0)
return 1 + zeroCount(num / 10);
else if (num / 10 == 0)
return 0;
else
return zeroCount(num / 10);
}
import java.util.*;
public class Count
{
static int count=0;
static int zeroCount(int num)
{
if (num == 0){
return 1;
}
else if(Math.abs(num) <= 9)
{
return 0;
}
else
{
if (num % 10 == 0)
{ // if the num last digit is zero
count++;
zeroCount(num/10);
} // count the zero, take num last digit out
else if (num%10 !=0){
zeroCount(num/10);
}
}
return count;
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.print("Input: ");
int num = sc.nextInt();
System.out.println("Output: " +zeroCount(num));
}
}
public static int count_zeros(int n)
{
if(n<=9)
{
if(n==0)
{
return 1;
}
else
{
return 0;
}
}
int s=n%10;
int count=0;
if(s==0)
{
count=1;
}
return count+count_zeros(n/10);
}
int countZeros(int n){
//We are taking care of base case
if(n<=9){
if(n==0){
return 1;
}
else
{
return 0;
}
}
int last=n%10; //last element of number for e.g- 20403, then last will give 3
int count=0; //Initalsizing count as zero
if(last==0){ //We are checking either the last digit is zero or not if it will
will update count from 0 to 1
count=1;
}
return count+countZeros(n/10); //Recursive call
}
int check(int n){
if(n==0)
return 1;
return 0;
}
int fun(int n)
{
if(n/10==0)
{
if(n==0){
return 1;
}
else{
return 0;
}
}
return check(n%10)+fun(n/10);
}
Check this out, this is the solution I came up with.
int countZeros(int input){
//base case
if(input == 0){
return 1;
}
int count = 0;
int lastDigit = input%10;
if(lastDigit == 0){
count = 1;
}
//calc the smallInput for recursion
int smallInput = input/10;
//set smallAns = 0, if i/p itself is not 0 and no 0 is present then return smallAns = 0
int smallAns = 0;
//recursion call
if(smallInput != 0){
smallAns = countZerosRec(smallInput);
}
//if we get lastDigit = 0 then return smallAns + 1 or smallAns + count, else return smallAns
if(lastDigit == 0){
return smallAns+count;
}
else{
return smallAns;
}}
You know that x % 10 gives you the last digit of x, so you can use that to identify the zeros. Furthermore, after checking if a particular digit is zero you want to take that digit out, how? divide by 10.
public static int zeroCount(int num)
{
if(num == 0) return 1;
else if(Math.abs(num) < 9) return 0;
else return (num % 10 == 0) ? 1 + zeroCount(num/10) : zeroCount(num/10);
}
I use math.Abs to allow negative numbers, you have to import java.lang.Math;
static int cnt=0;
public static int countZerosRec(int input) {
// Write your code here
if (input == 0) {
return 1;
}
if (input % 10 == 0) {
cnt++;
}
countZerosRec(input / 10);
return cnt;
}
CPP Code using recursion:
int final=0;
int countZeros(int n)
{
if(n==0) //base case
return 1;
int firstn=n/10;
int last=n%10;
int smallop=countZeros(firstn);
if(last==0)
final=smallop+1;
return final;
}
int countZeros(int n)
{
if(n==0)
{
return 1;
}
if(n<10) // Needs to be java.lang.Math.abs(n)<10 instead of n<10 to support negative int values
{
return 0;
}
int ans = countZeros(n/10);
if(n%10 == 0)
{
ans++;
}
return ans;
}
public static int countZerosRec(int input){
// Write your code here
if(input == 0)
return 1;
if(input <= 9)
return 0;
if(input%10 == 0)
return 1 + countZerosRec(input/10);
return countZerosRec(input/10);
}

Categories

Resources