Armstrong number logic error - java

Here I've code to print armstrong numbers until some particular range. But this programs doesnt prints all the numbers within the range. It just prints armstrong number within range of 1000. Whats wrong in this code?
public static void main(String[] args) {
long N, temp, sum = 0;
Scanner ip = new Scanner(System.in);
System.out.print("Enter the range: ");
N = ip.nextLong();
for (long i = 1; i < N; i++) {
temp = i;
while (temp > 0) {
long rem = temp % 10;
sum = sum + (rem * rem * rem);
temp = temp / 10;
}
if (sum == i) {
System.out.println(" " + i);
}
sum = 0;
}
ip.close();
}
when the input is 100000 it just prints
Enter the range: 100000
1
153
370
371
407

According to the definition of Armstrong numbers, each digit in the number is to be raised to n where is the number of digits in the number.
However your logic does not implement that. It only raises digits to the third power.
That's why your code fails.
Here you go, use this code:
for (long i = 1; i < N; i++) {
temp = i;
int n=Long.toString(i).length();
while (temp > 0) {
long rem = temp % 10;
sum = sum + (long) Math.pow(rem, n);
temp = temp / 10;
}
if (sum == i) {
System.out.println(" " + i);
}
sum = 0;
}
Ideone link here.

Related

To find out Armstrong number in between numbers

Below is my code.
package com.ofss.java.examples;
import java.util.Scanner;
class ArmstrongNumber {
public static void main(String[] args) {
int c = 0, a;
int n1, n2;//Range in which armstrong number need to find
Scanner s = new Scanner(System.in);
System.out.println("Enter the first number");
n1 = s.nextInt();
System.out.println("Enter the second number");
n2 = s.nextInt();
for (int i = n1; i <= n2; ++i) {
while (i > 0) {
a = i % 10;
System.out.println(a);
i = i / 10;
System.out.println(i);
c = c + (a * a * a);
System.out.println(c);
}
if (i == c)
System.out.println(c + "armstrong number");
else
System.out.println(c + "Not armstrong number");
}
}
}
I am getting incorrect results after executing. Code runs for infinite number till you stops it. It must print number between 151-154 (153 as armstrong).
Also, it is incorrectly printing 153 as not Armstrong number.
Armstrong Number
...is a number that is the sum of its own digits each raised to the power of the number of digits.
You should not change i since this is also used in
for (int i = n1; i <= n2; ++i)
Or you will probably never exit that loop eiter since you expect i to be negative at the end of the first iteration. Hard to increment until it reach n2.
Use a different variable to keep track of i safely.
int j = i;
while(j > 0) ...
About Armstrong number:
Armstrong number is a number that is the sum of its own digits each raised to the power of the number of digits
You need to put each digit to the power of the length of the number (the number of digit).
153 = 1^3 + 5^3 + 3^3
1634 = 1^4 + 6^4 + 3^4 + 4^4
Here is the method for it :
public static boolean isArmstrongNumber(int number){
int power = Integer.toString(number).length(); //just to get the number of digit...
int tmp = number;
int digit , sum = 0;
while(tmp > 0){
digit = tmp % 10;
sum += Math.round(Math.pow(digit , power));
tmp /= 10;
}
return sum == number;
}
Using this check from 0 to 10.000 gives :
0
1
2
3
4
5
6
7
8
9
153
370
371
407
1634
8208
9474
Same as Wikipedia :
The sequence of base 10 narcissistic numbers starts: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474, ...
Note that using a method remove the risk of forgetting to reset your variable like c in your case. Correcting this would give you a few more "correct" results (well the one with 3 digits)
You can also use less mathematics to read the number and use char[], remember that you need to substract '0' value to get the numeric value for a character :
public static boolean isArmstrongNumber(int number){
char[] digits = Integer.toString(number).toCharArray();
int power = digits.length;
int sum = 0;
for(char c : digits){
int digit = c - '0';
sum += Math.round(Math.pow(digit, power));
}
return sum == number;
}
There are two things.
you are updating i everytime as you have used it in while, so use different variable than i for this calculation.
int num = i;
c is used to compare sum of cube is same as number but you are not resetting it once the one iteration is over. so make c=0 inside for loop.
c = 0;
Also while printing you are using c, there should be i which is correct and real number.
Below is the working code you may try.
public static void main(String[] args)
{
int c = 0, a;
int n1, n2;//Range in which armstrong number need to find
Scanner s = new Scanner(System.in);
System.out.println("Enter the first number");
n1 = s.nextInt();
System.out.println("Enter the second number");
n2 = s.nextInt();
for (int i = n1; i <= n2; ++i)
{
int num = i;
while (num > 0)
{
a = num % 10;
num = num / 10;
c = c + (a * a * a);
}
if (i == c)
System.out.println(i + "armstrong number");
else
System.out.println(i + "Not armstrong number");
c = 0;
}
}
public class ArmstrongNumber {
private final int n1, n2;
public ArmstrongNumber(int n1, int n2) {
this.n1 = n1;
this.n2 = n2;
}
protected static boolean isArmstrong(int n) {
if(n < 0)
return false;
int remaining=n;
int sumCube=0;
while (remaining>0) {
int d = remaining % 10;
sumCube += cube(d);
remaining /= 10;
}
return n == sumCube;
}
private static int cube(int d) {
return d*d*d;
}
public Integer[] find() {
List<Integer> results = new ArrayList<>();
for (int i = n1; i <= n2; ++i)
{
if (isArmstrong(i))
results.add(i);
}
return results.toArray(new Integer[0]);
}
}
There are lot of things to improve in your code. One of the working logics as below:
for (int i = n1; i <= n2; ++i) {
int sum = 0, remainder = 0, digits = 0, temp = 0;
temp = i;
while (temp != 0) {
digits++;
temp = temp / 10;
}
temp = i;
while (temp != 0) {
remainder = temp % 10;
sum = sum + (int) Math.pow(remainder, digits);
temp = temp / 10;
}
if (i == sum)
System.out.println(i + " is an Armstrong number.");
else
System.out.println(i + " isn't an Armstrong number.");
}

