Count the number of integers in C - c

so I want to create a code that finds the quantity of numbers in a number. So this may sound weird, but it works something like this.
Input
12893012
Output
1 2 2 1 0 0 0 0 1 1
So the output means that in 12893012, there is one 0, two 1's, two 2's, one 3, no 4, no 5, no 6, no 7, one 8, and one 9.
#include <stdio.h>
int main()
{
int n,count=0;
printf("Enter an integer: ");
scanf("%d", &n);
while(n!=0)
{
n/=10; /* n=n/10 */
++count;
}
printf("Number of digits: %d",count);
}
My code only seems to find the number of digits in the number, any ideas? Thanks a lot btw.

Put it in an array and count.
Roughly,
int count[10] = {0};
while(n != 0)
{
count[n % 10]++;
n /= 10;
}
Print out the result.

You keep incrementing count but without checking the digit. This will just give you the number of digits. You need an array in which you can store the count for each digit.
int digitCounts[10];
//...
while (n != 0){
digitCounts[n % 10]++;
n /= 10;
}
You can use mod (%) to make it easier, because % 10 gives the last digit.

Make an array that stores the digit count. Remainder operator will give you the last digit which will be between 0 and 9.
int digit[10];
//...
while(n!=0)
{
int d = n % 10;
digit[d]++
//...
And then print it in a loop.

I suggest creating an array (or 10 variables) which hold quantitiy of digits, then reading digits one by one and checking what digit it is.
You can read single digit using
scanf(%1d, &variableName)
or
getchar()
functions.

all thanks go to #rohit89,#this and #Arc676
this is just a correction when zero (0) is entered
int count[10] = {0};
if(n){
while(n != 0)
{
count[n % 10]++;
n /= 10;
}
}else
count[0]=1;

Related

Round numbers to multiples of 10 by saving the first 2 digits and replacing the rest with 0

I need to round off the following numbers and retain the first two digits to do further calculations.I can't use the while neither the for.
I don't know how to do it, can anyone help me?
438332 = 430000
56322 = 56000
1256489 = 1200000
I wrote a recursive function so that it does not use while or for (what a stupid requirement!!)
The routine below keeps dividing the number by 10, until n only has 2 digits left (n < 100), while tracking how many 0's to put on the number.
For example, when the problem is 438332, at the base of the recursion, n = 43, and the calling functions will multiple by 10000, so the product is 430000, the expected answer.
#include <stdio.h>
int sigfigs2(int n)
{
return (n<100)? n : sigfigs2(n/10)*10;
}
int main(void) {
int test[] = {438332, 56322, 1256489};
for(int i=0; i<sizeof(test)/sizeof(*test); ++i)
{
printf("%d ==> %d\n", test[i], sigfigs2(test[i]));
}
return 0;
}
Output
Success #stdin #stdout 0s 5424KB
438332 ==> 430000
56322 ==> 56000
1256489 ==> 1200000
A trivial example like this
int roundNum(int num) {
int count = 0;
while (num > 100) {
num = ( num / 10 );
count ++;
}
while (count > 0) {
num *= 10;
count --;
}
}
FYI, this might be inefficient
I think you can easily use %1d placeholder to only read first two digits and then use strategy of taking mod with 10 to get total number of digits

How can I locate the same highest digit?

This code can locate the same digit in a multiple numbering system. The problem I have is that how can I locate the same highest digit if there is another same digit but lower?
Example Output
Can locate the same digit
Enter the random number: 32432
Greatest digit that occurred more than once = 3
Cannot locate the same highest digit because the program can only locate the lowest
Enter the random number: 34745676
Greatest digit that occurred more than once = 4
#include <stdio.h>
int main() {
char c;
int counts[10] = {0,0,0,0,0,0,0,0,0,0};
int max = 0;
printf("Enter the random number: ");
while(c=getc(stdin)){
if (c=='\n') break;
counts[c-'0']++;
}
for(int i=3; i<8; i++) {
if(counts[i] > counts[max]) max=i;
}
printf("Greatest digit that occurred more than once = %i",max);
return 0;
}
Rather then search only for digits 3 to 7, search digits 0 to 9.
Look for counts > 1
Recognize that there may be no solution with a digit that occurs 2 or more times.
There may exist more than 1 digit with the same max count greater than 1. Below simply reports the first one. You may want something different.
Use an int c to distinguish the 257 different results from getc().
Be prepared to handle input that is not a digit nor '\n'.
Append a '\n' to output.
...
// char c;
int c;
int counts[10] = {0,0,0,0,0,0,0,0,0,0};
int max = 0;
printf("Enter the random number: ");
while(c=getc(stdin)){
// if (c=='\n') break;
if (!isdigit(c)) break;
counts[c-'0']++;
}
// for(int i=3; i<8; i++) {
for(int i=0; i<10; i++) { // Note 1
// if(counts[i] > counts[max]) max=i;
if(counts[i] > 1 && counts[i] > counts[max]) max=i; // Note 2
}
if (counts[max] > 1) {
printf("Greatest digit that occurred more than once = %i\n",max);
} else {
printf("Greatest digit that occurred more than once did not occur\n", max);
}
Note 1: Could start at 1 as 0 is the default max.
Note 2: Could omit the counts[i] > 1 && as that consideration is tested after the loop. Left it in here as conceptually we only want to consider cases where the count is > 1.
Assumptions
You for loop runs from 3 to 8 which means it does not scan every cell of the array. Even if you scan it from 0 to 9 you will still not be able to get the output you want.
Explanation
If i understood corectly, for the input 34745676 the correct result is 7.
If that's the case you have to change your for in some way, because right now as soon as it finds the max value the condition won't be true if another digit later (which means higher digit) has the same value in order to change the value of max.
One Solution
Change your for loop to:
int max = 0;
for (int i = 1; i < 10; i++)
if (counts[i] >= counts[max])
max = i;
Demonstration
With input = 34745676 your array will look something like this after the while loop:
counts[10] = { 0, 0, 0, 1, 2, 1, 2, 2, 0, 0 }
Since the condition inside for is true if there is a greater value or the same value from the current max value, 2 >= 2 is true, hence the assignment max = i will occur on equal values as well and since the array is scanned 0 to 9, position of higher digit will be assigned last each time even if there is the same value on a lower digit.

How to see if integer has a specific digit in it in C

I need to build a program, that would write all numbers from 0 to 100, but will place an * instead of any number that contains the digit 3 or can be divided by 3. This is what I have so far. How can I make it work?
#include <stdio.h>
main() {
int i, c;
c = 100;
for (i = 0; i <= c; i++) {
if (i % 3 == 0) {
printf("*");
}
if (i)
printf("%d\n", i);
}
}
place an * instead of any number that contains the digit 3 or can be divided by 3.
OP's code took care of the "can be divided by 3" with i % 3 == 0.
How about a little divide and conquer for the "contains the digit 3"? Put a function in there.
if (contains_the_digit(i, 3) || (i % 3 == 0)) {
printf("*\n");
} else {
printf("%d\n", i);
}
Now what is left is to define contains_the_digit(int i, int digit)
Mathematically (nice and efficient):
bool contains_the_digit_via_math(int i, int digit) {
do {
if (abs(i % 10) == digit) { // Look at the least digit, abs() to handle negative `i`
return true;
}
i /= 10; // Now look at the upper decimal digits
} while (i);
return false;
}
Or textually:
bool contains_the_digit_via_string(int i, int digit) {
char buf[30]; // Something certainly big enough
sprintf(buf, "%d", i);
return strchr(buf, digit + '0') != NULL;
}
Or use your imagination for other ideas.
The key is to take your problems and reduce them to smaller ones with helper functions: divide and conquer.
Concert the number to a string
Replace '3' with '*' within that string
i.e.
int to_be_converted =12345612343242432; // Or summat else
char num[100]; // Should be more than enough
sprintf(num, "%d", to_be_converted);
for (int i =0; num[i]; i++) {
if (num[i] -- '3') num[i] = '*';
}
printf("Here you go %s", num);
That should do the trick
Just ad the bit to go through the numbers and check if divisible by 3. I leave that to the reader.
Seeing you forgot to add the return type int to your int main(), I think this is a good time to learn to write your own function!
In this case, you want a function that can check whether the last digit of a number is a 3 when you represent that number as base-10. That's easy! The function should look like (you need to #include <stdbool.h> at the beginning of your file, too):
bool ends_in_decimal_3(int number) {
// figure out a way to find the difference
// between number, rounded to multiples of 10
// and the original number. If that difference==3,
// then this ends in 3 and you can `return true;`
}
Armed with that function, you can see whether your i itself ends in 3, or whether i/10 ends in 3 and so on. Remembering that division / in C between ints always rounds down is a good trick to do that, and also an important hint on how to implement your rounding in ends_in_decimal_3.

Finding numbers with unique digits in C

I have to write a program that finds every number (except 0) which can be factored by numbers from 2-9.
For example first such a number would be number 2520 as it can be divided by every single number from 2 to 9.
It also has to be a number that contains only 1 type of digit of its own (no multiple digits in a number). So for example 2520 will not meet this requirement since there are two same digits (2). The example of a number that meets both requirements is number 7560. That is the point I don't how to do it. I was thinking about converting value in an array to string, and then putting this string in another array so every digit would be represented by one array entry.
#include <stdio.h>
#include <math.h>
int main() {
int i, n, x, flag, y = 0;
scanf("%d", &n);
double z = pow(10, n) - 1;
int array[(int)z];
for (i = 0; i <= z; i++) {
flag = 0;
array[i] = i;
if (i > 0) {
for (x = 2; x <= 9; x++) {
if (array[i] % x != 0) {
flag = 1;
}
}
if (flag == 0) {
y = 1;
printf("%d\n", array[i]);
}
}
}
if (y == 0) {
printf("not exist");
}
return 0;
}
This should give you a base:
#include <stdio.h>
#include <string.h>
int main()
{
char snumber[20];
int number = 11235;
printf("Number = %d\n\n", number);
sprintf(snumber, "%d", number);
int histogram[10] = { 0 };
int len = strlen(snumber);
for (int i = 0; i < len; i++)
{
histogram[snumber[i] - '0']++;
}
for (int i = 0; i < 10; i++)
{
if (histogram[i] != 0)
printf("%d occurs %d times\n", i, histogram[i]);
}
}
Output:
Number = 11235
1 occurs 2 times
2 occurs 1 times
3 occurs 1 times
5 occurs 1 times
That code is a mess. Let's bin it.
Theorem: Any number that divides all numbers in the range 2 to 9 is a
multiple of 2520.
Therefore your algorithm takes the form
for (long i = 2520; i <= 9876543210 /*Beyond this there must be a duplicate*/; i += 2520){
// ToDo - reject if `i` contains one or more of the same digit.
}
For the ToDo part, see How to write a code to detect duplicate digits of any given number in C++?. Granted, it's C++, but the accepted answer ports verbatim.
If i understand correctly, your problem is that you need to identify whether a number is consisted of multiple digits.
Following your proposed approach, to convert the number into a string and use an array to represent digits, i can suggest the following solution for a function that implements it. The main function is used to test the has_repeated_digits function. It just shows a way to do it.
You can alter it and use it in your code.
#include <stdio.h>
#define MAX_DIGITS_IN_NUM 20
//returns 1 when there are repeated digits, 0 otherwise
int has_repeated_digits(int num){
// in array, array[0] represents how many times the '0' is found
// array[1], how many times '1' is found etc...
int array[10] = {0,0,0,0,0,0,0,0,0,0};
char num_string[MAX_DIGITS_IN_NUM];
//converts the number to string and stores it in num_string
sprintf(num_string, "%d", num);
int i = 0;
while (num_string[i] != '\0'){
//if a digit is found more than one time, return 1.
if (++array[num_string[i] - '0'] >= 2){
return 1; //found repeated digit
}
i++;
}
return 0; //no repeated digits found
}
// test tha function
int main()
{
int x=0;
while (scanf("%d", &x) != EOF){
if (has_repeated_digits(x))
printf("repeated digits found!\n");
else
printf("no repeated digits\n");
}
return 0;
}
You can simplify your problem from these remarks:
the least common multiple of 2, 3, 4, 5, 6, 7, 8 and 9 is 2520.
numbers larger than 9876543210 must have at least twice the same digit in their base 10 representation.
checking for duplicate digits can be done by counting the remainders of successive divisions by 10.
A simple approach is therefore to enumerate multiples of 2520 up to 9876543210 and select the numbers that have no duplicate digits.
Type unsigned long long is guaranteed to be large enough to represent all values to enumerate, but neither int nor long are.
Here is the code:
#include <stdio.h>
int main(void) {
unsigned long long i, n;
for (n = 2520; n <= 9876543210; n += 2520) {
int digits[10] = { 0 };
for (i = n; i != 0; i /= 10) {
if (digits[i % 10]++)
break;
}
if (i == 0)
printf("%llu\n", n);
}
return 0;
}
This program produces 13818 numbers in 0.076 seconds. The first one is 7560 and the last one is 9876351240.
The number 0 technically does match your constraints: it is evenly divisible by all non zero integers and it has no duplicate digits. But you excluded it explicitly.

Print the digits of a number in reverse order without arrays or functions

As a homework problem, I'm working on reading a decimal int from stdin, converting it to a different base (also provided from stdin) and printing it to the screen.
Here's what I've got so far:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num, base, remainder, quotient;
printf("please enter a positive number to convert: ");
scanf("%d", &num);
printf("please enter the base to convert to: ");
scanf("%d", &base);
remainder = quotient = 1;
// validate input
if (num < 0 || base < 0) {
printf("Error - all numbers must be positive integers!\n");
return 1;
}
// keep dividing to find remainders
while (quotient > 0) {
remainder = num % base;
quotient = num / base;
num = quotient;
if (remainder >= 10) {
printf("%c", remainder + 55);
} else {
printf("%d", remainder);
}
}
printf("\n");
return 0;
}
This works great, only that the algorithm this uses calculates the converted numbers from least significant to most significant digit, thus printing it in reverse. So, for example, converting 1020 to hexadecimal ( 0x3FC ) will print CF3.
Is there a trick I could use to reverse these numbers to print in the correct order. I can only use if-else, while, simple math operators and printf()/getchar()/scanf() - no functions, arrays or pointers. thanks.
(removed original part of the post here, since it is not the solution)
Then the only solution I can see is to perform the loop that you have now the number of times that you have digits.
So, first you calculate all digits till you get to the last, and then print it.
Then you take the original value + base and start dividing again till you come to the second "highest value" digit, then print it.
It is a double loop and you calculate everything twice, but you don't use extra storage.
It's a good try, and well phrased question. If only we had more people asking questions in such a clear manner!
The restrictions seem artificial. I guess you haven't learned about functions, arrays, pointers etc., in your class yet, but I think this problem is not meant to be solved elegantly without functions and/or arrays.
Anyway, you can do something like this:
curr := base
pow := 1
while num / curr >= 1 do:
curr := curr * base
pow := pow + 1
while pow >= 1:
pow := pow - 1
print floor(num / base ** pow)
num := mod(num, base ** pow)
Basically, you are calculating how many digits you will need in the first loop, and then printing the digits in the correct order later.
Some specific issues with your code. I understand it's the beginning of a C class, but still, it's better to know of such issues now than to never realize them:
printf("please enter a positive number to convert: ");
You should add an fflush(stdout) after this to make sure the output appears before scanf() is called. By default, stdout is line buffered on many systems, so the prompt may not appear before your program waits for input.
printf("please enter the base to convert to: ");
Same as above.
if (remainder >= 10) {
printf("%c", remainder + 55);
} else {
printf("%d", remainder);
}
You're assuming ASCII character set. This need not be true. But without arrays or pointers, there's no easy way to print the alphabets corresponding to 10.... Also, your code may print weird characters for base > 36.
You should also be aware that it's very hard to use scanf() safely. Hopefully you will learn better ways of getting input later.
In one loop you can calculate the number of digits and the big_base.
In a second loop you can output the digits starting from the most significant, like this:
n = 1020, 3 hex digits, big_base = 16*16
1st step
1020 / (16*16) = 3
2nd step
n = 1020- 3*(16*16) = 252
252 / (16) = 15, F
3rd step
n = 252 - 15*16 = 12, C
Hey ! I recognize a famous homework I had in first year of my school too (#Epitech students : don't copy/paste the following code, try to come up with your own solution, it's for your own good ^^)
The solution to your problem is to perform the problem in a recursive way :
void my_putnbr_base(int num, int base)
{
int start;
int remainder;
remainder = num % base;
start = (num - remainder) / base;
if (start != 0)
my_putnbr_base(start, base);
if (remainder >= 10)
printf("%c", remainder + 55);
else
printf("%d", remainder);
}
Does your homework specifies that it should only work with positives numbers ? If not, it's easy to include the negative numbers handling :
void my_putnbr_base(int num, int base)
{
int start;
int remainder;
if (num < 0)
{
putchar('-');
my_putnbr_base(-num, base);
}
else
{
remainder = num % base;
start = (num - remainder) / base;
if (start != 0)
my_putnbr_base(start, base);
if (remainder >= 10)
printf("%c", remainder + 55);
else
printf("%d", remainder);
}
}
#arno : that's true, because the exemple code is using ASCII table. If we want something trully flexible we need the base in parameter. For example :
>> my_putnbr_base(4242, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
39U
>> my_putnbr_base(42, "0123456789ABCDEF")
2A
this implements the example :
void my_putnbr_base(int num, char *base)
{
int start;
int remainder;
int len;
len = strlen(base);
if (num < 0)
{
putchar('-');
my_putnbr_base(-num, base);
}
else
{
remainder = num % len;
start = (num - remainder) / len;
if (start != 0)
my_putnbr_base(start, base);
printf("%c", base[remainder]);
}
}
I hope it solves your problem !
edit: I didn't read correctly ^^ You are not allowed to use functions, so recursion is out of the question... Here is an interative way, you can put this in a main(). You can improve this code by adding the negative numbers handling and flexible bases, as I showed you :)
int my_putnbr_base_it(int num, int base)
{
unsigned int quotient = 1;
unsigned int remainder;
while ((num / quotient) >= base)
quotient *= base;
while (quotient)
{
if ((remainder = (num / quotient) % base) < 10)
printf("%d", remainder);
else
printf("%c", 55 + remainder);
quotient /= base;
}
return (0);
}
Hope it solves everything now !
You could rewrite the piece of code calculating each number to behave as a state machine. It will start in the initial state and compute the number of digits, then change the state to "print the Nth digit" to print the most significant digit, then change the state to proceed to the less significant digits, etc until it eneters the final state. Running this inside a loop you will output all digits in proper order.
You could use two loops. The first keeps generating powers of the base until it finds a power greater than the input number. The second starts from here (or rather, one power before) and works back to base^0 (i.e. 1) to compute the output digits most significant first.
Untested pseudo-code:
// Determine highest power, don't actually need "power" it's just there for illustration
power = 0;
baseraisedtopower = 1;
while (baseraisedtopower <= input)
{
baseraisedtopower *= base;
power++;
}
// Go back one step, could have saved previous result
baseraisedtopower /= base;
power--;
// Output
while (input > 0)
{
// Integer division, truncate
quotient = input / baseraisedtopower;
printf("%c", quotient + 55);
input -= quotient * baseraisedtopower;
baseraisedtopower /= base;
power--;
}
You can give a try at this approach.
It's more a proof of concept, you'll still need to handle some special case, but, hey, that's your homework :)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num, base, remainder, quotient;
int divider;
printf("please enter a positive number to convert: ");
scanf("%d", &num);
printf("please enter the base to convert to: ");
scanf("%d", &base);
remainder = quotient = 1;
// validate input
if (num < 0 || base < 0) {
printf("Error - all numbers must be positive integers!\n");
return 1;
}
// First get the highest divider
divider = base;
while ( num / divider > base ) {
divider *= base;
}
do {
// Get the highest digit
remainder = num / divider;
// And update num accordingly
num -= remainder * divider;
divider /= base;
if (remainder >= 10) {
printf("%c", remainder + 55);
} else {
printf("%d", remainder);
}
} while ( divider );
printf("\n");
return 0;
}
Interesting task, you've got as a homework.
I am a beginner programmer to, and I've tried to resolve this task.
The following code is working (I haven't tested a lot, apparently is working). I am sure it's not the optimal&best solution, but was the only thing I've could come up with. It should work with any base. Unfortunately it won't convert 10->A, 11->B, etc.:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(){
int nr,base,res,tp,tpb,tpbt,r,rnr,lp,lpt,i;
float baset,rt;
/** Read number */
printf("nr=");
scanf("%d",&nr);
/** Read base */
printf("base=");
scanf("%d",&base);
/** Returning result */
res=0;
/** Test if number is positive
and base is bigger than 2 */
if(nr<0||base<2){
/** Error */
res=1;
}
else{
/** Determine how many
digits are necessary */
lp=0;
baset=base;
while(baset>1){
lp++;
baset/=10;
}
/** Determine full power
of 10 when r has length of lp */
tpb=1;
while((lp--)>0){
tpb*=10;
}
/** Power of ten that will be
incremented */
tp=0;
/** Converted number (will be printed
as the result) */
rnr=0;
/** Algorithm */
while(nr>0){
r=nr%base;
nr/=base;
rt=r;
/** Temporary lp for
r */
lpt=0;
while(rt>1){
lpt++;
rt/=10;
}
/** Temporary tpb for
lpt */
tpbt=tpb;
for(i=0;i<lpt;i++){
tpbt/=10;
}
/** Build number */
rnr+=r*pow((double)(tpbt),(double)(tp++));
}
}
/** Show number */
printf("number is: %d \n",rnr);
return (res);
}
Based on what was suggested, the way to tackle this was to keep print the last number and repeat the loop for every digit. I kept track of the print condition by saving the previous quotient and printing when I got to it every time (then reseting the number and starting over), then reset it to the one before. Sounds complicated, but the change to the code was simple. My stop condition for the loop was when I had 2 consecutive prints, since most of the time it would just calculate quotient/remainder and print nothing, and when 2 digits print in a row, it's the last two. Anyway, here's the code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num, saved, base, remainder;
int quotient, prev_q, stop_q, just_printed;
printf("please enter a positive number to convert: ");
scanf("%d", &num);
printf("please enter the base to convert to: ");
scanf("%d", &base);
saved = num;
remainder = quotient = prev_q = just_printed = 1;
stop_q = 0;
// validate input
if (num <= 0 || base <= 0) {
printf("Error - all numbers must be positive integers!\n");
return 1;
}
// divide
while (1) {
remainder = num % base;
quotient = num / base;
num = quotient;
// print if it's the last number and reset num to the next
if (quotient == stop_q) {
if (remainder >= 10) { printf("%c", remainder + 55); }
else { printf("%d", remainder); }
// if 2 consecutive printing occur, this means it's time to end this
if (just_printed) { break; }
// next time print when hitting the previous quotient
stop_q = prev_q;
// reset the number to the original value
num = saved;
just_printed = 1;
} else {
just_printed = 0;
}
prev_q = quotient;
}
printf("\n");
return 0;
}
Thanks to everyone who pitched in!
We could use a recursive function to reverse the order of the digits of a number :
We'll need some mathematical functions from these libraries - stdlib.h and math.h
int reverse(int x)
{
if(abs(x)<=9)
{
return x;
}
else
{
return reverse(x/10) + ((x%10)*(pow(10, (floor(log10(abs(x)))))));
}
}
'If statement' is the base case for the recursive function.
'Else statement' may look intimidating at first but it's actually just simple arithmetic. floor(log10(abs(x))) gives us the number of digits of x, so ((x%10)*(pow(10, (floor(log10(abs(x))))))) is just putting the 'ones' place digit of the number to its correct place in accordance with the desired reversed number.
For better comprehension let's take an example, Let 123 be the number we need to reverse. The first thing that the function reverse will do is ask itself the reverse of 12 (reverse(x/10)) and when the function is called for the second time with argument 12 it'll ask itself the reverse of 1, Now this will be the base case for our function. It'll return 1 as abs(1)<=9, Now 2 will be prepended using ((x%10)*(pow(10, (floor(log10(abs(x)))))) it then will return 21 and 3 will be prepended by the same.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int reverse(int x);
int main()
{
int x, revInt;
scanf("%d", &x); // input : 123
revInt = reverse(x);
printf("%d", revInt); // output : 321
return 0;
}

Resources