Simple C++ code to generate Armstrong numbers [closed] - c++

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
The following is my simple attempt at generating Armstrong numbers. But it only outputs "1". What might be wrong?
#include<stdio.h>
#include<conio.h>
#include<iostream.h>
int main()
{
clrscr();
int r;
long int num = 0, i, sum = 0, temp;
cout << "Enter the maximum limit to generate Armstrong number ";
cin >> num;
cout << "Following armstrong numbers are found from 1 to " << num << "\t \n";
for(i=1;i<=num;i++)
{
temp = i;
while( temp != 0 )
{
r = temp%10;
sum = sum + r*r*r;
temp = temp / 10;
}
if ( i == sum ) {
cout << i;
sum = 0;
}
}
getch();
return 0;
}

You need to always set sum = 0 inside the for-i-loop.

Armstrong numbers: n-digit numbers equal to sum of n-th powers of their digits.
From your code
sum = sum + r*r*r;
'r*r*r' isn't n'th power of the number.

The first thing is that you're assuming that n (as in the nth power) is always three (in your r*r*r). That's only true if your initial value has three digits (as with the 153 example).
You need to count the digits in your initial number to calculate n, and then replace your r*r*r with raising r to the nth power.
This doesn't explain why 153 isn't found, though. The reason for that is because you aren't reseting sum to zero unless you find a match. You need to reset it to zero whether you found a match or not.

you can calculate n using log:
n = log(i)+1
then calculate r^n correctly and use it in your summation: sum += r^n;. r*r*r is not the correct way of calculating it.

