A simple program for splitting numbers does not display zeroes - c

I wrote a simple program in c that accepts two numbers and then splits the first number considering the digits of the second number like this:
Input:
362903157 2313
Output:
36
290
3
157
Everything works just fine, except when there are zeroes in the first number, my program skips them. For instance the upper example gives me this output:
36 293 1 570
And that is mycode:
#include <stdio.h>
int nDigits(unsigned i) {
int n = 1;
while (i > 9) {
n++;
i /= 10;
}
return n;
}
// find the highest multiple of 10
int multipleOfTen(int num){
int multiple = 1;
while(multiple <= num){
multiple *= 10;
if(multiple > num){
multiple /= 10;
break;
}
}
return multiple;
}
int main(){
int n, m, digit;
scanf("%d %d", &n, &m);
int lengthOfM = nDigits(m);
for (int i = 0; i < lengthOfM; i++){
digit = m / multipleOfTen(m); //2
for(int j = 1; j <= digit; j++){
printf("%d", n/multipleOfTen(n));
n = n% multipleOfTen(n);
}
printf("\n");
m = m % multipleOfTen(m);
}
return 0;
}
What should I change in my program so that the zeroes won't be ignored?

Instead of calling multipleOfTen() in each loop, call it once and save the result for both n and m. Then in each loop divide those results by 10
#include <stdio.h>
int nDigits(unsigned i) {
int n = 1;
while (i > 9) {
n++;
i /= 10;
}
return n;
}
// find the highest multiple of 10
int multipleOfTen(int num){
int multiple = 1;
while(multiple <= num){
multiple *= 10;
if(multiple > num){
multiple /= 10;
break;
}
}
return multiple;
}
int main(){
int n, m, digit;
int i, j;
int n10, m10;
scanf("%d %d", &n, &m);
int lengthOfM = nDigits(m);
n10 = multipleOfTen(n); //get the multiple of ten once
m10 = multipleOfTen(m);
for ( i = 0; i < lengthOfM; i++){
digit = m / m10;
m10 /= 10;
for( j = 0; j < digit; j++){
printf("%d", n/n10);
n = n% n10;
n10 /= 10;// divide by 10
}
printf("\n");
m = m % multipleOfTen(m);
}
return 0;
}

I suppose an approach like this is inadmissible?
#include <stdio.h>
#include <string.h>
int main ( void ) {
char n[64];
char m[64];
char * p = n;
int i = 0;
int c;
scanf("%63[0-9] %63[0-9]", n, m);
while ((c = m[i++]) != '\0') {
int j = c - '0';
while (j-- > 0) if (*p) putchar(*p++);
putchar(' ');
}
putchar('\n');
return 0;
}

when n=903157 and after n = n% multipleOfTen(n); n becomes 3157 not 03157 so when u dividing again in line printf("%d", n/multipleOfTen(n)); it prints 3 not 0 what you want!!
Fix your code to produce right output.

Related

Why does my program only work half the time?

I have an assignment to write a program for a natural number where its inverse is divisible by its number of digits. A natural number n ( n > 9) is entered from the keyboard. To find and print the largest natural number less than n that its inverse is divisible by its number of digits. If the entered number is not valid, print a corresponding message (Brojot ne e validen).
I have tried :
#include <stdio.h>
int main() {
int n,r,s=0,a=0;
int m;
scanf("%d",&n);
int t=n;
if(t<10)
{ printf("Brojot ne e validen");}
else {
for (int i = n - 1; i > 0; i--) {
while (n != 0) {
r = n % 10;
s = (s * 10) + r;
n = n / 10;
a++;
if (s % a == 0) {
m = i;
break;
}
}
}
printf("%d\n", m);
}
return 0;
}
And when my inputs is 50, it gives the correct answer which is 49, but when I try numbers like 100 or 17 it prints 98 instead of 89 and 16 instead of 7 respectively. I have been baffled by this for more than an hour now
check your logic.
you can check each value by
#include <stdio.h>
int main() {
int t,r,s=0,a=0;
int m;
scanf("%d",&t);
if(t<10)
{ printf("Brojot ne e validen");}
else {
for (int i = t - 1; i > 0; i--) {
while (t != 0) {
r = t % 10;
printf("%d \n", r);
s = (s * 10) + r;
printf("%d \n", s);
t = t / 10;
printf("%d \n", t);
a++;
if (s % a == 0) {
m = i;
break;
}
}
}
printf("%d\n", m);
}
return 0;
}

