I've gotta count how many times a certain digit is repeated in each number in a range. For example, in the numbers between 0 and 20, there is only one occurrence of 1 being repeated twice (11). I originally did this by converting the int to a str and iterating over it, but I would like to be able to solve this in an arithmetic way. Any ideas?
here is a general solution that you can use , your problem didn't contain much information so I assumed that you want to count the number of repeating of each digit in each number.
so what I did is like hashing where the digits in each number will never cross the value 9 , so they are from 0 to 9 so I made that hash table called arr, so what I did is to come to every single digit in number and increment the position of that digit in arr
for example , number 554 will cause arr[5]++; twice and arr[4]++; only once , simple idea of using hash tables.
and then at the end I iterate over the hash array printing the number of occurrence of each digit in each number.
and here is the code :
#include <stdio.h>
#include <math.h>
int main()
{
int arr[6] = {5555, 12112, 14, -3223, 44, 10001};
int tempArr[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for (int i = 0; i < 6; i++) {
int temp1 = arr[i];
// get the number of occurrences of each digit in each number
do{
tempArr[(abs(temp1) % 10)]++;
temp1 /= 10;
}while(temp1 != 0);
// loop over the array to know how many times each digit occurred
printf("the number of occurrences in number called %d\n", arr[i]);
for (int j = 0; j < 10; j++) {
if(tempArr[j] > 1)
printf("number %d occurred %d times\n", j, tempArr[j]);
// resetting that position of the array
tempArr[j] = 0;
}
}
return 0;
}
and here is the output :
the number of occurrences in number called 5555
number 5 occurred 4 times
the number of occurrences in number called 12112
number 1 occurred 3 times
number 2 occurred 2 times
the number of occurrences in number called 14
the number of occurrences in number called -3223
number 2 occurred 2 times
number 3 occurred 2 times
the number of occurrences in number called 44
number 4 occurred 2 times
the number of occurrences in number called 10001
number 0 occurred 3 times
number 1 occurred 2 times
You can divide your number multiple times by 10:
int number = 72;
int rest;
while(number)
{
rest = number % 10;
printf("%d\n", rest);
number /= 10;
}
Here rest contains '2' and then '7'
how many times a certain digit is repeated in each number in a range.
Pseudo code*1
Get the range: imin, imax (any int pair where imin <= imax)
Get the digit: digit 0 to 9
Iterate m from imin to imax, inclusive
.... Print m
.... Set digit_count = 0
.... Repeat
....... Last digit ld of m is abs(m%10).
....... If ld == digit, increment digit_count.
........ Divide m by 10
.... Until m == 0
.... Print digit_count
Done
*1 As OP did not provide code, seemed best to not provide a code answer.
Riffing on the answer provided by #Abdo Salm presented only to demonstrate a slightly alternative approach. All credit to Abdo.
EDIT: Going beyond single, arbitrary numbers to generating ascending contiguous sequence of numbers to be evaluated.
#include <stdio.h>
#include <string.h>
#include <limits.h>
void process( int n, int cnts[] ) {
// count occurences of each digit (right to left)
while( n )
cnts[ abs(n % 10) ]++, n /= 10;
}
void report( int cnts[], int thresh ) {
char *sep = "";
for( int j = 0; j < 10; j++ )
if( cnts[ j ] > thresh )
printf( "%s%dx%d", sep, cnts[ j ], j ), sep = ", ";
if( !*sep )
printf( "no digit occurred multiple times" );
putchar( '\n' );
}
int main() {
#ifndef PROVE
int tests[] = {
0, 11, 121, 5555, 12112, 14,
-3223, 44, 1223334444,
INT_MIN, INT_MAX,
};
// proof of concept: run through multiple arbitrary test values
for( int i = 0; i < sizeof tests/sizeof tests[0]; i++ ) {
// counter for each digit, all init'd to zero
int cnts[ 10 ];
memset( cnts, 0, sizeof cnts );
process( tests[ i ], cnts );
// report only digits appearing multiple times
printf( "%11d: ", tests[ i ] );
report( cnts, 1 );
}
#else // with "ranges" instead of arbitrary test cases
int ranges[][2] = {
{ 0, 10, },
{ 0, 22, },
{ 110, 133, },
{ 447, 448, },
};
for( int r = 0; r < sizeof ranges/sizeof ranges[0]; r++ ) {
int metacnts[10];
memset( metacnts, 0, sizeof metacnts );
for( int i = ranges[r][0]; i <= ranges[r][1]; i++ ) {
int cnts[ 10 ];
memset( cnts, 0, sizeof cnts );
process( i, cnts );
for( int j = 0; j < 10; j++ )
if( cnts[ j ] > 1 )
metacnts[ j ]++;
}
// report only digits appearing multiple times in numbers between min & max
printf( "Range %3d-%3d (incl) ", ranges[r][0], ranges[r][1] );
report( metacnts, 0 );
}
#endif
return 0;
}
/*
Output from arbitrary sequence:
0: no digit occurred multiple times
11: 2x1
121: 2x1
5555: 4x5
12112: 3x1, 2x2
14: no digit occurred multiple times
-3223: 2x2, 2x3
44: 2x4
1223334444: 2x2, 3x3, 4x4
-2147483648: 3x4, 2x8
2147483647: 3x4, 2x7
Output from arbitrary ranges:
Range 0- 10 (incl) no digit occurred multiple times
Range 0- 22 (incl) 1x1, 1x2
Range 110-133 (incl) 12x1, 1x2, 1x3
Range 447-448 (incl) 2x4
*/
Related
I'm making a program in C that factors any number using primes and saves these primes, multiplying them you find all the divisors of a number.
But I can't make an array that multiplies the previous columns and saves the results. follow the example
60 / 2
30 / 2
15 / 3
5 / 5
divisors = 2, 2, 3, 5
now i need`add 1 to array array {1, 2, 2, 3, 5}
i need this now start colune 2 {1, 2} 2 * 1 = 2 save.
next colune 3 {1, 2, 2} 2 * 1 = 2 but we already have 2 so don't save it.
continue 2 * 2 = 4 save.
colune 4 {1, 2, 2, 3} 3 * 1 = 3 save, 3 * 2 = 6 save, 3 * 4 = 12 save.
colune 5 {1, 2, 2, 3, 5} 5 * 1 = 5 save, 5* 2 = 10, 5 * 4 = 20 save, 5 * 3= 15 save, 5 * 6 = 30 save, 5 * 12 = 60 save.
now we found all divisors of 60 = 1, 2, 3, 4, 5, 6, 10 ,12 , 15,20, 30, 60.
It is important to mention that I need the program to be like this, I know there are other ways... but I only need this one, I have been unable to complete it for 1 week
video to help https://www.youtube.com/watch?v=p0v5FpONddU&t=1s&ab_channel=MATEM%C3%81TICAFORALLLUISCARLOS
my program so far
#include <stdlib.h>
#include <stdio.h>
int N = 1;
int verificarPrimo(int numero);
int main()
{
int num = 60, i, primo = 1, resultados[N], j = 1;
for (i = 0; i < 60; i++)
{
if (primo == 1)
{
resultados[N - 1] = primo;
i = 2;
primo = i;
}
if (verificarPrimo(i))
{
while (num % i == 0)
{
num = num / i;
resultados[N] = i;
N++;
}
}
}
for (i = 1; i < N; i++)
{
printf("%d \n", resultados[i]);
}
}
int verificarPrimo(int primo)
{
int i;
if (primo <= 1)
return 0;
for (i = 2; i <= primo / 2; i++)
{
if (primo % i == 0)
return 0;
}
return 1;
}
I tried out your code and ran into some issues with how the results were being stored. First off, the results array is being initially defined as an array with a size of "1", and that it not what you probably want.
int num = 60, i, primo = 1, resultados[N], j = 1;
With that in mind and determining the spirit of this project, following is tweaked version of the code to test for one or more values and their factors.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int verificarPrimo(int primo)
{
int sq = sqrt(primo) + 1; /* Usual checking for a prime number is from '2' to the square root of the number being evaluated */
if (primo <= 1)
return 0;
for (int i = 2; i < sq; i++)
{
if (primo % i == 0)
return 0;
}
return 1;
}
int main()
{
int N = 0;
int num = 0, entry = 0, resultados[100]; /* The results array needs to be defined with some value large enough to contain the assorted factors a number might have */
printf("Enter a number to evaluate for factors: "); /* Using a prompt to allow various values to be tested */
scanf("%d", &entry);
num = entry;
if (verificarPrimo(num)) /* Catchall in case the entered number is a prime number */
{
printf("This number is a prime number and has no factors other than one and itself\n");
return 0;
}
resultados[0] = 1; /* Normally the value '1' is implied in a list of factors, so these lines could be omitted */
N = 1;
for (int i = 2; i < entry; i++)
{
if (verificarPrimo(i))
{
while (num % i == 0)
{
num = num / i;
resultados[N] = i;
N++;
}
}
}
printf("Factors for %d\n", entry);
for (int i = 0; i < N; i++)
{
printf("%d ", resultados[i]);
}
printf("\n");
return 0;
}
Some items to point out in this tweaked code.
In the prime number verification function, it is usually customary to set up a for loop in testing for prime numbers to go from the value of "2" to the square root of the number being tested. There usually is no need travel to one half of the number being tested. For that, the #include <math.h> statement was added (FYI, "-lm" would need to be added to link in the math library).
Instead of defining the results array with a value of one element, an arbitrary value of "60" was chosen for the holding the possible number of results when evaluating factors for a given value. Your original code had the potential of storing data past the end of the array and causing a "smashing" error.
The value of "1" is usually left out of the list of factors for a number, but was left in as the initial result value. This might be left out of the completed code.
An additional entry field was added to allow for user entry to be tested to give the code some flexibility in testing numbers.
A test was also added to see if the entered number is itself a prime number, which would only have factors of "1" and itself.
Following is some sample terminal output testing out your original value of "60" along with some other values.
#Dev:~/C_Programs/Console/Factors/bin/Release$ ./Factors
Enter a number to evaluate for factors: 60
Factors for 60
1 2 2 3 5
#Dev:~/C_Programs/Console/Factors/bin/Release$ ./Factors
Enter a number to evaluate for factors: 63
Factors for 63
1 3 3 7
#Dev:~/C_Programs/Console/Factors/bin/Release$ ./Factors
Enter a number to evaluate for factors: 29
This number is a prime number and has no factors other than one and itself
Give that a try to see if it meets the spirit of your project.
I have generated an array that has 10 integers. I have to find how many times an element has been repeated, but I always get 0 as an output. Here in this code, countcolor variables is my count values. For example countcolor1 is my count value for the integer 1. Here is what I have so far:
#include <stdio.h>
#include <time.h>
int i;
double entropy_calculator(int bucket[10]);
int main() {
srand(time(NULL));
int countings;
int bucket[10];
for (i = 0; i < 10; ++i) {
bucket[i] = 1 + rand() % 10;
printf("%d \n", bucket[i]);
}
countings = entropy_calculator(bucket);
return 0;
}
double entropy_calculator(int bucket[10]) {
int x;
int countcolor1 = 0, countcolor2 = 0, countcolor3 = 0,
countcolor4 = 0, countcolor5 = 0, countcolor6 = 0;
for (x = 0; x <= 10; ++x) {
if (bucket[10] == 1)
countcolor1++;
if (bucket[10] == 2)
countcolor2++;
if (bucket[10] == 3)
countcolor3++;
if (bucket[10] == 4)
countcolor4++;
if (bucket[10] == 5)
countcolor5++;
if (bucket[10] == 6)
countcolor6++;
}
printf("%d,%d,%d,%d,%d,%d",
countcolor1, countcolor2, countcolor3,
countcolor4, countcolor5, countcolor6);
}
Notes on your code
The return type of entropy_calculator is double but you do not return anything. If you do not wish to return anything, set the return type to void.
In main, you attempt to assign the return value of entropy_calculator to an int called countings. If you are going to return some double value, countings should be a double.
Undefined behavior. According to the C Standard, behavior of a program is undefined in the event that an array subscript is out of range. bucket is an array of 10 integers. The valid indices of an array with N elements is in general 0, 1, 2, ..., N - 1; in other words, the first element is assigned the index 0, the second element is assigned the index 1, ..., the Nth element is assigned the index N - 1. Thus, the valid indices into the bucket array is any integer in the closed interval [0, 10 - 1] = [0, 9]. In your entropy_calculator function, you are attempting to access the element of bucket with index 10; the only valid indices are one of 0, 1, ..., 9.
In entropy_calculator, suppose we change all the 10s to a 9 so that the loop runs from x = 0, x = 1, .. . , x = 9 and checks of the form ([bucket[10] == j) for some j in [1, 6] are replaced with ([bucket[9] == j). All of these six checks are simply checking if the 10th element of bucket is one of 1, 2, ..., or 6. You have disregarded the other 9 randomly-generated numbers in bucket so you are never involving them in the count. You are also disregarding the other possible randomly-generated values, namely, 7, 8, 9, and 10 as you are currently only comparing the 10th element of bucket against 1, 2, ..., and 6.
Solution
I assume your task is to
generate 10 random integers in [1, 10] and store them in an array of ints, say, bucket.
create a function that accepts as an argument an array of 10 ints (i.e. a pointer to an int) and prints the number of occurrences of 1s, 2s, ..., 10s in the array.
To make the program slightly more general, we define the macro MAX_LEN and make it represent the number 10.
In main, first, we initialize the random number generator by setting the seed to the current time. Second, we define an array of MAX_LEN ints called bucket. Third, we fill each element of bucket with a pseudo-random integer in [1, MAX_LEN]. Lastly, we call the functionentropy_calculator, passing bucket as the sole argument, and then return 0.
In the function, entropy_calculator, we define an array of MAX_LEN ints called counts, with each element initialized to zero. We create our own internal mapping such that the nth element of counts represents the number of ns found in bucket, for each n in {1, 2, ..., MAX_LEN}. Equivalently, for each n in {1, 2, ..., MAX_LEN}, the number of ns found in bucket is represented by the element of counts with index n - 1. We then loop over the elements of the bucket array and, using our mapping, increment the corresponding element in the counts array. We then print out all the elements of counts.
For example, for some i in the set of valid indices of the arrays in our program, i.e. {0, 1, ..., MAX_LEN - 1}, if we find that bucket[i] is 5, then we want to increment the 5th element of counts (since the nth element of counts counts the number of ns generated) which is counts[5 - 1] or, more generally, counts[bucket[i] - 1].
Program
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_LEN 10
void entropy_calculator(int bucket[]);
int main(void) {
/* initialize random number generator */
srand((unsigned) time(NULL));
/* will contain MAX_LEN random ints in [1, MAX_LEN] */
int bucket[MAX_LEN];
/* generate pseudo-random ints in [1, MAX_LEN], storing them in bucket */
for (int i = 0; i < MAX_LEN; i++) {
bucket[i] = 1 + rand() % MAX_LEN;
printf("%d\n", bucket[i]);
}
entropy_calculator(bucket);
return 0;
}
/****************************************************************************
* entropy_calculator: given an array of MAX_LEN integers in [1, MAX_LEN], * *
* prints the number of occurrences of each integer in *
* [1, MAX_LEN] in the supplied array *
****************************************************************************/
void entropy_calculator(int bucket[]) {
int counts[MAX_LEN] = {0}; /* initialize counts to all 0s */
int i; /* loop variable */
for (i = 0; i < MAX_LEN; i++)
counts[bucket[i] - 1]++;
/* printing all elements of counts */
for (i = 0; i < MAX_LEN; i++) {
if (i % 4 == 0) printf("\n");
printf(" %2d*: %d", i + 1, counts[i]);
}
printf("\n");
}
Example Session
3
9
2
6
10
9
3
8
3
1
1*: 1 2*: 1 3*: 3 4*: 0
5*: 0 6*: 1 7*: 0 8*: 1
9*: 2 10*: 1
Simplified version
If the task is to simply generate MAX_LEN (macro representing the value 10) random integers in [1, MAX_LEN] and to count how many 1s, 2s, ..., (MAX_LEN - 1), MAX_LENs are generated, then it can simply be done as follows.
We create an array of MAX_LEN integers, called counts. The valid indices associated with counts is 0, 1, ..., MAX_LEN - 1. We form our own internal mapping such that the element of counts with index n - 1 represents the number of randomly-generated ns for n in {1, 2, ..., MAX_LEN}.
As we generate a random integer in [1, MAX_LEN], we assign it to cur, and we increment the element of counts with index cur - 1 as this element represents the number of occurrences of the number cur.
Program
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_LEN 10
int main(void) {
srand((unsigned) time(NULL)); /* initialize random number generator */
int counts[MAX_LEN] = {0}; /* initialize counts to all 0s */
int i, cur;
for (i = 0; i < MAX_LEN; i++) {
cur = 1 + rand() % MAX_LEN; /* pseudo-random int in [1, MAX_LEN] */
printf("%d\n", cur);
counts[cur - 1]++;
}
/* printing all elements of counts */
for (i = 0; i < MAX_LEN; i++) {
if (i % 4 == 0) printf("\n");
printf(" %2d*: %d", i + 1, counts[i]);
}
printf("\n");
return 0;
}
Example Session
8
4
6
2
4
1
10
9
2
10
1*: 1 2*: 2 3*: 0 4*: 2
5*: 0 6*: 1 7*: 0 8*: 1
9*: 1 10*: 2
#include<stdio.h>
#include<time.h>
int i;
double entropy_calculator(int bucket[10]);
int main()
{
srand(time(NULL));
int countings;
int bucket[10];
for(i=0; i<10; ++i)
{
bucket[i] = 1 + rand() % 10;
printf("%d ", bucket[i]);
}
printf("\n");
countings = entropy_calculator(bucket);
return 0;
}
double entropy_calculator(int bucket[10])
{
int x;
int countcolor1=0, countcolor2=0, countcolor3=0, countcolor4=0, countcolor5=0, countcolor6=0;
for(x=0; x<10; ++x)
{
if (bucket[9]==1)
countcolor1++;
if (bucket[9]==2)
countcolor2++;
if (bucket[9]==3)
countcolor3++;
if (bucket[9]==4)
countcolor4++;
if (bucket[9]==5)
countcolor5++;
if (bucket[9]==6)
countcolor6++;
}
printf("%d,%d,%d,%d,%d,%d",countcolor1,countcolor2,countcolor3,countcolor4,countcolor5,countcolor6);
}
I create a program that get the input of array element size of 10. Everything getting will with the sum of even and odd number. but when it comes to the inverse it didn't work.
i created two arrays where the first getting the value from the user and second copying the element starting from end of the first array..
#include <stdio.h>
int main (){
int array[10] , i , odd =0 , even =0;
int array1[10],b;
for (i=0 ; i < 10 ; i ++){
printf("Insert number %d: ",i);
scanf("%d",&array[i]);
}
for (i=0; i < 10 ; i++){
if ( array[i] % 2 == 0){
even = even + array[i];
}
else
odd = odd + array[i];
}
printf("\n The Sum of Even Numbers in this Array = %d ", even);
printf("\n The Sum of Odd Numbers in this Array = %d ", odd);
for ( i = 10 , b =0; i>0; i-- , b++)
{
array1[b] = array[i];
}
printf("\nReverse Order:\n");
for ( b = 0 ; b< 10;b++ )
{
printf(" %d",array[b]);
}
return 0;
}
The input will be: 2 3 5 4 6 12 3 7 4 9
What I expect the out put for the reverse is: 9 4 7 3 12 6 4 5 3 2
But it gave me same value as : 2 3 5 4 6 12 3 7 4 9 .
Any Idea for how doing this reverse.?
In addition to the answer by #Yunnosch that identifies the problems in your current implementation, you can refactor (rearrange) your code to sum even and odd and reverse array into array1 in a single loop. The only other loop you need is the loop to iterate over array1 outputting the reversed array.
With a bit of re-arranging, you could do something similar to:
#include <stdio.h>
int main (void) {
int array[] = { 2, 3, 5, 4, 6, 12, 3, 7, 4, 9 }, /* array */
array1[sizeof array/sizeof *array], /* array1 */
even = 0, odd = 0; /* even/odd */
size_t n = sizeof array/sizeof *array; /* no. elem in array */
for (size_t i = 0; i < n; i++) { /* loop over each element in array */
array1[i] = array[n - i - 1]; /* reverse into array1 */
if (array[i] & 1) /* check if odd (bit-0 == 1) */
odd += array[i]; /* add value to odd */
else /* even */
even += array[i]; /* add value to even */
}
/* output results */
printf ("even sum: %d\nodd sum : %d\n\nreversed: ", even, odd);
for (size_t i = 0; i < n; i++)
printf (" %d", array1[i]);
putchar ('\n');
}
(note: you can either use if (array[i] % 2) or if (array[i] & 1) to test whether the element is odd or even. Anding with 1 simply checks whether bit-0 is 1, if it is, it's an odd number. Modern compilers will optimize to remove the division inherent to modulo, so whichever you prefer should pose no penalty)
Example Use/Output
$ ./bin/revarr
even sum: 28
odd sum : 27
reversed: 9 4 7 3 12 6 4 5 3 2
Look things over and let me know if you have questions.
You are outputting the array which you never tried to inverse.
printf(" %d",array[b]);
should be
printf(" %d",array1[b]);
Aside, the input by David C. Rankin:
Also for ( i = 10 ... and array1[b] = array[i]; assigns from beyond the end of array. It should e.g. better be
for ( i = 10 , b =0; i>0; i-- , b++)
{
array1[b] = array[i-1];
}
I need to write a function that accepts the length of series(0 and 1) and the user writes the series. The function tells the place of the longest same sun-series.
Example:
The function gets length = 12, and the user writes: 1 0 0 1 1 1 1 0 0 0 1 1
The answer for this one is 4 because the longest combination (four consecutive 1's) starts at 4th place.
Another example:
The length is: 12 and the user inputs : 1 0 0 0 1 1 0 1 1 1 0 0
The answer for this one is 2 (three consecutive 0's starting at position 2—if there are multiple sub-series with same length it returns the first one).
This is what I tried to do:
int sameNumbers(int seriaLength)
{
int i;
int place=0;
int num1, num2;
int sameCount;
int maxSameCount = 0;
printf("Please enter the seria: \n");
scanf("%d",&num1);
for(i = 1; i < seriaLength; i++)
{
scanf("%d",&num2);
while(num1 == num2)
{
sameCount++;
}
if(sameCount > maxSameCount)
{
maxSameCount = sameCount;
place = i;
}
scanf("%d",&num1);
}
return place;
}
Edit:
I need to do this without arrays.
Thanks!!
This seems to do what you want. To understand the logic, see the comments in the code.
#include <stdio.h>
int sameNumbers(int seriaLength)
{
int i, num, previousNum, length = 0, maxLength = 0, start = 0, startOfLongest = 0;
printf( "Please enter the series: " );
for( i = 0; i < seriaLength; i++ )
{
scanf( "%d", &num );
if( i > 0 && num == previousNum ) length++;
else { length = 1; start = i; } // if the number is not the same as the previous number, record the start of a new sequence here
if( length > maxLength ) { maxLength = length; startOfLongest = start; } // if we've broken (not equalled) the previous record for longest sequence, record where it happened
previousNum = num;
}
return startOfLongest + 1; // add 1 because the OP seems to want the resulting index to be 1-based
}
int main( int argc, const char * argv[] )
{
printf( "%d\n", sameNumbers( 12 ) );
return 0;
}
I m trying to find number of factors of product of big numbers.
The problem statement is this : Suppose you are given N numbers(let say N = 10), each number <= 1000000.
How to find the number of factors of the product of such numbers.
Can someone please provide an efficient algorithm for doing this.
Example :
1) N = 3 and Numbers are 3, 5, 7
Ans = 8 (1, 3, 5, 7, 15, 21, 35, 105)
2) N = 2 and Numbers are 5, 5
Ans = 3 (1, 5 and 25)
Editorial for the problem is here
http://discuss.codechef.com/questions/15943/numfact-editorial
int total = 0, N = 0, Number;
scanf ("%d", &total);
while (total--)
{
scanf ("%d", &N);
map<int, int> Counter;
for (int i = 0; i < N; i++)
{
scanf ("%d", &Number);
for (int j = 2; j * j <= Number; j++)
{
while (Number % j == 0)
{
Counter[j]++;
Number /= j;
}
}
if (Number > 1) Counter[Number]++;
}
int Answer = 1;
for (map<int, int>::iterator it = Counter.begin(); it != Counter.end(); it++)
Answer *= (it->second + 1);
printf ("%d\n", Answer);
}
This got Accepted.
Sample Inputs and Outputs:
7
3
3 5 7
3
2 4 6
2
5 5
10
2 2 2 2 2 2 2 2 2 2
1
100
10
10000 10000 10000 10000 10000 10000 10000 10000 10000 10000
10
1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000
8
10
3
11
9
1681
3721
Factorize each number into list of prime factors and their multiplicities, L(n) = { p_i , k_i }, for a number n = Π piki. Numer of divisors for such n is ND( L(n) ) = Π (ki+1) a product of all coefficients, each incremented by 1 (this includes 1 and n itself as divisors of n). This corresponds to picking none, one, ... ki of each of them to multiply.
To calculate the ND of a product of arbitrary number of numbers, factorize each and merge their factorizations, where in case of matching primes their coefficients are added together. Then calculate the ND of the merged factorization.
To merge many factorizations together, start by merging two of them; then merge the result and the next one; then merge the last result and the next factorization, and so on. This is called folding. Or better merge them pairwise, then merge the results in same pairwise fashion, and so on util only one merged result is left. That's similar to how a bottom-up mergesort is done.
Multiply all the numbers, factorize the result, count all divisors:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
int p = 1;
for (int i = 1; i < argc; i++)
p *= strtol(argv[i], NULL, 10);
int n = 0;
int s = sqrt(p) + 1;
for (int i = 1; i <= s; i++)
if (p % i == 0)
n += 2 - (p / i == i); // obfuscation ;)
printf("%d\n", n);
return 0;
}