project euler exercise 5 approach - c

Question: 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
So, I was trying to do exercise 5 on project euler and I came out with this code:
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int main () {
int n, fnd = FALSE, count, i;
for (i = 1; fnd == FALSE; i++) {
count = 0;
for (n = 1; n <= 20; n++) {
count += i % n;
}
printf ("testing %d, count was: %d\n", i, count);
if (count == 0) {
fnd = TRUE;
printf ("%d\n", i);
}
}
return 0;
}
I believe my apporach is correct, it will surely find the number which is divisible by 1 to 20. But it's been computing for 5 minutes, and still no result. Is my approach correct? If yes, then is there another way to do it? I can't think on another way to solve this, tips would be very much appreciated. Thank you in advance.
EDIT:
So, based on the advice I was given by you guys I figured it out, thank you so much!
So, it's still brute force, but instead of adding 1 to the last number, it now adds 2520, which is the LCM of 1 to 10. And therefore, calculating if the sum of the remainders of the multiples of 2520 divided from 11 to 20 was 0. Since 2520 is already divisible by 1 to 10, I only needed to divide by 11 to 20.
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int main () {
int n, fnd = FALSE, count, i;
for (i = 2520; fnd == FALSE; i = i + 2520) {
count = 0;
for (n = 11; n <= 20; n++) {
count += i % n;
}
printf ("testing %d, count was: %d\n", i, count);
if (count == 0 && i != 0) {
fnd = TRUE;
printf ("%d\n", i);
}
}
return 0;
}
Thank you so much, I wouldn't solve it without your help : )
PS: It now computes in less than 10 secs.

Your approach is taking too long because it is a brute-force solution. You need to be slightly clever.
My hint for you is this: What does it mean for a number to be evenly divisible by another number? Or every number below a certain number? Are there commonalities in the prime factors of the numbers? The Wikipedia page on divisibility should be a good starting point.

Hint: You should look up "least common multiple".
Next hint:
The answer is the least common multiple (LCM) of the numbers 1, 2, 3, ..., 20.
LCM of n numbers can be found sequentially: if LCM(1, 2) = x, than LCM(1, 2, 3) = LCM(x, 3); if LCM(1, 2, 3) = y, than LCM(1, 2, 3, 4) = LCM(y, 4) etc. So it's enough to know how to find LCM of any 2 numbers.
For finding LCM of 2 numbers we can use the following formula: LCM(p, q) = pq/GCD(p, q), where GCD is the greatest common divisor
For finding GCD, there is a well-known Euclid's algorithm (perhaps the first non-trivial algorithm on the Earth).

I think you should start by computing the prime factors of each number from 2 to 20.
Since the desired number should be divisible by each number from 1 to 20, it must also
be divisible by each prime factor of those numbers.
Furthermore, it is important keep track of the multiplicities of the prime factors.
For example, 4 = 2 * 2, hence the desired number must be divisible by 2 * 2.

Something I quickly baked with Python 3:
primary_list = []
for i in range(2, 4097):
j = i
k = 2
delta_list = primary_list[0:]
alpha_list = []
while j > 1:
if j % k == 0:
j /= k
alpha_list.append(k)
k = 2
else:
k += 1
for i in alpha_list:
try:
delta_list.remove(i)
except:
primary_list.append(i)
final_number = 1
for i in primary_list:
final_number *= i
print(final_number)
This computes in mere seconds under a slow machine. Python is very good with abstract numbers. The best tool for the job.
The algorithm is relatively simple. We have a basic list primary_list where we store the multiples of the numbers. Then comes the loop where we estimate the range of numbers that we want to compute. We use a temporary variable j as a number that can be easily divided, chopped and conquered. We use k as the divisor, starting as 2. The delta_list is the main working copy of the primary_list where we take apart number after number until only the required "logic" is left. Then we add those numbers to our primary list.
1: 1
2: 2 1
3: 3 1
4: 2 2 1
5: 5 1
6: 2 3 1
7: 7 1
8: 2 2 2 1
9: 3 3 1
10: 2 5 1
The final number is found by multiplying the numbers that we have in the primary_list.
1 * 2 * 3 * 2 * 5 * 7 * 2 * 3 = 2520
As said, Python is _really_ good with numbers. It's the best tool for the job. That's why you should use it instead of C, Erlang, Go, D or any other dynamic / static language for Euler exercises.