Your code only works with n=3 : sum = sum + r*r*r;
You must use the pow() function (http://www.codecogs.com/reference/c/math.h/pow.php) to compute powers. (Or create a custom one.)

To summarize the right, but partial answers:
// #include <math.h>
for (long int i = 1; i <= num; i++)
{
long int n = 0, sum = 0; // <--- here
long ing temp = i;
while ( temp != 0 )
{
++n;
temp /= 10;
}
temp = i;
while ( temp != 0 )
{
int r = temp%10;
sum += int(pow(double(r), n)); // <-- here
temp /= 10;
}
if ( i == sum )
{
cout << i;
sum = 0;
}
}

#Power-inside, I saw your code, its difficult to change your code and edit it, but I have written a similar code to generate Armstrong numbers in a given limit, and it works fine.
Here it is....
#include<iostream.h>
#include<conio.h>
class arm
{
int a;
public:
void display();
};
void arm::display()
{
cout<<"Enter any number to find armstrong numbers less than it";
cin>>a;
for(int i=a;i>=1;i--)
{
int d=i;
int b=i;
int c=i;
int count=0;
while(b!=0)
{
b=b/10;
count++;
}
int l,m;
m=0;
for(int k=1;k<=count;k++)
{
l=c%10;
c=c/10;
m=m+l*l*l;
}
if(d==m)
cout<<d<<"\t";
}
}
void main()
{
arm k;
k.display();
getch();
}

Related

Wrong output- trying for if the number is Armstrong

I am new to coding and just starting with the c++ language, here I am trying to find the number given as input if it is Armstrong or not.
An Armstrong number of three digits is an integer such that the sum of the cubes of its digits is equal to the number itself. For example, 153 is an Armstrong number since 1^3 + 5^3 + 3^3 = 153.
But even if I give not an armstrong number, it still prints that number is armstrong.
Below is my code.
#include <cmath>
#include <iostream>
using namespace std;
bool ifarmstrong(int n, int p) {
int sum = 0;
int num = n;
while(num>0){
num=num%10;
sum=sum+pow(num,p);
}
if(sum==n){
return true;
}else{
return false;
}
}
int main() {
int n;
cin >> n;
int i, p = 0;
for (i = 0; n > 0; i++) {
n = n / 10;
}
cout << i<<endl;
if (ifarmstrong(n, i)) {
cout << "Yes it is armstorng" << endl;
} else {
cout << "No it is not" << endl;
}
return 0;
}
A solution to my problem and explantation to what's wrong
This code
for (i = 0; n > 0; i++) {
n = n / 10;
}
will set n to zero after the loop has executed. But here
if (ifarmstrong(n, i)) {
you use n as if it still had the original value.
Additionally you have a error in your ifarmstrong function, this code
while(num>0){
num=num%10;
sum=sum+pow(num,p);
}
result in num being zero from the second iteration onwards. Presumably you meant to write this
while(num>0){
sum=sum+pow(num%10,p);
num=num/10;
}
Finally using pow on integers is unreliable. Because it's a floating point function and it (presumably) uses logarithms to do it's calculations, it may not return the exact integer result that you are expecting. It's better to use integers if you are doing exact integer calculations.
All these issues (and maybe more) will very quickly be discovered by using a debugger. much better than staring at code and scratching your head.

Kickstart 2022 interesting numbers

The question is to find the number of interesting numbers lying between two numbers. By the interesting number, they mean that the product of its digits is divisible by the sum of its digits.
For example: 459 => product = 4 * 5 * 9 = 180, and sum = 4 + 5 + 9 = 18; 180 % 18 == 0, hence it is an interesting number.
My solution for this problem is having run time error and time complexity of O(n2).
#include<iostream>
using namespace std;
int main(){
int x,y,p=1,s=0,count=0,r;
cout<<"enter two numbers"<<endl;
cin>>x>>y;
for(int i=x;i<=y;i++)
{
r=0;
while(i>1)
{
r=i%10;
s+=r;
p*=r;
i/=10;
}
if(p%s==0)
{
count++;
}
}
cout<<"count of interesting numbers are"<<count<<endl;
return 0;
}
If s is zero then if(p%s==0) will produce a divide by zero error.
Inside your for loop you modify the value of i to 0 or 1, this will mean the for loop never completes and will continuously check 1 and 2.
You also don't reinitialise p and s for each iteration of the for loop so will produce the wrong answer anyway. In general limit the scope of variables to where they are actually needed as this helps to avoid this type of bug.
Something like this should fix these problems:
#include <iostream>
int main()
{
std::cout << "enter two numbers\n";
int begin;
int end;
std::cin >> begin >> end;
int count = 0;
for (int number = begin; number <= end; number++) {
int sum = 0;
int product = 1;
int value = number;
while (value != 0) {
int digit = value % 10;
sum += digit;
product *= digit;
value /= 10;
}
if (sum != 0 && product % sum == 0) {
count++;
}
}
std::cout << "count of interesting numbers are " << count << "\n";
return 0;
}
I'd guess the contest is trying to get you to do something more efficient than this, for example after calculating the sum and product for 1234 to find the sum for 1235 you just need to add one and for the product you can divide by 4 then multiply by 5.

Tips on Improving Efficiency of this Code (Beginner)

I am currently doing a coding exercise and am missing some cases due to the time limit being exceeded. Can I get some tips on how to improve the efficiency of my code? Also if you have any general tips for a beginner I would also appreciate that. The problem is below and thanks.
You are given all numbers between 1,2,…,n except one. Your task is to find the missing number.
Input
The first input line contains an integer n.
The second line contains n−1 numbers. Each number is distinct and between 1 and n (inclusive).
Output
Print the missing number.
Constraints
2≤n≤2⋅105
Example
Input:
5
2 3 1 5
Output:
4
Here is my code:
#include <bits/stdc++.h>
using namespace std;
int missingNumber(vector<int> available, int N) {
for (int i=1; i<=N; i++) {
bool counter = false;
for (int j=0; j<N-1; j++) {
if (i == available[j]) {
counter = true;
}
}
if (counter == false) {
return i;
}
}
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
int N;
cin >> N;
vector<int> available(N-1);
int temp = 0;
for (int i=0; i<N-1; i++) {
cin >> temp;
available[i] = temp;
}
cout << missingNumber(available, N);
}
A very simple solution with O(N) complexity is based on the observation that if the N-1 numbers are all between 1 and N and distinct from each other, then it suffices to:
compute the sum of all these N-1 numbers, so linear complexity
subtract the sum computed at step 1 from the sum of the N numbers from 1 to N, which we know is N * (N + 1) / 2, so O(1) complexity.
here is an answer with two versions to your problem
the first version is using Arithmetic progression formula n*(a1 + an) /2
and then subtract your vector sum with the result of the formula.
double missingNumber_ver1(std::vector<int> available, int N) {
// formula for sum for Arithmetic progression
double sum = N * (available[0]+available[N-2]) /2;
double available_sym = std::accumulate(available.begin(), available.end(), 0); // this is to sum the giving numbers
double missing_num = sum-available_sym;
return missing_num;
}
the second version is to use XOR operator and when there is a xor value that is not 0 that means this is the missing number. I'm also using std::iota to build the comparison vector with range values.
double missingNumber_ver2(std::vector<int> available, int N) {
std::vector<int>tem_vec(N-1);
std::iota(tem_vec.begin(), tem_vec.end(), available[0]);
auto av_it = available.begin();
auto tem_vec_it = tem_vec.begin();
while(!(*av_it ^ *tem_vec_it))
{
av_it++;
tem_vec_it++;
}
return *tem_vec_it;
}
and here is the full code - look that I made few changes also in the main() function
#include <iostream>
#include <numeric>
#include <vector>
double missingNumber_ver1(std::vector<int> available, int N) {
// formula for sum for Arithmetic progression
double sum = N * (available[0]+available[N-2]) /2;
double available_sym = std::accumulate(available.begin(), available.end(), 0);
double missing_num = sum-available_sym;
return missing_num;
}
double missingNumber_ver2(std::vector<int> available, int N) {
std::vector<int>tem_vec(4);
std::iota(tem_vec.begin(), tem_vec.end(), available[0]);
auto av_it = available.begin();
auto tem_vec_it = tem_vec.begin();
while(!(*av_it ^ *tem_vec_it))
{
av_it++;
tem_vec_it++;
}
return *tem_vec_it;
}
int main() {
int N;
std::cin >> N;
std::vector<int> available;
int temp = 0;
for (int i=0; i<N-1; i++) {
std::cin >> temp;
available.push_back(temp);
}
std::cout << "missingNumber_ver1 " << missingNumber_ver1(available, N) << "\n";
std::cout << "missingNumber_ver2 " <<missingNumber_ver2(available, N) << "\n";
}

How to reduce the time in this program?

I have a program like this: given a sequence of integers, find the biggest prime and its positon.
Example:
input:
9 // how many numbers
19 7 81 33 17 4 19 21 13
output:
19 // the biggest prime
1 7 // and its positon
So first I get the input, store it in an array, make a copy of that array and sort it (because I use a varible to keep track of the higest prime, and insane thing will happen if that was unsorted) work with every number of that array to check if it is prime, loop through it again to have the positon and print the result.
But the time is too slow, can I improve it?
My code:
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int numbersNotSorted[n];
int maxNum{0};
for (int i = 0; i < n; i++)
{
cin >> numbersNotSorted[i];
}
int numbersSorted[n];
for (int i = 0; i < n; i++)
{
numbersSorted[i] = numbersNotSorted[i];
}
sort(numbersSorted, numbersSorted + n);
for (int number = 0; number < n; number++)
{
int countNum{0};
for (int i = 2; i <= sqrt(numbersSorted[number]); i++)
{
if (numbersSorted[number] % i == 0)
countNum++;
}
if (countNum == 0)
{
maxNum = numbersSorted[number];
}
}
cout << maxNum << '\n';
for (int i = 0; i < n; i++)
{
if (numbersNotSorted[i] == maxNum)
cout << i + 1 << ' ';
}
}
If you need the biggest prime, sorting the array brings you no benefit, you'll need to check all the values stored in the array anyway.
Even if you implemented a fast sorting algorithm, the best averages you can hope for are O(N + k), so just sorting the array is actually more costly than looking for the largest prime in an unsorted array.
The process is pretty straight forward, check if the next value is larger than the current largest prime, and if so check if it's also prime, store the positions and/or value if it is, if not, check the next value, repeat until the end of the array.
θ(N) time compexity will be the best optimization possible given the conditions.
Start with a basic "for each number entered" loop:
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int main() {
int n;
int newNumber;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> newNumber;
}
}
If the new number is smaller than the current largest prime, then it can be ignored.
int main() {
int n;
int newNumber;
int highestPrime;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> newNumber;
if(newNumber >= highestPrime) {
}
}
}
If the new number is equal to the highest prime, then you just need to store its position somewhere. I'm lazy, so:
int main() {
int n;
int newNumber;
int highestPrime;
int maxPositions = 1234;
int positionList[maxPositions];
int nextPosition;
int currentPosition = 0;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> newNumber;
currentPosition++;
if(newNumber >= highestPrime) {
if(newNumber == highestPrime) {
if(nextPosition+1 >= maxPositions) {
// List of positions is too small (should've used malloc/realloc instead of being lazy)!
} else {
positionList[nextPosition++] = currentPosition;
}
}
}
}
}
If the new number is larger than the current largest prime, then you need to figure out if it is a prime number, and if it is you need to reset the list and store its position, etc:
int main() {
int n;
int newNumber;
int highestPrime = 0;
int maxPositions = 1234;
int positionList[maxPositions];
int nextPosition;
int currentPosition = 0;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> newNumber;
currentPosition++;
if(newNumber >= highestPrime) {
if(newNumber == highestPrime) {
if(nextPosition+1 >= maxPositions) {
// List of positions is too small (should've used malloc/realloc instead of being lazy)!
} else {
positionList[nextPosition++] = currentPosition;
}
} else { // newNumber > highestPrime
if(isPrime(newNumber)) {
nextPosition = 0; // Reset the list
highestPrime = newNumber;
positionList[nextPosition++] = currentPosition;
}
}
}
}
}
You'll also want something to display the results:
if(highestPrime > 0) {
for(nextPosition= 0; nextPosition < currentPosition; nextPosition++) {
cout << positionList[nextPosition];
}
}
Now; the only thing you're missing is an isPrime(int n) function. The fastest way to do that is to pre-calculate a "is/isn't prime" bitfield. It might look something like:
bool isPrime(int n) {
if(n & 1 != 0) {
n >>= 1;
if( primeNumberBitfield[n / 32] & (1 << (n % 32)) != 0) {
return true;
}
}
return false;
}
The problem here is that (for positive values in a 32-bit signed integer) you'll need 1 billion bits (or 128 MiB).
To avoid that you can use a much smaller bitfield for numbers up to sqrt(1 << 31) (which is only about 4 KiB); then if the number is too large for the bitfield you can use the bitfield to find prime numbers and check (with modulo) if they divide the original number evenly.
Note that Sieve of Eratosthenes ( https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes ) is an efficient way to generate that smaller bitfield (but is not efficient to use for a sparse population of larger numbers).
If you do it right, you'll probably create the illusion that it's instantaneous because almost all of the work will be done while a human is slowly typing the numbers in (and not left until after all of the numbers have been entered). For a very fast typist you'll have ~2 milliseconds between numbers, and (after the last number is entered) humans can't notice delays smaller than about 10 milliseconds.
But the time is too slow, can I improve it?
Below loop suffers from:
Why check smallest values first? Makes more sense to check largest values first to find the largest prime. Exit the for (... number..) loop early once a prime is found. This takes advantage of the work done by sort().
Once a candidate value is not a prime, quit testing for prime-ness.
.
// (1) Start for other end rather than as below
for (int number = 0; number < n; number++) {
int countNum {0};
for (int i = 2; i <= sqrt(numbersSorted[number]); i++) {
if (numbersSorted[number] % i == 0)
// (2) No point in continuing prime testing, Value is composite.
countNum++;
}
if (countNum == 0) {
maxNum = numbersSorted[number];
}
}
Corrections left for OP to implement.
Advanced: Prime testing is a deep subject and many optimizations (trivial and complex) exist that are better than OP's approach. Yet I suspect the above 2 improvement will suffice for OP.
Brittleness: Code does not well handle the case of no primes in the list or n <= 0.
i <= sqrt(numbersSorted[number]) is prone to FP issues leading to an incorrect results. Recommend i <= numbersSorted[number]/i).
Sorting is O(n * log n). Prime testing, as done here, is O(n * sqrt(n[i])). Sorting does not increase O() of the overall code when the square root of the max value is less than log of n. Sorting is worth doing if the result of the sort is used well.
Code fails if the largest value was 1 as prime test incorrectly identifies 1 as a prime.
Code fails if numbersSorted[number] < 0 due to sqrt().
Simply full-range int prime test:
bool isprime(int num) {
if (num % 2 == 0) return num == 2;
for (int divisor = 3; divisor <= num / divisor; divisor += 2) {
if (num % divisor == 0) return false;
}
return num > 1;
}
If you want to find the prime, don't go for sorting. You'll have to check for all the numbers present in the array then.
You can try this approach to do the same thing, but all within a lesser amount of time:
Step-1: Create a global function for detecting a prime number. Here's how you can approach this-
bool prime(int n)
{
int i, p=1;
for(i=2;i<=sqrt(n);i++) //note that I've iterated till the square root of n, to cut down on the computational time
{
if(n%i==0)
{
p=0;
break;
}
}
if(p==0)
return false;
else
return true;
}
Step-2: Now your main function starts. You take input from the user:
int main()
{
int n, i, MAX;
cout<<"Enter the number of elements: ";
cin>>n;
int arr[n];
cout<<"Enter the array elements: ";
for(i=0;i<n;i++)
cin>>arr[i];
Step-3: Note that I've declared a counter variable MAX. I initialize this variable as the first element of the array: MAX=arr[0];
Step-4: Now the loop for iterating the array. What I did was, I iterated through the array and at each element, I checked if the value is greater than or equal to the previous MAX. This will ensure, that the program does not check the values which are less than MAX, thus eliminating a part of the array and cutting down the time. I then nested another if statement, to check if the value is a prime or not. If both of these are satisfied, I set the value of MAX to the current value of the array:
for(i=0;i<n;i++)
{
if(arr[i]>=MAX) //this will check if the number is greater than the previous MAX number or not
{
if(prime(arr[i])) //if the previous condition satisfies, then only this block of code will run and check if it's a prime or not
MAX=arr[i];
}
}
What happens is this- The value of MAX changes to the max prime number of the array after every single loop.
Step-5: Then, after finally traversing the array, when the program finally comes out of the loop, MAX will have the largest prime number of the array stored in it. Print this value of MAX. Now for getting the positions where MAX happens, just iterate over the whole loop and check for the values that match MAX and print their positions:
for(i=0;i<n;i++)
{
if(arr[i]==MAX)
cout<<i+1<<" ";
}
I ran this code in Dev C++ 5.11 and the compilation time was 0.72s.

Program to calculate square root c++

I am making a C++ program to calculate the square root of a number. This program does not use the "sqrt" math built in operation. There are two variables, one for the number the user will enter and the other for the square root of that number. This program does not work really well and I am sure there is a better way to do so:
Here is my full code:
#include <iostream>
using namespace std;
int main(){
int squareroot = 0;
int number;
cout << "enter a number sp that i can calculate its squareroot" << endl;
cin >> number;
while (squareroot * squareroot != number){
squareroot+=0.1;
}
cout << "the square root is" << squareroot << endl;
return 0;
}
I know there must be a better way. Pls help. Looked through Google but don't understand the complex programs there as I am still a beginner.
Thanks in advance.
Below explanation is given for the integer square root calculation:
In number theory, the integer square root of a positive
integer n is the positive integer m which is the greatest integer less
than or equal to the square root of n
The approach your started is good but needs several correction to make it work:
you are working with int you want to add 1 to squareroot not 0.1
you want to stop your calculation when you squareroot * squareroot is equal or greater than number. Think about the case were the number is 26, you don't have an integer that multiplies itself to 26.
in the case of number equal to 26, do you want to return 5 or 6? After your while loop the value of squareroot will be 6 so you might want to reverse it to 5 (if squareroot * squareroot is different than number)
Below the exemple:
#include <iostream>
using namespace std;
int main(){
int squareroot = 0;
int number;
cout << "enter a number sp that i can calculate its squareroot" << endl;
cin >> number;
while (squareroot * squareroot < number){
squareroot+=1;
}
if (squareroot * squareroot != number) --squareroot;
cout << "the square root is" << squareroot << endl;
return 0;
}
Below a more efficient and elegant way of calculating the square root using binary search principle. O(log(n))
int mySqrt(int x) {
if (x==0) return 0;
int left = 1;
int right = x/2 + 1;
int res;
while (left <= right) {
int mid = left + ((right-left)/2);
if (mid<=x/mid){
left = mid+1;
res=mid;
}
else {
right=mid-1;
}
}
return res;
}
This function uses Nested Intervals (untested) and you can define the accuracy:
#include <math.h>
#include <stdio.h>
double mySqrt(double r) {
double l=0, m;
do {
m = (l+r)/2;
if (m*m<2) {
l = m;
} else {
r = m;
}
}
while(fabs(m*m-2) > 1e-10);
return m;
}
See https://en.wikipedia.org/wiki/Nested_intervals
This function will calculate the floor of square root if A is not a perfect square.This function basically uses binary search.Two things you know beforehand is that square root of a number will be less or equal to that number and it will be greater or equal to 1. So we can apply binary search in that range.Below is my implementation.Let me know if you don't understand anything in the code.Hope this helps.
int sqrt(int A) {
if(A<1)return 0;
if(A==1)return 1;
unsigned long long start,end,mid,i,val,lval;
start = 1;
end = A;
while(start<=end){
mid = start+(end-start)/2;
val = mid*mid;
lval = (mid-1)*(mid-1);
if(val == A)return mid;
else if(A>lval && A<val) return mid-1;
else if(val > A)end = mid;
else if(val < A)start = mid+1;
}
}
The problem with your code, is that it only works if the square root of the number is exactly N*0.1, where N is an integer, meaning that if the answer is 1.4142 and not 1.400000000 exactly your code will fail. There are better ways , but they're all more complicated and use numerical analysis to approximate the answer, the easiest of which is the Newton-Raphson method.
you can use the function below, this function uses the Newton–Raphson method to find the root, if you need more information about the Newton–Raphson method, check this wikipedia article. and if you need better accuracy - but worse performance- you can decrease '0.001' to your likening,or increase it if you want better performance but less accuracy.
float mysqrt(float num) {
float x = 1;
while(abs(x*x - num) >= 0.001 )
x = ((num/x) + x) / 2;
return x;
}
if you don't want to import math.h you can write your own abs():
float abs(float f) {
if(f < 0)
f = -1*f;
return f;
}
Square Root of a number, given that the number is a perfect square.
The complexity is log(n)
/**
* Calculate square root if the given number is a perfect square.
*
* Approach: Sum of n odd numbers is equals to the square root of n*n, given
* that n is a perfect square.
*
* #param number
* #return squareRoot
*/
public static int calculateSquareRoot(int number) {
int sum=1;
int count =1;
int squareRoot=1;
while(sum<number) {
count+=2;
sum+=count;
squareRoot++;
}
return squareRoot;
}
#include <iostream>
using namespace std;
int main()
{
double x = 1, average, s, r;
cout << "Squareroot a Number: ";
cin >> s;
r = s * 2;
for ( ; ; ) //for ; ; ; is to run the code forever until it breaks
{
average = (x + s / x) / 2;
if (x == average)
{
cout << "Answer is : " << average << endl;
return 0;
}
x = average;
}
}
You can try my code :D
the method that i used here is the Babylonian Squareroot Method
which you can find it here https://en.wikipedia.org/wiki/Methods_of_computing_square_roots