for loop unexpectedly jumping down in value

Goldbach's conjecture states that every even integer over 4 is the sum of two primes, I am writing a program in C to find these pairs. To do this it first finds all the primes less than a user given number. I have a for loop to iterate from 4 to the user given number and find the pairs within the loop body. When that loop gets to about around 40, suddenly jumps back down by about 30 and then continues to iterate up (with user input 50 it jumped from 38 to 9, with input 60 it jumped from 42 to 7). I can't figure out why this is happening. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <unistd.h>
struct pair{
int a;
int b;
}pair_t;
int main(){
int N;
int numPrimes = 1;
int *primes = malloc(100*sizeof(int));
int isPrime = 1;
primes[0] = 2;
int timesRealloc = 0;
int availableSlots = 100;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
struct pair pairs[N/2 + 4];
int j = 0;
int i;
for (i = 3; i <= N; i+=2){
j = 0;
isPrime = 1;
while (primes[j] <= sqrt(i)) {
if (i%primes[j] == 0) {
isPrime = 0;
break;
}
j++;
}
if (isPrime == 1){
primes[numPrimes] = i;
numPrimes++;
}
if (availableSlots == numPrimes){
timesRealloc++;
availableSlots += 100;
primes = realloc(primes, availableSlots*sizeof(int));
}
}
printf("The largest prime I found was %d\n", primes[(numPrimes-1)]);
int k;
for (i=4; i<=N; i+=2){
printf("i is %d, N is %d\n", i, N);
if (i > N){ break; }
for (j=0; j<numPrimes; j++){
for (k=0; k<numPrimes; k++){
int sum = primes[j] + primes[k];
if(sum == i){
pairs[i].a = primes[j];
pairs[i].b = primes[k];
}
}
}
}
for (i=4; i<=N; i+=2){
printf("%d is the sum of %d and %d\n", i, pairs[i].a, pairs[i].b);
}
return 0;
}
You attempt to be space efficient by compressing the pairs array to just hold every other (even) number and start from 4 instead of zero. However, you miscalculate its size and then when you go to use it, you treat it like it hasn't been compressed and that there's a slot for every natural number.
The code suffers from having the prime array calculation in main() along with the other code, this is best separated out. And when it looks for pairs, it doesn't quit when it finds one, nor when it starts getting sums greater than the target. My rework below attempts to address all of these issues:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#define INITIAL_SLOTS (100)
struct pair {
int a;
int b;
} pair_t;
int compute_primes(int limit, unsigned **primes, int size) {
int numPrimes = 0;
(*primes)[numPrimes++] = 2;
for (int i = 3; i <= limit; i += 2) {
bool isPrime = true;
for (int j = 0; (*primes)[j] <= i / (*primes)[j]; j++) {
if (i % (*primes)[j] == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
(*primes)[numPrimes++] = i;
}
if (numPrimes == size) {
size *= 2;
*primes = realloc(*primes, size * sizeof(unsigned));
}
}
return numPrimes;
}
int main() {
int N;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
unsigned *primes = calloc(INITIAL_SLOTS, sizeof(unsigned));
int numPrimes = compute_primes(N, &primes, INITIAL_SLOTS);
printf("The largest prime I found was %d\n", primes[numPrimes - 1]);
struct pair pairs[(N - 4) / 2 + 1]; // compressed data structure
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
bool found = false;
for (int j = 0; ! found && j < numPrimes; j++) {
for (int k = 0; ! found && k < numPrimes; k++) {
int sum = primes[j] + primes[k];
if (sum == i) {
pairs[offset].a = primes[j];
pairs[offset].b = primes[k];
found = true;
} else if (sum > i) {
break;
}
}
}
}
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
printf("%d is the sum of %d and %d\n", i, pairs[offset].a, pairs[offset].b);
}
free(primes);
return 0;
}
OUTPUT
> ./a.out
Please enter the largest even number you want to find the Goldbach pair for:
10000
The largest prime I found was 9973
4 is the sum of 2 and 2
6 is the sum of 3 and 3
8 is the sum of 3 and 5
10 is the sum of 3 and 7
12 is the sum of 5 and 7
14 is the sum of 3 and 11
...
9990 is the sum of 17 and 9973
9992 is the sum of 19 and 9973
9994 is the sum of 53 and 9941
9996 is the sum of 23 and 9973
9998 is the sum of 31 and 9967
10000 is the sum of 59 and 9941
>