I solved it using C. Below is the algorithm!
#include <stdio.h>
#include <stdio.h>
int main()
{
int i;
int count;
for(i=21;i>0;i++)
{ count = 0;
for( int j=2;j<21;j++)
{
if (i%j!=0)
break;
count++;
}
if (count==19)
break;
}
printf("%d\n",i);
return 0;
}

Just some thoughts about above comments,
#pg190 you say " it really only needs to be divisible by the primes between 1 and 20, i.e. 2, 3, 5, 7, 11, 13, 17, 19."
take 9699690, does not devide by all value from 1-20.
So this might be a good solution,
Given the number set [1-20]
The Least Common Multiple can be computed as follows.
Ex. For numbers 2,6,9
Express them in prime multiplications
2 2
6 2 3
9 3 3
LCM = multiple of highest power of each prime number.
= 2*3^2 = 18
This can be done to the problem in hand by expressing each number as prime multiplication
and then do this math.

$num=20;
for($j=19;$j>1;$j--)
{
$num= lcm($j,$num);
}
echo $num;
function lcm($num1, $num2)
{
$lcm = ($num1*$num2)/(gcd($num1,$num2));
return $lcm;
}
function gcd($n1,$n2)
{
$gcd=1;
$min=$n1;
if($n1>$n2)
{
$min=$n2;
}
for($i=$min;$i>1;$i--)
{
if($n1%$i==0 && $n2%$i==0)
{
$gcd*=$i;
$n1/=$i;
$n2/=$i;
}
}
return $gcd;
}
solved in php

Related

Make an array multiply only the columns behind it, going one at a time until the last one and save the answer in c

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.

How to compare array indexes with an integer in C?

A grocery store has N different types of chips. Chris wants to buy the chips as many as possible. He has M dollar in his pocket right now and he ask you to help him to count the number of chips he can buy as many as possible.
Format Input:
Input start with T, the number of test cases. For each test cases, there will be 2 integers N and M. In the second line there will be N integers, describing the price of one i-th chips. There will be unlimited supply of each type of chips.
Format Output:
Output starts with “Case #X: ”, where X is the test case number starting at 1, then followed by an integers, the maximum number of chips that Chris can buy
Constraints:
• 1 ≤ T ≤ 100
• 1 ≤ N ≤ 10000
• 1 ≤ M ≤ 10^9
• It is guaranteed the price will be between 1 and 10^6
Sample Input (user input) and Output (output in italic):
6
4 5
1 2 3 4
Case #1: 5
3 3
5 5 5
Case #2: 0
3 2
1 1 1
Case #3: 2
10 5
1 1 1 1 1 2 2 2 2 2
Case #4: 5
6 2
1 2 3 6 5 4
Case #5: 2
1 5
1
Case #6: 5
`
#include <stdio.h>
int main()
{
int t;
scanf("%d", &t);
for(int i = 1; i <= t; i++)
{
long long int n, m;
scanf("%lld %lld", &n, &m);
int chips[n];
for(int j = 0; j < n; j++)
{
scanf("%d", &chips[j]);
}
if(m > chips[n - 1])
{
printf("Case #%d: %lld\n", i, m);
}
else if(m < chips[n - 1])
{
printf("Case #%d: 0\n", i);
}
}
return 0;
}
`
I made a mistake in the if else part. I compare the m with the whole array, but I think I have to compare the m with the indexes of the array one by one. I don't know how to write the syntax to compare the indexes one by one. Does anyone know how to write the if else statement correctly for this problem?
If the problem is asking for the maximum number of packets chris can buy, then chris should only think about how many quantity of lowest-priced packet he can buy.
for example, in testcase 1, the lowest price of a packet is 1, so in this case, having m = 5, he can by 5 packets of worth 1.
So, first, you should find the lowest price of a packet (min value among the given array of costs)
then print:
printf("case #%d: %d\n", m/min);

