I did the following to calculate recursive logarithm:(b is the base of log here)
int log(int b, int n) {
if (n/b == 1) {
return 1;
} else {
return log(b, n/b) + 1;
}
}
However, it's wrong.I'm doing it from the openDSA interactive platform.The original question is the following:
For function "log", write the missing base case condition and the recursive call. This function computes the log of "n" to the base "b". As an example: log 8 to the base 2 equals 3 since 8 = 222. We can find this by dividing 8 by 2 until we reach 1, and we count the number of divisions we made. You should assume that "n" is exactly "b" to some integer power.
int log(int b, int n) {
if /* Missing base case condition */ {
return 1;
} else {
return /* Missing a Recursive case action */;
}
}
My code is incorrect.I'm getting infinite recursion.
If the format MUST be like this:
int log(int b, int n ) {
if <<enter base case>> {
return 1;
} else {
return <<enter action case>> ;
}
}
Then the safest method (that I can come up with) would be:
int log(int b, int n ) {
if (n <= b) {
return 1;
} else {
return log(b, n/b)+1 ;
}
}
A better solution in my opinion would be
int log(int b, int n ) {
if (b > n) {
return 0;
} else {
return 1 + log(b, n/b);
}
}
This returns the log base b of n rounded down to an integer, and has more consistency with inexact results than the other answer.
e.g. log(2,6)=2 ; log(2,7)=2 ; log(2,8)=3 ; log(2,9)=3
Though, it still doesn't handle things like b < 2 or cases where the result would be negative.
int log(int b, int n ) {
if (b == 1) {
return b;
} else if (n == 1) {
return 0;
} else {
return 1 + log(b, n/b);
}
}
Related
I had a test exam in java, that almost no one have succeeded in this question and I can't figure out the solution.
The question was like this:
Find the sum of an integer last and first number. For example 1234-->5, 137-->8, 4-->8. You are only allowed to use recursion and no helper function"
I tried various things. Here is my last attempt:
public static int sumOfFirstandLastdigits(int number)
{
int lastdigit=sumOfFirstandLastdigits(number/10);
if(number/10==0)
{
return number%10;
}
return lastdigit+sumOfFirstandLastdigits(number%10);
}
Assuming the input is supposed to be non-negative:
//If n < 0, return first digit of -n
//Otherwise, return sum of first and last digits of n
int sumLastAndFirstDigit(int n) {
if (n < -9)
return sumLastAndFirstDigit(-(-n/10));
if (n <= 0)
return -n;
if (n < 10)
return n+n;
return n%10 + sumLastAndFirstDigit(-(n/10));
}
You can do this by overloading the method and passing the last digit as a second parameter to keep track of it through the recursion without changing the value (AKA Default Parameter):
public static void main(String[] args) {
System.out.println(sumDigits(3891901));
System.out.println(sumDigits(1234));
System.out.println(sumDigits(5678));
}
private static int sumDigits(int i) {
return sumDigits(i, i % 10);
}
private static int sumDigits(int i, int j) {
if (i / 10 == 0) {
return i % 10 + j;
}
return sumDigits(i / 10, j);
}
Output:
4
5
13
This thread on default parameters might help learn more as well.
Found a solution using String, not sure it's the best :
public int sumLastAndFirstDigit(Integer firstDigit, int number) {
String numberAsString = String.valueOf(number);
//Set the first digit
if(firstDigit == null) {
firstDigit = Integer.valueOf(numberAsString.substring(0,1));
//If there is only one digit in number for the first loop, then return 2 x firstDigit
if(numberAsString.length() == 1) {
return 2 * firstDigit;
}
}
//Remove the first digit to create the new number
String newNumberAsString = numberAsString.substring(1);
Integer newNumber = Integer.valueOf(newNumberAsString);
if(newNumberAsString.length() == 1) {
//When it's the last digit, sum first and last
return firstDigit + newNumber;
}
return sumLastAndFirstDigit(firstDigit, newNumber);
}
Then do :
sumLastAndFirstDigit(null,1234);
sumLastAndFirstDigit(null,137);
sumLastAndFirstDigit(null,4);
Use the sign as a flag to recognize the initial call. Only works with positive numbers, of course.
public static int sum(int value){
if(value > 0)
// initial call
return value % 10 + sum(-value);
else
// recursive call
return -value < 10 ? -value : sum(value / 10);
}
This are the 2 different solutions my professor suggested, although he said no helper (the first one is without an helper).
public static int sumFirstAndLast2(int num) {
if (num < 10 )
return num+num;
return sumFirstAndLast2(num/10) - num%100/10 + num%10;
}
public static int sumFirstAndLast(int num) {
if ( num < 10 )
return num+num;
return sumFirstAndLastHelper(num,true);
}
private static int sumFirstAndLastHelper(int num, boolean isLast) {
if ( isLast )
return num%10 + sumFirstAndLastHelper(num/10,false);
if ( num < 10 )
return num;
return sumFirstAndLastHelper(num/10,false);
}
The task is to implement a program which counts how many different Sums of Primes there are for a given number sumtoBreak.
The Method primeSum should subtract all possible primes currprime from the number sumtoBreak until the sumtoBreak becomes zero and then return (in sum) a one for each possibilty. To account for all possibilities, in each recession step, it calls itself
with sumtoBreak - currprime plus
calls itself with the nextPrime.
My Problem is that java won't return anything unless the sumtoBreak is zero right at the beginning.
Would be glad for any advice!
Here's the code (I know that the parenthesis in the code with the nested if statements are redundant, but I just wanted to make sure, that's not the problem):
Here's the fixed code:
public class PrimeSum {
public static boolean isPrime(int primecandidate) {
int count = 0;
for (int i = 2; i <= primecandidate / 2; i++) {
if (primecandidate % i == 0)
count++;
}
if (count == 0)
return true;
else
return false;
}
public static int nextPrime(int currprime) {
int j = currprime + 1;
while (!isPrime(j))
j++;
return j;
}
public static int primeSum(int sumtoBreak, int currprime) {
if (sumtoBreak == 0) {
return 1;
} else {
if (sumtoBreak < 0 || currprime > sumtoBreak) {
return 0;
} else {
return primeSum(sumtoBreak, nextPrime(currprime)) + primeSum(sumtoBreak - currprime, currprime);
}
}
}
public static void main(String[] args) {
System.out.println(primeSum(Integer.parseInt(args[0]), 2));
}
}
This doesn't answer your question, but corrects an error in your isPrime Method and computes the result much faster:
private static boolean isPrime(final int primecandidate) {
if ( primecandidate < 2) { // 0 & 1 are NOT Prime
return false;
}
if ((primecandidate & 0x1) == 0) { // Even is NOT Prime...
return primecandidate == 2; // ...except for 2 (and 0).
}
for (int i = 2, iMax = (int) Math.sqrt(primecandidate); i <= iMax; i++) {
if (primecandidate % i == 0) {
return false;
}
}
return true;
}
Note the following:
the final argument primecandidate is marked final
it corrects the result for 0 & 1 to false
the method is marked private
the iMax is Sqrt(primecandidate) & not primecandidate / 2
iMax is calculated once, instead of every iteration
I use a strategy I call "if you're done, be done."
Meaning: don't set a flag (in your case count), just get out!
Please note also, there is an apache commons Math3 function...
org.apache.commons.math3.primes.Primes.isPrime(j)
It is significantly slower for smallish values (<= Short.MAX_VALUE)
It is somewhat faster for largeish values (ca. Integer.MAX_VALUE)
There is also a BigInteger.isProbablePrime(...) function, but my Benchmark suggests it is rather slow.
I hope this helps a little?
Some things you might have missed:
in a function, a return statement terminates (break) the function immediatly. So in
if(...) { return ...; }
else {...}
→ else is redundant, as if the condition is true, the function is already terminated (break)
Something like a==0 has a boolean value (true or false). So
if(count==0) { return false; }
else { return true;}
can be shortened to return count!=0;
I recommend to always use braces, because something like if(i==0) ++i; break;, means if(i==0) {++i;}. break; will be called in any case.
public static boolean
isPrime(int n)
{
if(n==0 || n==1) { return false; }
for(int i= 2; i <= n/2; ++i)
{
if(n%i == 0) { return false; } //we know, n is not a prime,
//so function can break here
}
return true; //since for all values of i, the function did not break,
//n is a prime
}
I wish you a lot of motivation to code for the future!
I had an interview the other day that asked the question, loop through the numbers from 0 to 100 and print out every third number. This is a very easy question if you know what the modulo function is. So I came up with the solution (Note I was using Java):
for (int i=0; i<100; i++) {
if (i % 3 == 0) {
System.out.println(i);
}
}
He then asked, what if you can't use division or the modulo function. So I had to think about this for about 30 seconds, and came up with a solution, that I knew was very inefficient, and let him know it was very inefficient, but would work.
int x = 3;
for (int i=0; i<100; i++) {
for (int j=0; j<33; j++) {
if (x*j==i) {
System.out.println(i);
break;
}
}
}
I'm free writing this without testing, so it might not work 100%, but you get the idea of how I solved the problem. He said he understood what I was trying to do. He then said that there is another way to do it using a recursive function. He tried to briefly explain it to me, but I didn't understand how you could use a recursive function to solve this problem. Can anyone come up with a solution using recursion?
EDIT:
Thanks for all the answers! I didn't think this question would attract as much attention as it did, but I appreciate all the answers. Some of you didn't understand that you can ONLY increment by 1. So you must loop through every natural number from 0 to 100.
There is a cool trick to test if a number is divisible by three. If the sum of all its digits is divisible by three, then the original is divisible by three. This can be applied recursively: if I have a number a, I can add all the digits of a together to get b and see if b is divisible by 3. How do I know if b is divisible by three? Add all of its digits together to get c and see if c is divisible by three...
As with all recursion, you have to stop at some point. The base case is when you have a sum which is only one digit long- you can have a list of digits divisible by three and check against these. In code:
public boolean printDivisibleByThrees(){
for(int i=0; i<100; i++){
if(isDivisibleByThree(i)){
System.out.println(i);
}
}
}
public boolean isDivisibleByThree(int i){
if(i<0){
i = -1*i; //we only care about the absolute value of i
}
if(Arrays.asList(0,3,6,9).contains(i)){
return true;
} else if(i<10){
return false; //one digit number not divisible by three
} else {
int j = sumDigits(i);
return isDivisibleByThree(j);
}
}
public int sumDigits(int i){
String iString = (new Integer(i)).toString();
int sum = 0;
for(char digit : iString.toCharArray()){
sum += (new Integer(digit+"")).intValue();
}
return sum;
}
As no answer has been picked yet I like to add my two cents here.
Since the trick is do the modulo function with recursion and without division (as I understood) here is my solution:
public static void main(String[] args) {
for ( int i = 1; i <=100; i++ ){
if ( mod(i, 3) ){
System.out.println(i);
}
}
}
public static boolean mod(int a, int b){
if ( a < 0 ){
return false;
}else if (a==b){
return true;
}else{
return mod( a-b, b );
}
}
EDIT
This version will handle division by 0 and negative numbers on the modulo function:
public static boolean mod(int a, int b){
if ( b < 0 ){
b=b*-1;
}
if ( a < 0 || b == 0){
return false;
}else if (a==b){
return true;
}else{
return mod( a-b, b );
}
}
Use a second parameter that will keep if the number is or not the third
public class Rec
{
public static void rec(int n, int t) {
if(t==3) {
System.out.println(n);
t=0; // reset it
}
if(n!=100) {
rec(++n, ++t);
}
}
public static void main (String[] args)
{
rec(0, 3);
}
}
One can define the modulus operator using recursion as follows:
// Assume a, b > 0
static int mod(a, b) {
if (a < b) {
return a;
} else {
return mod(a-b, b);
}
}
So then you could do:
for (int i=0; i<100; i++) {
if (mod(i, 3) == 0) {
System.out.println(i);
}
}
I want to add one more answer that is probably unusual, but works fine for each range.
The code is C++ (I'm from mobile and I've only a C++ compiler on it), but it is quite easy to understand and to rewrite in Java.
#include <iostream>
void foo(int c, int n) {
static int i = 0;
if(c >= n) return;
switch(i++) {
case 1:
case 2:
foo(++c, n);
break;
case 0:
case 3:
std::cout << c << std::endl;
i = 1;
foo(++c, n);
}
}
int main() {
foo(0, 100);
}
Another variation on the recursion (JavaScript code):
function f(m,i){
if (i == 100){
return;
} else if (i == 3*m){
console.log(i);
f(m + 1,i + 1);
} else {
f(m,i + 1);
}
}
f(0,0);
Why not just do:
for (int i = 0; i < 100; i += 3)
System.out.println(i);
This way you don't have to check if it is every third number, because it goes up by 3 each time.
void printNth(int max, int n, int i, int sinceLastPrinted) {
if (i>max) {
return;
}
if (sinceLastPrinted == n-1) {
System.out.println(i);
sinceLastPrinted = -1;
}
printNth(max, n, i+1, sinceLastPrinted+1);
}
printNth(100, 3, 0, 0);
It's also not 100% clear whether the last number (100 in the example) should be included (if it is "a 3rd number"), depending on that you might need to modify to:
if (i>=max) {
And also not very clear where to start the "every 3rd"? 0, 3, 6, or 2, 5, 8? The advantage of my function is that this can be easily modified by passing different value for i
This would work. !
public class Recursion {
public static void main(String[] args) {
myRecursiveMethod(0,1,100,3);
}
public static void myRecursiveMethod(int begin,int temp,int end,int n)
{
if(begin<=end)
{
if(temp==n)
{
System.out.println(begin);
temp=0;
}
myRecursiveMethod(++begin,++temp,end,n);
}
}
}
public class A4work
{
private static int fibonacci(int n) {
if (n <= 1) {
return n;
}
{
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
private static boolean isAfibonacci(int a) {
int x = 0; //sequence number
int c = 0; //number in fib sequence
while (a <= c) {
c = fibonacci(x);
x++;
}
if (a == c) {
return true;
} else {
return false;
}
}
public static void main(String[] args) //called a method signiture
{
System.out.println("The 5th Square pyramidal number is " + isAfibonacci(3));
}
}
I think I have the code right, but it keeps on returning false. I'm using it to decide if a number is in the fib sequence or not.
Thanks for the help
When you use System.out.println("The 5th Square pyramidal number is "+ isAfibonacci(3) );, a in your isAfibonacci(); method becomes 3. Now look at your code knowing that.
while(3 <= 0) //replaced a with 3 here and c with 0 for visualization
{
...
}
A non-negative, non-zero integer will never be less than or equal to 0, therefore, will always result in false.
If your input a is 5, for example, you will have:
int c = 0; //number in fib sequence
while (a <= c) { ... }
The while loop will never run since 5 <= 0 is false. So a == c will always be false for any a greater than zero.
I think you want to stop iterating when c is greater than or equal to a, so the correct condition would be
while (c < a) { ... }
How would I go about using recursion to calculate the probability of rolling a certain number, r, with a given number of dice? I tried to treat this as a choose problem but am still quite confused as to how the algorithm should work.
For example, it should work out to be something like this:
P(4,14)=(1/6)P(3,13)+(1/6)P(3,12)+(1/6)P(3,11)+(1/6)P(3,10)+(1/6)P(3,9)+(1/6)P(3,8)
P(3,8)=(1/6)P(2,7)+(1/6)P(2,6)+(1/6)P(2,5)+(1/6)P(2,4)+(1/6)P(2,3)+(1/6)P(2,2)
P(2,4)=(1/6)P(1,3)+(1/6)P(1,2)+(1/6)P(1,1)+(1/6)P(1,0)+(1/6)P(1,-1)+(1/6)P(1,-2)
=(1/6)(1/6)+(1/6)(1/6)+(1/6)(1/6)+(1/6)(0)+(1/6)(0)+(1/6)(0)
I'm just having trouble converting it into code.
static double P(int dice, int r) {
int ret = 1;
for (int i = 2; i < 7; i++) {
ret = (1/6)(ret*(dice-i))/(i+1);
}
return ret;
}
static double RollDice(int dice,int r) {
if (dice==1 && (r<1 || r>6)){
return 0;
}
if (dice==1 && (r>=1 && r<=6)){
return (1.0/6);
}
else {
return ((1.0/6)*P(dice-1,r-1));
}
I do not understand why you have to separate methods P() and RollDice(), since in your formulae you (correctly) describe everything with P.
If you were to put your formulae into code, it should look something like this:
EDIT: changed the base case to 0 dice, since then it becomes even simpler.
static double P(int dice, int r) {
if (dice == 0) {
// Zero dice: probabiliy 1 to get 0
if (r == 0) {
return 1.0;
} else {
return 0.0;
}
else {
// Multiple dice: recursion
double sum = 0.0;
for (/* TODO */) {
sum += //TODO
}
}
}
For the recursion part, try working it out by looking at the formula:
P(4, 14) = (1/6)P(3, 13) + (1/6)P(3, 12) + ... + (1/6)P(3, 8)
i.e. in the general case
P(dice, r)=(1/6)P(dice-1, r-1) + (1/6)P(dice-1, r-2) + ... + (1/6)P(dice-1, r-6)
meaning that you have to loop from r-6 to r-1.
And since you are taking a sum over multiple recursive calls, you have to use an accumulator initialized to 0. (The variable I called sum)
EDIT: Click here for a complete example, compare to WolframAlpha to verify the result.