How to find largest sum of divsors of a number between 2 and N?

I have a simple math problem. I want to find a number in the range [2,N] (excluding 1 and N from the divisors) with the largest sum of divisors. For example, for N = 100 the number with the highest sum of divisors between 2 and 100 is 96, which has the sum of all its divisors equal to 155.
I wrote the following program to show me the sum of that number's divisors but couldn't figure out how to get that number itself. How do I find and print that number?
int main(int argc, char const *argv[])
{
int N,
sum,
max=0;
scanf("%d", &N);
int i = 0,
d = 0;
for(i=2; i<=N; i++)
{
sum=0;
for(d = 2; d < i; d++)
{
if(i % d == 0)
{
sum += d;
}
}
if(sum > max)
{
max = sum;
}
}
printf("%d\n", max);
return 0;
}
Others have well shown how to save and report the i at which the maximum occurred.
Yet I wanted to add how OP's approach can be significantly faster: Iterate up to the square root of N rather than N. This way is about square_root(N) times faster. No so important when N is 100, but significant for larger ones.
#include <stdlib.h>
#include <stdio.h>
void print_maxsumdiv(int N, int mode) {
unsigned long long loop_count = 0;
int sum, max = 0;
int max_i = 0;
int i = 0, d = 0;
for (i = 2; i <= N; i++) {
sum = 0;
if (mode) {
// Iterate up to the just under the square root of `i`
for (d = 2; d < i/d; d++) {
loop_count++;
if (i % d == 0) {
sum += d + i/d; // Add both dividers
}
}
if (d == i/d) { // perfect square
sum += d;
}
}
else {
// Iterate up `i` (OP's original approach)
for (d = 2; d < i; d++) {
loop_count++;
if (i % d == 0) {
sum += d;
}
}
}
if (sum > max) {
max = sum;
max_i = i;
}
}
printf("i:%6d max:%9d (count:%12llu)\n", max_i, max, loop_count);
}
int main() {
for (int mode = 0; mode < 2; mode++) {
print_maxsumdiv(100, mode);
print_maxsumdiv(10000, mode);
//print_maxsumdiv(1000000, mode);
}
return 0;
}
Output
i: 96 max: 155 (count: 4851)
i: 9240 max: 25319 (count: 49985001)
i: 96 max: 155 (count: 480)
i: 9240 max: 25415 (count: 646800)
It should be easy. Just introduce one more variable valueForMax
int N,
sum,
max=0,
valueForMax = 0;
and update it together with max
if(sum > max)
{
valueForMax = i;
max = sum;
}
Then you can
printf("best value %d, sum = %d\n", valueForMax, max);
When you save max, you just need to save a copy of i in a separate variable.
Here's a working program:
#include <stdio.h>
int
main(int argc, char const *argv[])
{
int N,
sum,
max = 0;
int max_i = -1;
printf("Enter N: ");
fflush(stdout);
scanf("%d", &N);
int i = 0,
d = 0;
for (i = 2; i <= N; i++) {
sum = 0;
for (d = 2; d < i; d++) {
if (i % d == 0) {
sum += d;
}
}
if (sum > max) {
max = sum;
max_i = i;
}
}
printf("MaxSum:%d Index:%d\n", max, max_i);
return 0;
}
Here's the output:
MaxSum:155 Index:96