Why while() creates magic?

I was writing a program to find armstrong numbers from 100 to 999. If I give number as an input program works but if I check number using while loop it says that every number not an armstrong number. I can't understand why.
That is the code:
package armstrong;
//import java.util.Scanner;
public class Armstrong {
public static void main(String[] args) {
int n, sum = 0, temp, remainder, digits = 0;
//Scanner in = new Scanner(System.in);
//System.out.println("Input a number to check if it is an Armstrong number");
//n = in.nextInt();
n = 100;
while (n <= 999) {
temp = n;
// Count number of digits
while (temp != 0) {
digits++;
temp = temp / 10;
}
temp = n;
while (temp != 0) {
remainder = temp % 10;
sum = sum + power(remainder, digits);
temp = temp / 10;
}
if (n != sum) System.out.println(n + " is not an Armstrong number.");
else System.out.println("Armstrong number:" + n);
n++;
}
}
static int power(int n, int r) {
int c, p = 1;
for (c = 1; c <= r; c++)
p = p * n;
return p;
}
}
You should initialize digits, sum to zero in your loop like:
while (n <= 999) {
digits = 0;
sum = 0
...
}
Based on this page: http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/arms.html
You should set sum to back to zero inside the loop:
while(n <= 999) {
temp = n;
sum = 0;
...
}
and power method should be:
static int power(int n) {
return n * n * n;
}
Hope it helps.

How to sort Integer digits in ascending order without Strings or Arrays?

