I am having issues with a task I've done, it outputs answer correctly without any errors. It gives me 2/3 points, last shows error, and doesn't show what. I've no clue what I've done wrong. Can someone have a look at this please.
Task:
A perfect number is a natural number that is equal to the sum of all its natural divisors (different from itself).
6 = 1 + 2 + 3
28 = 1 + 2 + 4 + 7 + 14
A redundant number is a natural number which is greater than the sum of all its natural divisors (different from itself).
9> 1 + 3
The deficit number is a natural number that is less than the sum of all its natural divisors (different from itself).
12 <1 + 2 + 3 + 4 + 6
Input
A natural number N (N <1000) followed by N natural numbers (not greater than 32000).
Remember 0 is an natural number.
For each of the numbers given in the input, the program should print a line of the form on the screen:
X - perfect / redundant / deficit number
depending on the type of number.
Sample input
6 15 28 6 56 22 496
Sample output
15 - redundant number
28 - perfect number
6 - perfect number
56 - deficit number
22 - redundant number
496 - a perfect number
#include <iostream>
using namespace std;
void ifPerfect(int n)
{
int sum = 0;
for (int i = 1; i <= n / 2; i++)
if (n % i == 0)
sum += i;
if (sum == n)
{
cout << n << " - perfect number" << endl;
}
}
void ifRedundant(int n)
{
int sum = 0;
for (int i = 1; i < n; i++)
{
if (n % i == 0)
{
sum += i;
}
}
if (n > sum)
{
cout << n << " - redundant number" << endl;
}
}
void ifDeficit(int n)
{
int sum = 0;
for (int i = 1; i < n; i++)
{
if (n % i == 0)
{
sum += i;
}
}
if (n < sum)
{
cout << n << " - deficit number" << endl;
}
}
int main()
{
int n;
cin >> n;
if (n >= 0 && n < 1000)
{
int *tab = new int[n];
for (int i = 0; i < n; i++)
{
cin >> tab[i];
}
for (int i = 0; i < n; i++)
{
ifRedundant(tab[i]);
ifPerfect(tab[i]);
ifDeficit(tab[i]);
}
delete[] tab;
return 0;
}
}
According to Wiki (https://en.wikipedia.org/wiki/Perfect_number), 0 is NOT a perfect number, while your program would say that it is.
Given an input of 0, you program will produce an incorrect answer.
The clue was the statement "Remember 0 is an natural number."
While natural, it is not perfect.
I should mention the purpose of this code is to tackle a leading zero scenario when finding date palindromes in dates in format MMDDYYY.
Here is the code.
#include <iostream>
using namespace std;
unsigned numDigits (unsigned num)//this works
{
if (num < 10) return 1;
return 1+ numDigits(num/10);
}
int main ()
{
unsigned date = 1111110;//01/11/1110(jan 11th of 1110 is palindrome)
cout<<numDigits(date)<<"num of dig"<<endl;
if (numDigits(date) == 7)
{
unsigned array[8];
unsigned number = date;
unsigned revArr[8];
for (int h = 7; h >= 0; h--) //this pops array withdate
{
array[h] = number % 10;
number /= 10;
cout<<array[h]<<endl;
}
cout<<"vs"<<endl;
for (int i = 0; i < 8; i++) //this pops revarray withdate
{
revArr[i] = number % 10;
number /= 10;
cout<<array[i]<<endl;
}
for (int j = 0; j < 8; j++)
{
if (array[j] == revArr[j])
{
cout<<j<<"th digit are" <<" equal"<<endl;
}
}
}
return 0;
}
In this case both of the arrays are identical, I don't underdtdanwd why array[0] == revArr[0] but array[1] != revArr[1] and so on but array[7] == revArr[7] again... its boggling my mind.
The loops traverse all elements of the array. Even when the expression number /= 10 is equal to 0. In this case the zero is stored in the array elements because 0 / 10 gives again 0.
Before the second loop write
number = date;
I am solving a problem in which I have to find those element from the array whose total gives maximum sum. But there is a condition that no two adjacent element can be the part of that max subarray. Here is my code using simple brute Force solution-
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t != 0)
{
int n, i, s, k = 0, m = -1001;
vector< int > a;
cin >> n;
a.resize(n, 0);
vector< int > b;
for (i = 0; i < n; i++)
{
cin >> a[i];
m = max(m, a[i]);
if (a[i] < 0)
{
a[i] = 0;
++k;
}
}
if (k == n)
cout << m;
else
{
k = 0;
s = a[0];
b.push_back(a[0]);
for (i = 1; i < n; i++)
{
if (i != k + 1)
{
if (a[i])
{
s += a[i];
b.push_back(a[i]);
k = i;
}
}
else
{
if (s - a[i - 1] + a[i] > s)
{
b.pop_back();
s -= a[i - 1];
s += a[i];
b.push_back(a[i]);
++k;
}
}
}
}
cout << endl;
for (i = n; i >= 0; i--)
{
if (b[i])
cout << b[i] << " ";
}
cout << endl;
--t;
}
return 0;
}
Here is input to code-
First line represent no. of test cases,
Second line represent size of array
And the next line shows array elements.m
5
5
-1 7 8 -5 4
4
3 2 1 -1
4
11 12 -2 -1
4
4 5 4 3
4
5 10 4 -1
Output-
4 8
32 32607 -787829912 1 3
32 32607 -787829912 12
3 5
10
Expected output-
4 8
1 3
12
3 5
10
So, there are 5 test cases. For the first test case and last two test case output is correct. But for second and third test case it is giving garbage value. What is the problem, that for some test cases it is giving garbage value, and for other not.
for (i = n; i >= 0; i--)
{
if (b[i])
cout << b[i] << " ";
}
This prints out n+1 values in b. But even in the best case, b only has n values (for n=1). And for n>1, b.size() is less than n, so you are reading garbage from outside the vector's storage (this is undefined behavior). Just use the correct bound:
for (i = b.size() - 1; i >= 0; ++i)
I think I found your (first) problem:
if(k==n)
cout<<m;
When all numbers are negative this outputs the largest of them.
But the empty array has a sum of 0 and is larger than a negative number and has no 2 adjacent members in it. So clearly the right answer should be 0, not m.
using loops, how to find occurences of each digit in integer interval [n, m]?
for example:
INPUT n,m = [19, 23] = 19, 20, 21, 22, 23
OUTPUT should be:
0 occurences: 1 times
1 occurences: 2 times
2 occurences: 5 times
3 occurences: 1 times etc.
#include <iostream>
using namespace std;
int main()
{
int i, j, z, count, n, m;
cin >>n >>m;
for(int i=0; i<10; i++) // LOOP FOR DIGITS
{
cout << i <<"occurences: ";
count=0;
for(int j=n; j<m; j++) // LOOP INTEGER INTERVAL
{
while (z!=0)
{
z = j % 10; // LAST DIGIT OF FIRST NUMBER IN INTERVAL
if (z == i) count++;
z /= 10;
}
}
cout << count <<" times"<< endl;
}
}
my code returns 0 times for each digit, where is the error?
You don't need to loop over the range 10 times.
int n, m;
cin >> n >> m;
counts = int[10];
for(int i = 0; i < 10; ++i) {
counts[i] = 0;
}
for(int j = n; j <= m; j++) {
int z = j;
do {
int digit = z % 10; // LAST DIGIT OF FIRST NUMBER IN INTERVAL
counts[digit]++;
z /= 10;
} while (z != 0);
}
for(int i = 0; i < 10; ++i) {
cout << i << " occurrences " << counts[i] << " times";
}
You can use std::stringstream to get each digit in a number like so:
constexpr int n = 19;
constexpr int m = 23;
std::array<int, 10> digit_count = {0};
for (int i = n; i <= m; i++)
{
std::stringstream s;
s << i;
unsigned char digit;
while (s >> digit) digit_count[digit - '0']++;
}
Some issues that I see:
z = j % 10;
You need to intialize z outside your while loop to j Also you want to get the mod but not set z to it. try putting the result into a temp variable as opposed to into z.
Your for loop is not inclusive of the last number. for(int j=n; j<m; j++) should be j<=m.
z = j;
while (z!=0)
{
int mod = z % 10; // LAST DIGIT OF FIRST NUMBER IN INTERVAL
if (mod == i) count++;
z /= 10;
}
}
This final code gives the correct result:
#include <iostream>
using namespace std;
int main()
{
int i, j, z, count, n, m;
cin >>n >>m;
for(int i=0; i<10; i++) // LOOP FOR DIGITS
{
cout << i <<" occurences: ";
count=0;
for(int j=n; j<=m; j++) // LOOP INTEGER INTERVAL
{
z = j;
while (z!=0)
{
int mod = z % 10; // LAST DIGIT OF FIRST NUMBER IN INTERVAL
if (mod == i) count++;
z /= 10;
}
}
cout << count <<" times"<< endl;
}
}
19 23
0 occurences: 1 times
1 occurences: 2 times
2 occurences: 5 times
3 occurences: 1 times
4 occurences: 0 times
5 occurences: 0 times
6 occurences: 0 times
7 occurences: 0 times
8 occurences: 0 times
9 occurences: 1 times
Basically, the modulo operation is used to retrieve the least significant digit of any number. Dividing this number with the radix will remove the least significant digit, making the next digit the new least significant digit.
int main(int argc, char *argv[])
{
int radix = 10;
int x, y;
printf("Lower bound: ");
scanf("%d, &x);
printf("Upper bound: ");
scanf("%d, &y);
int digits[radix];
count_digit_occurence(x, y, radix, digits);
int i;
for (i = 0; i < radix; ++i)
{
int occ = digits[i];
printf("%d occurred %d times\n", i, occ);
}
}
void count_digit_occurence(int x, int y, int radix, int digits[radix])
{
int i, n;
for (i = x; i <= y; ++i)
{
n = i;
while (n > 0)
{
++(digits[n % radix]);
n /= radix;
}
}
}
All the answers so far provide algorithms with complexity O(m-n) at best, i.e. linear in the distance from n to m. Here, I provide a method that has logarithmic complexity. The basic idea is to consider the last digit of each number first, then the second last etc.
In order to simplify the code, I change the problem slightly and consider the range [n, m-1], i.e. excluding m.
There are m-n numbers in this range; if this is is a multiple of 10, then each last digit occurs exactly (m-n)/10 times. Otherwise, we must account for the edges. The following routine adds to count unit times the number of occurrences of the last digits in all numbers in the range from n to m-1 inclusive.
void count_last_digits(int n, int m, std::array<int,10> count&, int unit=1)
{
// 1 increment n until it has the same last digit as m
for(int dn=n%10, dm=m%10; n<m && dn!=dm; dn=++n%10)
count[dn] += unit;
// 2 add unit*(m-n)/10 to all counts
if(int cnt = unit*(m-n)/10) // avoid to add nothing
for(int d=0; d!=10; ++d)
count[d] += cnt;
}
Once, we counted the last digits, we count the second last digits etc. First, we need a helper function that just counts the digits of a single number
void count_digits(int x, std::array<int,10> &count, int unit=1)
{
for(; x; x/=10)
count[x%10] += unit;
}
To proceed with the second last digits, we first trim (using this helper function) the interval such that both n and m are multiples of 10, then divide them both by 10, multiply the unit of counting by 10, and recurse
std::array<int,10> count_all_digits(int n, int m)
{
std::array<int,10> count={0};
for(int unit=1; n<m; n/=10,m/=10,unit*=10) {
// count last digits
count_last_digits(n, m, count, unit);
// increment n to the next multiple of 10, but not above m
if(int inc = std::min(10-(n%10), m-n)) {
count_digits(n/10, count, unit*inc);
n += inc;
}
// decrement m to the previous multiple of 10, but not below n
if(int dec = std::min(m%10, m-n)) {
count_digits(m/10, count, unit*dec);
m -= dec; // not really necessary
}
}
return count;
}
The functions count_last_digits() and count_digits() have complexity O(1) and O(ln(x)), respectively. Both are called O(ln(m)) times, so the latter dominates the overall complexity, which is O(ln(m)^2).
Note that these functions assume 0 < n <= m, i.e. n<=0 is not allowed.
The program i am designing is for an assignment, but as a do distant learning it is not easy finding a solution.
The program that I have to create must first ask user for an unsigned long int and then break that number down to each digit without repeating number (for example 3344 the program should list 3 and 4), my program just lists all digits. After they have been listed the position of that digits needs to be dispayed with the position (digit at the right is position 0). Then the program should be "reconstruct" to make the original unsigned long int.
An example of what it should look like :
7377683
3 : 0 5
6 : 2
7 : 3 4 6
8 : 1
7377683
The code that i am using currently :
#include <iostream>
using namespace std;
int main()
{
unsigned long int number;
cout << "Enter an integer " << endl;
cin >> number;
for(int i=0; i<10 ; i++)
{
if (number > 0)
{
cout << number%10 << " : " << i; //output digit and position
cout << "\n";
number /= 10;
}
}
return 0;
}
I cannot use arrays or strings to complete this task and that is what i am finding challenging.
You could store digit positions in a decimal bitmask type thing.
unsigned long n, digits[10]{};
// Input
std::cin >> n;
// Break down
for (int i = 1; n; i *= 10, n /= 10)
digits[n % 10] += i;
// Reconstruct and print digit positions
for (int i = 0; i < 10; i++) {
if (!digits[i])
continue;
n += digits[i] * i;
std::cout << i << ":";
for (int j = 0; digits[i]; j++, digits[i] /= 10)
if (digits[i] % 10)
std::cout << " " << j;
std::cout << std::endl;
}
// Output
std::cout << n;
It's kinda neat because you don't need to know how many digits your number has. Also, you could construct the new number and output the positions of all digits in the same loop which you are breaking it down, thus removing the need to store the digits anywhere, but that feels like cheating.
Since you can't use arrays or strings you can probably get away with using an integral type as a bitmap. Any time you output a number in your loop set a bit in the bitmap that corresponds to that number. Then when you need to output that number you check to see if that bit is set and if it is you skip printing it out. Something like the following maybe.
for (int mask = 0, i = 0; i<10; i++)
{
if (number > 0)
{
int value = number % 10;
if ((mask & (1 << value)) == 0)
{
cout << value << " : " << i << endl; //output digit and position
mask |= 1 << value;
}
number /= 10;
}
}
Taking a number down into individual digits works like this:
int number = 4711;
vector<int> v;
while(number > 0)
{
int digit = number % 10;
number /= 10;
v.push_back(digit);
}
Putting it back together again into an integer (we need to go "backwards", as the digits come out "back to front" in the above code)
int number = 0;
for(int i = v.size()-1; i >= 0; i--)
{
number *= 10;
number += v[i];
}
I'm intentionally not showing a complete program to solve your problem, since part of learning programming is to learn how to solve problems. But you sometimes need a few "steps" on the way.
Something like this would solve it with arrays:
int array[10][10] = { { 0 } }; // Position of each digit.
int count[10] = { 0 }; // Number of each digit
int number = 4711;
int pos = 0;
while(number > 0)
{
int digit = number % 10;
number /= 10;
count[digit]++;
array[digit][count[digit]] = pos;
pos++;
}
I'm leaving it to you to fill in the rest of the code (to print and reassemble the number). [The above code doesn't cope with the number zero].
This is the working solution which address to the most crucial problem in your question:
int number = 7377683;
int temp = number;
int pos = 0;
int counter = 0;
int currNum;
int uniqueCount = 0;
Added: Codes to check number of unique digits in number:
for (int x=0; x<9; x++)
for (int y=temp; y>0; y/=10)
if (y%10 == x)
{
uniqueCount ++;
break;
}
Codes to generate the output of every unique elements and positions:
for (int y=0; y<uniqueCount; y++)
{
pos = counter;
currNum = number%10;
cout << temp%10 << " : ";
for (int x=temp; x>0; x/=10)
{
if (temp%10 == currNum)
cout << pos << " ";
pos++;
temp /= 10;
}
counter++;
number /=10;
temp = number;
cout << endl << endl;
}
Program Output:
3 : 0 5
8 : 1
6 : 2
7 : 3 4 6
This solution is using the most basic construct without array (according to your requirements).