How many times a digit is appeared in a number

Well, I wrote the code and everything is fine except one thing.
When I enter that digit number, which has to be upto 10 digits, I recieve in arr[0] various values, for example, if I enter "12345" I get 20, 1 , 1 , 1 , 1 , 1 , 0 ,0 ,0 ,0.
Which is fine from arr[1] to arr[9], but pretty odd in arr[0].
Any ideas?
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main()
{
int i,j,p=0, temp,indexNum, arr[10] = { 0 }, num, level = 10, level2 = 1,maxIndex;
printf("Please enter a digit number (upto 10 digits) \n");
scanf("%d", &num);
temp = num;
while (temp > 0)
{
p++;
temp /= 10;
}
for (i = 0;i < p;i++)
{
temp = num;
while (temp > 0)
{
indexNum = num % level / level2;
arr[indexNum]++;
level *= 10;
level2 *= 10;
temp /= 10;
}
}
for (j = 0; j < 10; j++)
{
printf("%d\n", arr[j]);
}
getch();
}
Here is simplified version of your program:
#include <stdio.h>
#include <math.h>
int main()
{
int i = 0, j = 0, temp = 0, indexNum = 0, num = 0, level = 10;
int arr[10] = {0};
num = 7766123;
temp = num;
if(0 == temp) arr[0] = 1; // Handle 0 input this way
while (temp > 0)
{
indexNum = temp % level;
arr[indexNum]++;
temp /= 10;
}
for (j = 0; j < 10; j++)
{
printf("%d\n", arr[j]);
}
return 0;
}
A few hints to help you:
What does arr[10] = { 0 } actually do?
When you calculate indexNum, you are dividing integers. What happens when the modulus is a one-digit number, and level2 is greater than 1?
It's probably easier to read the input into a string and count digit characters. Something like this (not tested):
std::map<char, int> count;
std::string input;
std::cin >> input;
for (auto iter = input.begin(); iter != input.end(); ++iter) {
if (*iter < 0 || *iter > 9)
break;
else
++count[*iter];
}
for (auto iter = count.begin(); iter != count.end(); ++iter) {
std::cout << *iter << '\n';
}
You need to get rid of your first for loop. Something more like:
#include <stdio.h>
#include <math.h>
using namespace std;
int main()
{
int j;
int temp;
int indexNum;
int arr[10] = { 0 };
int num;
int level = 10;
int level2 = 1;
printf("Please enter a digit number (upto 10 digits) \n");
scanf("%d", &num);
temp = num;
while (temp > 0)
{
indexNum = num % level / level2;
arr[indexNum]++;
level *= 10;
level2 *= 10;
temp /= 10;
}
for (j = 0; j < 10; j++)
{
printf("%d\n", arr[j]);
}
return 0;
}
Check the program below.
void count_digits(unsigned int a, int count[])
{
unsigned int last_digit = 0;
if (a == 0) {
count[0] = 1;
}
while (a != 0)
{
last_digit = a%10;
count[last_digit]++;
a = a/10;
}
}
int main()
{
int count[10]= {0};
unsigned int num = 1122345; /* This is the input, Change it as per your need */
int i = 0;
count_digits(num, count);
for (i = 0; i < 10; i++)
{
printf ("%d: -- %d\n", i, count[i]);
}
return 0;
}

Largest palindrome made from the product of two 3-digit numbers with C