I'm trying to sort the digits of an integer of any length in ascending order without using Strings, arrays or recursion.
Example:
Input: 451467
Output: 144567
I have already figured out how to get each digit of the integer with modulus division:
int number = 4214;
while (number > 0) {
IO.println(number % 10);
number = number / 10;
}
but I don't know how to order the digits without an array.
Don't worry about the IO class; it's a custom class our professor gave us.
It's 4 lines, based on a for loop variant of your while loop with a little java 8 spice:
int number = 4214;
List<Integer> numbers = new LinkedList<>(); // a LinkedList is not backed by an array
for (int i = number; i > 0; i /= 10)
numbers.add(i % 10);
numbers.stream().sorted().forEach(System.out::println); // or for you forEach(IO::println)
There's actually a very simple algorithm, that uses only integers:
int number = 4214173;
int sorted = 0;
int digits = 10;
int sortedDigits = 1;
boolean first = true;
while (number > 0) {
int digit = number % 10;
if (!first) {
int tmp = sorted;
int toDivide = 1;
for (int i = 0; i < sortedDigits; i++) {
int tmpDigit = tmp % 10;
if (digit >= tmpDigit) {
sorted = sorted/toDivide*toDivide*10 + digit*toDivide + sorted % toDivide;
break;
} else if (i == sortedDigits-1) {
sorted = digit * digits + sorted;
}
tmp /= 10;
toDivide *= 10;
}
digits *= 10;
sortedDigits += 1;
} else {
sorted = digit;
}
first = false;
number = number / 10;
}
System.out.println(sorted);
it will print out 1123447.
The idea is simple:
you take the current digit of the number you want to sort(let's call it N)
you go through all digits in already sorted number(let's call it S)
if current digit in S is less than current digit in N, you just insert the digit in the current position in S. Otherwise, you just go to the next digit in S.
That version of the algorithm can sort in both asc in desc orders, you just have to change the condition.
Also, I suggest you to take a look at so-called Radix Sort, the solution here takes some ideas from radix sort, and I think the radix sort is the general case for that solution.
I assume you're allowed to use hashing.
public static void sortDigits(int x) {
Map<Integer, Integer> digitCounts = new HashMap<>();
while (x > 0) {
int digit = x % 10;
Integer currentCount = digitCounts.get(digit);
if (currentCount == null) {
currentCount = 0;
}
digitCounts.put(x % 10, currentCount + 1);
x = x / 10;
}
for (int i = 0; i < 10; i++) {
Integer count = digitCounts.get(i);
if (count == null) {
continue;
}
for (int j = 0; j < digitCounts.get(i); j++) {
System.out.print(i);
}
}
}
How to sort a number without use of array, string or sorting api? Well, you can sort a number with following simple steps (if too much to read then see the debugging output below to get an idea of how the sorting is done):
Get the last digit of the number using (digit = number % 10)
Divide number so last digit is gone (number /= 10)
Loop through digits of number (that does not have digit) and check if digit is smallest
If new smaller digit found then replace the digit = smallest digit and keep looking until end
At the end of the loop you have found the smallest digit, store it (store = (store * 10) + digit
Now that you know this is smallest digit, remove this digit from number and keep applying the above steps to remainder number and every time a smaller digit is found then add it to the store and remove digit from number (if digit is repeated in number, then remove them all and add them to store)
I provided a code with two while loops in the main method and one function. The function does nothing but, builds a new integer excluding the digit that is passed to for example I pass the function 451567 and 1 and the function returns me 45567 (in any order, doesn't matter). If this function is passed 451567 and 5 then, it finds both 5 digits in number and add them to store and return number without 5 digits (this avoid extra processing).
Debugging, to know how it sorts the integer:
Last digit is : 7 of number : 451567
Subchunk is 45156
Subchunk is 4515
Subchunk is 451
Subchunk is 45
Subchunk is 4
Smalled digit in 451567 is 1
Store is : 1
Remove 1 from 451567
Reduced number is : 76554
Last digit is : 4 of number : 76554
Subchunk is 7655
Subchunk is 765
Subchunk is 76
Subchunk is 7
Smalled digit in 76554 is 4
Store is : 14
Remove 4 from 76554
Reduced number is : 5567
Last digit is : 7 of number : 5567
Subchunk is 556
Subchunk is 55
Subchunk is 5
Smalled digit in 5567 is 5
Store is : 145
Remove 5 from 5567
Repeated min digit 5 found. Store is : 145
Repeated min digit 5 added to store. Updated store is : 1455
Reduced number is : 76
Last digit is : 6 of number : 76
Subchunk is 7
Smalled digit in 76 is 6
Store is : 14556
Remove 6 from 76
Reduced number is : 7
Last digit is : 7 of number : 7
Smalled digit in 7 is 7
Store is : 145567
Remove 7 from 7
Reduced number is : 0
Ascending order of 451567 is 145567
The sample code is as follow:
//stores our sorted number
static int store = 0;
public static void main(String []args){
int number = 451567;
int original = number;
while (number > 0) {
//digit by digit - get last most digit
int digit = number % 10;
System.out.println("Last digit is : " + digit + " of number : " + number);
//get the whole number minus the last most digit
int temp = number / 10;
//loop through number minus the last digit to compare
while(temp > 0) {
System.out.println("Subchunk is " + temp);
//get the last digit of this sub-number
int t = temp % 10;
//compare and find the lowest
//for sorting descending change condition to t > digit
if(t < digit)
digit = t;
//divide the number and keep loop until the smallest is found
temp = temp / 10;
}
System.out.println("Smalled digit in " + number + " is " + digit);
//add the smallest digit to store
store = (store * 10) + digit;
System.out.println("Store is : " + store);
//we found the smallest digit, we will remove that from number and find the
//next smallest digit and keep doing this until we find all the smallest
//digit in sub chunks of number, and keep adding the smallest digits to
//store
number = getReducedNumber(number, digit);
}
System.out.println("Ascending order of " + original + " is " + store);
}
/*
* A simple method that constructs a new number, excluding the digit that was found
* to b e smallest and added to the store. The new number gets returned so that
* smallest digit in the returned new number be found.
*/
public static int getReducedNumber(int number, int digit) {
System.out.println("Remove " + digit + " from " + number);
int newNumber = 0;
//flag to make sure we do not exclude repeated digits, in case there is 44
boolean repeatFlag = false;
while(number > 0) {
int t = number % 10;
//assume in loop one we found 1 as smallest, then we will not add one to the new number at all
if(t != digit) {
newNumber = (newNumber * 10) + t;
} else if(t == digit) {
if(repeatFlag) {
System.out.println("Repeated min digit " + t + "found. Store is : " + store);
store = (store * 10) + t;
System.out.println("Repeated min digit " + t + "added to store. Updated store is : " + store);
//we found another value that is equal to digit, add it straight to store, it is
//guaranteed to be minimum
} else {
//skip the digit because its added to the store, in main method, set flag so
// if there is repeated digit then this method add them directly to store
repeatFlag = true;
}
}
number /= 10;
}
System.out.println("Reduced number is : " + newNumber);
return newNumber;
}
}
My algorithm of doing it:
int ascending(int a)
{
int b = a;
int i = 1;
int length = (int)Math.log10(a) + 1; // getting the number of digits
for (int j = 0; j < length - 1; j++)
{
b = a;
i = 1;
while (b > 9)
{
int s = b % 10; // getting the last digit
int r = (b % 100) / 10; // getting the second last digit
if (s < r)
{
a = a + s * i * 10 - s * i - r * i * 10 + r * i; // switching the digits
}
b = a;
i = i * 10;
b = b / i; // removing the last digit from the number
}
}
return a;
}
Here is the simple solution :
public class SortDigits
{
public static void main(String[] args)
{
sortDigits(3413657);
}
public static void sortDigits(int num)
{
System.out.println("Number : " + num);
String number = Integer.toString(num);
int len = number.length(); // get length of the number
int[] digits = new int[len];
int i = 0;
while (num != 0)
{
int digit = num % 10;
digits[i++] = digit; // get all the digits
num = num / 10;
}
System.out.println("Digit before sorting: ");
for (int j : digits)
{
System.out.print(j + ",");
}
sort(digits);
System.out.println("\nDigit After sorting: ");
for (int j : digits)
{
System.out.print(j + ",");
}
}
//simple bubble sort
public static void sort(int[] arr)
{
for (int i = 0; i < arr.length - 1; i++)
for (int j = i + 1; j < arr.length; j++)
{
if (arr[i] > arr[j])
{
int tmp = arr[j];
arr[j] = arr[i];
arr[i] = tmp;
}
}
}
}
class SortDigits {
public static void main(String[] args) {
int inp=57437821;
int len=Integer.toString(inp).length();
int[] arr=new int[len];
for(int i=0;i<len;i++)
{
arr[i]=inp%10;
inp=inp/10;
}
Arrays.sort(arr);
int num=0;
for(int i=0;i<len;i++)
{
num=(num*10)+arr[i];
}
System.out.println(num);
}
}
Since the possible elements (i. e. digits) in a number are known (0 to 9) and few (10 in total), you can do this:
Print a 0 for every 0 in the number.
Print a 1 for every 1 in the number.
int number = 451467;
// the possible elements are known, 0 to 9
for (int i = 0; i <= 9; i++) {
int tempNumber = number;
while (tempNumber > 0) {
int digit = tempNumber % 10;
if (digit == i) {
IO.print(digit);
}
tempNumber = tempNumber / 10;
}
}
Scanner sc= new Scanner(System.in);
int n=sc.nextInt();
int length = 0;
long tem = 1;
while (tem <= n) {
length++;
tem *= 10;
}
int last=0;
int [] a=new int[length];
int i=0;
StringBuffer ans=new StringBuffer(4);
while(n!=0){
last=n%10;
a[i]=last;
n=n/10;
i++;
}
int l=a.length;
for(int j=0;j<l;j++){
for(int k=j;k<l;k++){
if(a[k]<a[j]){
int temp=a[k];
a[k]=a[j];
a[j]=temp;
}
}
}
for (int j :a) {
ans= ans.append(j);
}
int add=Integer.parseInt(ans.toString());
System.out.println(add);
For the input:
n=762941 ------->integer
We get output:
149267 ------->integer
import java.util.*;
class EZ
{
public static void main (String args [] )
{
Scanner sc = new Scanner (System.in);
System.out.println("Enter the number - ");
int a=sc.nextInt();
int b=0;
for (int i=9;i>=0;i--)
{
int c=a;
while (c>0)
{
int d=c%10;
if (d==i)
{
b=(b*10)+d;
}
c/=10;
}
}
System.out.println(b);
}
}
import java.util.Scanner;
public class asc_digits
{
public static void main(String args[]){
Scanner in= new Scanner(System.in);
System.out.println("number");
int n=in.nextInt();
int i, j, p, r;
for(i=0;i<10;i++)
{
p=n;
while(p!=0)
{
r = p%10;
if(r==i)
{
System.out.print(r);
}
p=p/10;
}
}
}
}
Stream can also be used for this :
public static int sortDesc(final int num) {
List<Integer> collect = Arrays.stream(valueOf(num).chars()
.map(Character::getNumericValue).toArray()).boxed()
.sorted(Comparator.reverseOrder()).collect(Collectors.toList());
return Integer.valueOf(collect.stream()
.map(i->Integer.toString(i)).collect(Collectors.joining()));
}
class HelloWorld {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int num=sc.nextInt();
System.out.println(" rever number is= "+reversernum(num));
System.out.println("\n sorted number is= "+sortedNumdesc(num));
}
private static int reversernum(int n1)
{
if(n1<10)
return n1;
int n_reverse=0;
int lastDigit=0;
while(n1>=1)
{
lastDigit=n1%10;
n_reverse=n_reverse*10+lastDigit;
// System.out.println(" n_reverse "+n_reverse);
n1=n1/10;
}
return n_reverse;
}
private static int sortedNumdesc(int num)
{
if(num<10)
return num;
List<Integer> numbers = new LinkedList<>();
for (int i=num ;i>0;i/=10)
numbers.add(i%10);
// numbers.stream().sorted().forEach(System.out:: println);
int sorted_Num=0;
List<Integer> sortednum= numbers.stream().sorted()
.collect(Collectors.toList());
// System.out.println("sorted list "+sortednum);
for(Integer x: sortednum)
sorted_Num=sorted_Num*10+x;
return sorted_Num;
}
}

Find Number Equal to the sum of factorial of each of its digits eg:145

Find Number Equal to the sum of factorial of each of its digits eg:145
From 1 to 200
I tried this :
public static void main(String[] args) {
int i = 0, x = 0, temp, temp1, digit = 0, factorial = 1, sum = 0;
System.out.println("Special Numbers from 1 to 10,000 -:");
for (i = 1; i <= 200; i++) {
temp = i;
temp1 = i;
while (temp > 0) {
digit = temp % 10;
factorial = 1;
for (x = 1; x <= digit; x++) {
factorial *= x;//factorial of digit
}
sum += factorial;//sum of factorial of a all the digits of the number
temp = temp / 10;
}
if (sum == temp1) {
System.out.println(temp1);
}
}
}
So if i put i=145 it works but othervise i get the wrong output.
You forgot to make sum 0, so you only get the correct result for the first number you try. The line sum = 0; should go before while(temp>0){.
Your sum variable is declared outside the for block.
Each time you calculate a factorial sum get added to the previous sum and hence 1! + 4! + 5! will never be 145 in this case.
Try initializing it inside the loop to 0.
You need to initialize sum inside the for loop.
for(i=1;i<=200;i++){
sum = 0; //<--include this
temp = i;
temp1 = i;
while(temp>0){
digit = temp%10;
factorial =1;
for(x = 1;x<=digit;x++){
factorial*=x;//factorial of digit
}
sum+=factorial; //sum of factorial
temp = temp/10;
}
if(sum == temp1){
System.out.println(temp1);
}
}

Armstrong number code in Java is not working right

I am completely new to Java and am writing code to check whether a number is an Armstrong number or not in the range 0 to 999.
Please tell me what is wrong. When run on command prompt, it repeatedly prints:
1 is the count
Code:
import java.util.*;
class Armstrong
{
public static void main (String[] args)
{
int sum = 0;
for (int i = 0; i < 1000; i++)
{
int n = i;
int count =0;
while(n > 0)
{
int mod = n % 10;
n = n / 10;
count++;
}
System.out.println(+count+ "is the count");
for (int j = 1; j < count; j++)
{
int val = i % 10;
i= i / 10;
sum = val * val * val + sum;
}
if (sum == i)
{
System.out.println( +i+ "is an Armstrong number");
}
}
}
}
An Armstrong number is a number that is the sum of its own digits each raised to the power of the number of digits.
For starters, you always raise the digits to the power of 3, so your calculation can only work for i between 100 and 999.
Second, you are changing i within your inner loop, so the comparison at the end if (sum==i) will fail, since sum should be compared to the original i.
Next, you don't reset sum to 0 in each iteration of i.
You also skip one of the digits.
This seems to work :
int sum = 0;
for (int i = 100; i < 1000; i++) { // start at 100
sum = 0; // clear the sum in each iteration
int n = i;
int count = 0;
while (n > 0) {
int mod = n % 10;
n = n / 10;
count++;
}
n = i;
for (int j = 0; j < count; j++) { // iterate over all the digits
int val = n % 10;
n = n / 10; // don't change i
sum = val * val * val + sum;
}
if (sum == i) {
System.out.println(i + " is an Armstrong number");
}
}
This returns :
153 is an Armstrong number
370 is an Armstrong number
371 is an Armstrong number
407 is an Armstrong number
There is no need to run three loops. You can do it simpler that way:
for(int i = 0; i < 1000; i++) {
int currNumber = i;
int sum = 0;
while(currNumber != 0)
{
int mod = currNumber % 10;
sum = sum + mod * mod * mod;
currNumber = currNumber / 10;
}
if (i == sum) {
System.out.println(i + " is an Armstrong number");
}
}
Print Armstrong number in java
public class CalculatArmstrong
{
public static void main(String[] args)
{
for(int i=0;i<=2000;i++)
{
int number=i;
int n=number;
int rem;
int arms=0;
while(number>0)
{
rem=number%10;
arms=arms+rem*rem*rem;
number=number/10;
}
if(n==arms)
{
System.out.println(n);
}
}
}
}

Categories