Explain the algorithm and check whether the number is a prime number or not?

I'm understand only the code, but not it's core concept anyone explain about its flow chart and Algorithm
why we use i<=n/2 in this code is there any way to use i<=n
#include <stdio.h>
int main() {
int n, i, flag = 0;
printf("Enter a positive integer: ");
scanf("%d", &n);
for (i = 2; i <= n / 2; ++i) {
// condition for non-prime
if (n % i == 0) {
flag = 1;
break;
}
}
if (n == 1) {
printf("1 is neither prime nor composite.");
}
else {
if (flag == 0)
printf("%d is a prime number.", n);
else
printf("%d is not a prime number.", n);
}
return 0;
}
Suppose n is composite. Then n=ab for some integers a,b>1. Your first loop checks if a or b is an integer in the range [2, n/2]. If that loop never finds a factorization like that, it must be that one of the factors (if it exists) is greater than n/2. If it is greater than n/2, the other factor must be less than 2. The only such factorization is n=1n, in which case n is in fact a prime. Thus it suffices to check only factors up to n/2.
PS: I deliberately don't specify what I mean when n is odd. That's left as an exercise for you to fill in.
PPS: You can easily do a lot better than stopping at n/2. Hint: What happens when both factors are the same?
In the code you are using i <= n / 2 because for any numbers, you can't divide itself by another number greater than its half.
Let's take 29 for example (and use int, so not floating part).
29 / 2 = 14
29 / 3 = 9
29 / 4 = 7
29 / 5 = 5
...
29 / 14 = 2
29 / 15 = 1
29 / 16 = 1
...
Here, you see that after 14 (the half of 29), all the results are 1.
If you wish to, you can even use this formula n > i * i. Let me explain with this example. Here, we should stop at i = 5 because 29 < 6 * 6
29 / 2 = 14
29 / 3 = 9
29 / 4 = 7
29 / 5 = 5
===== END HERE (but let's continue to see what happens) =====
29 / 6 = 4
29 / 7 = 4
29 / 8 = 3
...
You can see that after 5, the results become smaller than the index, so you are just recalculating something that you have already calculated. It avoids timeouts on big numbers.

We are given a number lets say m. We have to distribute the number into n parts

Lets says I have a number m = 9. I want to divide it into n=5 parts like given below:
As m>n, each part will get at least 1.
First give 1 to all 5 parts
part0: 1,
part1: 1,
part2: 1,
part3: 1,
part4: 1
Now for the remaining (9 - 5 = 4) divide again starting from 1st. final allocation looks like:
part0: 2
part1: 2
part2: 2
part3: 2
part4: 1
algo:
take an array arr[n]={0}.
x=0
while(m) {
arr[x]+=1;
m--;
x=(x+1)%n;
}
My question is I don't want to run this loop to divide n into m parts. Mathematically, how can I know the value allocated to a part directly. i.e part0: 2 for above example.
Integer division gets you the "base" size of all parts: 9 / 5 == 1.
Modulo gives you the remainder, 9 % 5 == 4. This means you should add 1 to the first 4 parts.
int partCount = 5;
int number = 9;
int base = number / partCount;
int remain = number % partCount;
for (int i=0; i<partCount; i++) {
part[i] = base;
if (i < remain) part[i]++;
}
The algorithm might be clearer if you use larger numbers. E.g. 31 in 7 parts:
31 / 7 == 4 - so we have 7 parts of 4 each, (== 28) plus the remainder:
31 % 7 == 3 - give the first 3 parts 1 more each to make 31 total.
for (i=0; i<n; i++) {
arr[i] = m/n + (m%n < i ? 1 : 0);
}

How to find Number of Factors of "product of numbers"

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;
}

Resources