The code is trying to find the largest palindrome made from the product of two 2-digit numbers. The answer is 91*99 = 9009 but I keep getting 990, which is not even a palindrome. I really appreciate the help!
#include <stdio.h>
int main()
{
int i = 10;
int j = 10;
int a = 0;
int b = 0;
int array[100] = {0};
int divider = 10;
int num;
int great;
int product;
int n;
int flag;
/*Loop through first 2 digit number and second 2 digit number*/
while (i<100)
{
while (j < 100)
{
product = i*j;
array [a] = product % 10;
n = product / divider;
while (n != 0)
{
a++;
num = n%10;
divider *=10;
array[a]=num;
n = product/divider;
}
flag = 0;
while (b<a)
{
if (array[b] != array[a])
{
flag = 1;
}
b++;
a--;
}
if (flag == 0)
{
great = product;
}
j++;
a = 0;
b = 0;
}
i++;
}
printf("The largest palindrome is %d \n", great);
return 0;
}
Here is a code snippet you can try.
#include <stdio.h>
void main()
{
int a = 1; // first integer
int b = 1; // second integer
int currentNumber;
int currentPalin; if a palindrome is found, its stored here
while (a<100){ //loop through the first number
while (b<100){ // loop through the second number
currentNumber = a*b;
if (currentNumber == reverse(currentNumber) ){ //check for palindrome
currentPalin = currentNumber;
}
b = b+1; //increment the second number
}
b = a; // you could have set b=1 but it would not be an efficient algorithm because
//some of the multiplication would occur twice. eg- (54*60) and (60*54)
a = a +1; //increment the first number
}
printf ("Largest palindrom is %d \n", currentPalin);
getchar();
}
// method for finding out reverse
int reverse(int n){
int reverse = 0;
while (n != 0)
{
reverse = reverse * 10;
reverse = reverse + n%10;
// when you divide a number by 10, the
//remainder gives you the last digit. so you are reconstructing the
//digit from the last
n = n/10;
}
return reverse;
}
Update:- As suggested by M Oehm, I have modified the code to make it more general.
#include <stdio.h>
void main()
{
int a = 1;
int b = 1;
int currentNumber;
int currentPalin=0;
while (a<100){
while (b<100){
currentNumber = a*b;
if (currentNumber == reverse(currentNumber) ){
if (currentNumber>currentPalin){
currentPalin = currentNumber;
}
}
b = b+1;
}
b = 1;
a = a +1;
}
if (currentPalin==0){
printf("No Palindrome exits in this range");
}
else {
printf ("Largest palindrome is %d \n", currentPalin);
}
getchar();
}
int reverse(int n){
int reverse = 0;
while (n != 0)
{
reverse = reverse * 10;
reverse = reverse + n%10;
n = n/10;
}
return reverse;
}
An alternative approach to solve the problem.
#include<stdio.h>
int reverse(int num)
{
int result = 0;
while( num > 0)
{
result = result * 10 + (num%10);
num/=10;
}
return result;
}
int main()
{
int last_best = 1;
int best_i=1;
int best_j = 1;
const int max_value = 99;
for( int i = max_value ; i > 0 ; --i)
{
for(int j = i ; j > 0 ; --j){
int a = i * j;
if( last_best > a )
break;
else if ( a == reverse(a) )
{
last_best = a;
best_i = i;
best_j = j;
}
}
}
printf("%d and %d = %d\n", best_i,best_j,last_best);
}
And it is quite simple to follow.
It seems that you do not reinitialize variables at the beginning of loop. They keeps values from previous iterations. For example, j and divider. Put
j = 10;
before starting "j" loop, i.e.:
j = 10;
while (j < 100) ...
The same for divider:
...
j = 10;
while (j < 100) {
divider = 10;
...
If you were using for loops you would avoid this problem naturally:
for(i=10; i<100; i++) {
for(j=10; j<100; j++) {
...
}
}

Resources