I have to check whether a number is an Armstrong number or not, using a recursive method.
public class ArmStrong {
public static void main(String[] args) {
System.out.println(isArm(407, 0, 0));
}
static boolean isArm(int n,int last,int sum) {
if (n <= 0 ) {
if (sum == n) {
return true;
} else {
return false;
}
}
return isArm(n / 10, n % 10,sum + last * last * last);
}
}
When I debug, in the last call of isArm when n is 4, the base statement is skipped.
Your code will instantly jump to the answer (if (n <= 0)) before applying the cube of the last digit.
For example, trivially, let's try 9, which obviously isn't armstrong.
Your code will first check if 9 is 0 - it's not. So, we recurse, which will go with self(0, 9, 0+0). The next run is supposed to then recurse once more, so that the sum + last*last*last can actually get some cubing done. But it'll never get there - n is 0, so, you jump into the if.
As your variable name kinda gives away last is referring to the digit that the previous run lopped off, and yet you aren't cubing it.
The solution is to simply get the cubing in before checking if n is null:
The first thing your method should do is
sum += last*last*last;
Then, the second problem shows up: This correctly calculates your sum to be 407, but you check this against n, which is, obviously, 0 - you are 'destroying' n as you go through. One trivial way to solve that is to pass the original n, unmolested, through, as a 4th parameter. I'll leave that as an exercise for the reader.
Although #rzwitserloot has pointed at an issue which is rooted in the way you've designed the recursion, the problem is still not resolved.
Yes, the recursive calls go "one step ahead" the calculation of the sum of digits, which happens in the Recursive case, and the left-most digit of the given number doesn't contribute the sum, since n is zero and recursion hits the Base case. That's true, but it's not the only thing you need to fix.
Here's the definition of so-called Narcissistic numbers (aka Armstrong numbers):
In number theory, a narcissistic number (also known as a pluperfect digital invariant (PPDI), an Armstrong number (after Michael F. Armstrong)or a plus perfect number) in a given number base b b is a number that is the sum of its own digits each raised to the power of the number of digits.
Therefore, a method with hard-coded power of 3 is capable to validate only three-digit Armstrong numbers. There are only few of them, for other valid Armstrong numbers it would produce an incorrect result.
So, before calculating the sum you need to know the numbers of digits there's no workaround. If you want to address the problem only by using Recursion, the numbers of digits can be also calculated recursively. If we take this route, the solution boils down to implementing two recursive methods.
That's how it might look like:
public static boolean isArm(int n) {
return n == getSum(n, getDigitCount(n));
}
public static int getSum(int n, int power) {
return n == 0 ? 0 : (int) Math.pow(n % 10, power) + getSum(n / 10, power);
}
public static int getDigitCount(int n) {
return n == 0 ? 0 : 1 + getDigitCount(n / 10);
}
main()
public static void main(String[] args) {
System.out.println(isArm(10)); // is not an Armstrong number
System.out.println(isArm(21)); // is not an Armstrong number
System.out.println(isArm(407)); // is an Armstrong number
System.out.println(isArm(153)); // is an Armstrong number
System.out.println(isArm(9)); // is an Armstrong number
}
Output:
false // 10
false // 21
true // 407
true // 153
true // 9
Related
class Generate // to print all numbers from 1000 to 9999 whose digits are in ascending order
{
private boolean order(int n, int i) // checks if the digits of given number are in ascending order
{
if (n == 0) return true;
if (n % 10 < i) return (order(n / 10, n % 10));
return false;
}
void show(int n) // recursive function to generate numbers from 1000 to 9999
{
if (n > 9999) // base case for recursor
System.out.print("");
else
{
if (order(n, 10)) // if digits are in ascending order, prints the number
System.out.println(n);
show(n + 1); // recursive call
}
}
}
The above code was supposed to print all numbers from 1000 to 9999. Code compiled and run but received a runtime exception: java.lang.StackOverflowError: null. Would a try-catch block fix my problem? This is my first time posting here hence I am not familiar with the question etiquette, please correct me if I'm wrong.
Java (and most of the programming languages) provides finite number of memory slot to be used for stack-frame, when your program/code reaches that limit it throws the StackOverFlow error.
In your case, your program reaches that limit before coming to base condition.
My take on this -
Do not use Recursive approach until and unless you are splitting your problem into acceptable sub-problems.
this shows you how you can increase stack-frame-size to be used by the JVM for a particular thread.
In my opinion StackOverFlow is due to double recursion i.e both show(), and order() are recursive... I think show() does not need to be recursive. modified your code as under:
public static void main(String[] args) {
/
new Generate().show(); // added main function to get output or exception.. you can omit it and call Generate().show() at the point u require.
}
}
class Generate//to print all numbers from 1000 to 9999 whose digits are in ascending order
{
private boolean order(int n, int i)//checks if the digits of given number are in ascending order
{
if(n==0)
return true;
if(n%10<i)
return(order(n/10,n%10));
return false;
}
void show()//function to generate numbers from 1000 to 9999 - WITHOUT Recursion
{
int n = 1000;
while(n<=9999)
{ if(order(n,10))//if digits are in ascending order, prints the number
System.out.println(n);
n++;
}
}
}
and here is output: (showing first 7 iterations only)
1234
1235
1236
1237
1238
1239
1245 .......
I'm currently stuck on one line of code that I'm not fully understanding.
So, I'm reading example codes from the book, and one of "programs" used recursion to determine the number of digits in an integer n. The one line of code that I got stuck at and do not fully understand is:
if (number >= 10) {
return numberOfDigits(number / 10) + 1;
For an example, this makes the number 42 return 2, which it's supposed to do. But how exactly does the function return 2? 42 divided by 10 is equal to 4,2 or 4. That plus 1 is 5, so how does it return 2?
Recursion is a way to get one call of the method to perform some of the work, while deferring the remainder of the work to making another recursive call. Here, a "number of digits" recursive method says that the number of digits in a number is equal to 1 for the last digit plus the number of digits remaining after the last digit is removed.
In the return statement, the + 1 counts the last digit in the number, while number / 10 performs truncating integer division to remove the last digit. The recursive call counts the digits in the number with the last digit removed.
What you haven't shown is the base case of the recursion, when the number is single-digit (not greater than or equal to 10). That is simply 1 digit. The value 4 is not figured into the calculation. The method effectively counts the digits, one at a time, until there are no more digits left. There is one recursive method call per digit.
The full method probably looks something like this:
public int numberOfDigits(int number) {
if (number >= 10) {
return numberOfDigits(number / 10) + 1;
}
// base case: only one digit
return 1;
}
By inspection, if we pass a two digit number, the if statement will be hit, which will return whatever the recursive call of the input / 10 is, plus one. Let's say the input were 42. In this case, it would return numberOfDigits(42 / 10) + 1. We know that numberOfDigits(4) returns 1, so this would return a total of 2, which is correct.
Using inductive reasoning, we can build up to convince ourselves of any number of arbitrary length.
Side note: In my travels, I have more often seen the base case handled first using an if statement, with the inductive case happening by default. So, I would have expected to see this code:
public int numberOfDigits(int number) {
if (number < 10) return 1;
return numberOfDigits(number / 10) + 1;
}
I've been searching for the source code of this game and found this one. However, I didn't understand the hasDupes method at the end of the code.
Could you explain it to me?
Source code - here
public static boolean hasDupes(int num){
boolean[] digs = new boolean[10];
while(num > 0){
if(digs[num%10]) return true;
digs[num%10] = true;
num/= 10;
}
return false;
So let's step through it:
boolean[] digs = new boolean[10];
In Java, all the items in an array declaration are given a default value. In the case of boolean, it is false. So this creates an array of 10 elements where each element is false
while(num > 0){
if(digs[num%10]) return true;
digs[num%10] = true;
num/= 10;
}
Modding a number by 10 (num % 10) and then dividing by 10 (num/= 10) is a common way to "pop" off the last digit from a number. For example,
int someNum = "1357";
int lastDigit = mod % 10; // lastDigit is 7
someNum /= 10; // someNum is now 135
As you can see, the 7 gets removed. So the while loop is just popping of each digit of num until all the digits are processed. Now, for each digit that is being removed, digs[num%10] = true; is simply keeping track of the digits already removed. By keeping track of these, if(digs[num%10]) return true; will return true from the method if a digit has already been processed.
So, in much simpler words, this method just checks to see if a number contains more than 1 of the same digit.
12345 will return false
12341 will return true
Just make a pen & paper test. Our number system has 10 digits: 0 to 9. digs represents, whether a digit has occured already. with num % 10 you get the last digit of num. So let's say num has an 1 at the least significant position. That means: digs[i] will be set to true (digs[num%10] = true;). Now let's look on: with num /= 10 you remove the last digit from an integer. For example, 3211 /= 10 will be 321 (integer arithmetics, I know you cannot apply /= to literals, but it is only a demonstration to explain the semantics). Since num is > 0, the loop is executed again. This time, the if-condition will be true (because we set digs[1] to true one iteration before), we found a duplicate digit. If the method is able to leave the loop without entering the if, num has pairwise unequal digits. That's it.
It's checking if any value in base 10 has duplicated digits.
So 9019 has duplicated digits (9) when written as a decimal value. 123 does not.
In the context of the game, it basically checks to see if the given integer, num, has duplicated digits. It does so by creating an array of 10 boolean values, such that two digits that are duplicated will be dropped into the same cell in the array. The algorithm uses
An array of 10 boolean values to represent each digit in our base 10 number system. So if you are dealing with base 16 number system, you will need an array of 16 boolean values.
num modulo 10 to extract the least significant digit of num until all digits have been examined. Again, it uses modulo 10 because it is assuming a base 10 number system.
The moment that duplicated digits are detected, the method returns true:
if(digs[num%10]) return true;
If you look at the main() method in your sample codes, the algorithm will attempt to keep generating random number, until one with no duplicated digits is found.
while(hasDupes(target= (gen.nextInt(9000) + 1000)));
Im trying to implement a function that returns a natural number which is the sum of the digits within an entered natural number. I just keep on getting an infinite loop. I know i have to return the recursive call but i cant figure this out. Here is what i have so far:
private static NaturalNumber sumOfDigits(NaturalNumber n) {
NaturalNumber zero = new NaturalNumber2(0);
if (n.compareTo(zero) == 0) {
return zero;
} else {
NaturalNumber z = new NaturalNumber2(n.divideBy10());
n.divideBy10();
z.add(sumOfDigits(n));
// return ___;
}
}
What am i supposed to return? Returning z doesn't work
You are making the recursive call with n, the same number that was passed into your procedure. If you strip off a digit for z, then the recursive call has to be made with the rest of the digits.
You can strip off a digit with mod 10 and then get the rest of the digits by divide by 10. If you were using ints it would be:
return (n % 10) + sumOfDigits(n / 10);
z.add(sumOfDigits(n)); should be z.add(sumOfDigits(n.divideBy10()));. The main point is in the recursion you only want to process the remainder of the answer, not the whole problem.
I'm having trouble figuring why the following code isn't producing the expected output. Instead, result = 272 which does not seem right.
/*
*Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be: 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
*Find the sum of all the even-valued terms in the sequence which do not exceed four million.
*/
public class Fibonacci
{
public static void main (String[] args)
{
int result = 0;
for(int i=2;i<=33;i++)
{
System.out.println("i:" + fib(i));
if(i % 2 == 0) //if i is even
{
result += i;
System.out.println("result:" + result);
}
}
}
public static long fib(int n)
{
if (n <= 1)
return n;
else
return fib(n-1) + fib(n-2);
}
}
The line result += i; doesn't add a Fibonacci number to result.
You should be able to figure out how to make it add a Fibonacci number to result.
Hint: Consider making a variable that stores the number you're trying to work with.
First of all, you got one thing wrong for the Fib. The definition for Fib can be found here: http://en.wikipedia.org/wiki/Fibonacci_number.
Second of all (i % 2) is true for every other number (2, 4, 6 and so), which will man that it is true for fib(2), fib(4), and so on.
And last, result += i adds the index. What you wan't to add is the result of the fib(i). So first you need to calculate fib(i), store that in a variable, and check if THAT is an even or odd number, and if it is, then add the variable to the result.
[Edit]
One last point: doing fib in recursion when you wan't to add up all the numbers can be really bad. If you are working with to high numbers you might even end up with StackOverflowException, so it is always a good idea to try and figure a way so that you don't have to calculate the same numbers over and over again. In this example, you want to sum the numbers, so instead of first trying fib(0), then fib(1) and so on, you should just go with the list, check every number on the way and then add it to the result if it matches your criteria.
Well, here's a good starting point, but it's C, not Java. Still, it might help: link text