Hi so I am using C code and trying to create a table where the number gets incremented in multiples of 5 starting from 1 to 5 to 10 to... all the way until the user's input. What I've gotten so far is that it starts at 1 and then increases the number by 5 like 1 to 6 to 11 to 16... until it gets to where it can't increase the number by 5 anymore without going above the user's input. Could someone help me set up the for loop better?
Here's the segment of my code I'm talking about:
else //run this statement if the user inputs a number greater than 14
{
printf("Number Approximation1 Approximation2\n-----------------------------------------------------\n"); //prints the header for second table
for ( i = 1; i <= n; i += 5 )
{
printf("%d %e %e\n", i, stirling1( i ), stirling2( i )); //calls functions to input approximate factorials
}
}
So with this code if I input n as 28, I get i to increment from 1 to 6 to 11 to 16 to 21 to 26.
What I want the code to do if I input n as 28 is increment i from 1 to 5 to 10 to 15 to 20 to 25 to 28.
Thanks in advance!
Try this:
{
printf("Number Approximation1 Approximation2\n-----------------------------------------------------\n"); //prints the header for second table
printf("%d %e %e\n", i, stirling1( 1 ), stirling2( 1 ));
for ( i = 5; i <= n; i += 5 )
{
printf("%d %e %e\n", i, stirling1( i ), stirling2( i )); //calls functions to input approximate factorials
}
}
This will print values for 1, 5, 10, 15, 20... and so on
Note that, besides an extra line of code, its faster than adding an "if" inside the loop.
I added two if statements which would help you deal with the special cases of having statements printed at i = 1 and i = n besides having the statement printed every 5.
else //run this statement if the user inputs a number greater than 14
{
printf("Number Approximation1 Approximation2\n-----------------------------------------------------\n"); //prints the header for second table
for ( i = 1; i <= n; i += 5 )
{
printf("%d %e %e\n", i, stirling1( i ), stirling2( i )); //calls functions to input approximate factorials
if (i == 1){
//when it iterates at the end of this loop, i = 5.
//In your example, you will get i from 1 to 5 to 10 up to 25 etc.
i = 0;
}
if ( (i + 5) > n){
// for the next loop, it will check if i will exceed n on the next increment.
// you do not want this to happen without printing for n = i.
//In your case if n = 28, then i will be set to 23, which will then increment to 28.
i = n - 5;
}
}
}
There are probably other more elegant ways of achieving this, but this is just a simple example of what you could try.
Related
who can assess here?
I need a step-by-step explanation of this program, in particular, I'm interested in this line of code:
for(i = n-((n+1) % 2); i>=1; i-=2)
#include <stdio.h>
int main()
{
int i, n;
scanf("%d",&n);
for(i = n-((n+1) % 2); i>=1; i-=2)
{
if(i%2==1)
printf("%d ", i);
}
return 0;
}
This expression
n-((n+1) % 2)
yields the closest odd number that is equal to or less than n.
For example if n is an even number for example is equal to 2 then the expression will be equal to the odd number 1.
That is you will have in this case
2 - ( ( 2 + 1 ) % 2 )
that is equivalent to
2 - ( 3 % 2 )
that in turn is equivalent to
2 - 1
If n is an odd number for example equal to 3 then the expression will be equal to 3.
So subtracting 2 as
i-=2
you will have always an odd number.
Thus this statement in the body of the for loop
if(i%2==1)
printf("%d ", i);
outputs positive odd numbers in the descending order.
For example if n is equal to 10 then i will be initially equal to 9 and the loop outputs
9 7 5 3 1
The if statement is redundant. You could just write
printf("%d ", i);
Logic: I am trying to loop from 3 to 100 and put all prime numbers in that range in an array. I do this by first putting 2 manually into the array. After that, I loop over all the numbers and if a number is not divisible by all the prime numbers I have added to the array, it is a prime. The logic itself is not really valid in my opinion but this is a homework problem and I need to do it the way the professor wants it to be done.
So I try to loop and it gets to a point and the program just crashes. What am I doing wrong here?
int primeNums_lessThan100[25] = {2}; //25 is the size here because there are only 25 prime numbers under 100.
int primeNums_lessThan100_length = 1;
for(int counter = 3 ; counter < 100 ; counter++)
{
printf("Entered here!\n");
for(int array_idx = 0; array_idx < primeNums_lessThan100_length ; array_idx++)
{
if(counter % primeNums_lessThan100[array_idx] != 0)
{
printf("Entered here, TOO!\n");
primeNums_lessThan100[array_idx+1] = counter;
primeNums_lessThan100_length++;
}
else
{
continue;
}
}
}
You have a basic error in your logic. It's not enough to find out the counter value is coprime with some previously found prime to determine counter is prime itself. You need to test it is coprime with all primes found.
Suppose counter == 9 and you test it against the first item of your 'prime' numbers, which is 2. The result of 9 % 2 is of course 1, which is not equal zero and your program adds 9 to the array as a prime number. It happens even earlier for counter == 4 — first you find out it is divisible by 2 and reiterate the loop to find out in the next step 4 % 3 != 0 and add 4 to 'primes'.
As a further result the array overflows (you put more numbers into it than you expected and declared; actually, you put every natural number to it, because each N greater than 2 is not divisible by (N-1)), which means you eventually write past the end of the array, thus triggering an Undefined Behavior.
That displays also a basic error in the design: you do not check your array_idx against the array size, which might allow you to handle the error in some civilized manner.
the following proposed code:
cleanly compiles
performs the desired functionality
comments in code explain what is being done
note use of size_t for numbers that will never be less than 0
Note that all prior prime values are checked against the testPrime
Note that when a prime is found, it is placed in the next available entry in the array: `primeNums[]
and now, the proposed code:
#include <stdio.h> // puts(), printf()
// eliminate ''magic' numbers by giving them meaningful names
//25 is the size here because there are only 25 prime numbers under 100
#define MAX_PRIMES 25
#define TEST_LIMIT 100
int main( void )
{
// declare prime number array and init to 0
int primeNums[ MAX_PRIMES ] = {0};
// pre-set first prime number
primeNums[0] = 2;
// init number of primes found
size_t primeCount = 1;
// test all values of interest
for( int testPrime = 3 ; testPrime < TEST_LIMIT ; testPrime++ )
{
// init 'prime' indicator, 1 means value is prime
size_t Prime = 1;
for( size_t prime_idx = 0; prime_idx < MAX_PRIMES; prime_idx++ )
{
// check that array of prime values contains a valid prime
if( primeNums[ prime_idx ] )
{
if( testPrime % primeNums[ prime_idx ] == 0 )
{
// indicate not a prime number
Prime = 0;
}
}
else
{ // else, all previously found prime numbers checked
break;
} // end if
} // end for each prime already found
if( Prime )
{ // then test number was prime
// update the array of primes
primeNums[ primeCount ] = testPrime;
// update the count of primes found
primeCount++;
}
}
// display the found primes
for( size_t i = 0; i < primeCount; i++ )
{
printf( "%d, ", primeNums[i] );
}
// assure the data gets displayed on the terminal before the program exits
puts( "" );
}
a run of the proposed code results in:
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
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 have an assignment to write a code that prints out all prime numbers between 1-100. I am looking at different programs to get an idea on what to do and keep running into i.e. "if (x%c == 0)".
Now I can't find out what the "x%c" means. I've looked around a lot and can't find any good answers anywhere. Possibly because of searching for the wrong thing. What exactly does that do in the following code?
#include<stdio.h>
int main()
{
int n, i = 3, count, c;
printf("Enter the number of prime numbers required\n");
scanf("%d",&n);
if ( n >= 1 )
{
printf("First %d prime numbers are :\n",n);
printf("2\n");
}
for ( count = 2 ; count <= n ; )
{
for ( c = 2 ; c <= i - 1 ; c++ )
{
if ( i%c == 0 )
break;
}
if ( c == i )
{
printf("%d\n",i);
count++;
}
i++;
}
return 0;
}
It is the modulo operation.
https://en.wikipedia.org/wiki/Modulo_operation
It is the remainder, if you do a division in integer space.
for example:
3 % 3 = 3 mod 3 = 0
means if you divide 3 by 3 you get one and the remainder is 0.
If the division leaves no remainder the first number is a multiple of the second.
That means it is not a prime (if the number you divide with is not 1 or the same number)
A full example
15 % 2 = 1
15 % 3 = 0
15 is no prime
"percentage in-between variables" is the operator for finding the remainder in C.
For example, if x = 10 and y = 4, then, x % y would be 2.
for ( c = 2 ; c <= i - 1 ; c++ )
{
if ( i%c == 0 )
break;
}
In the code snippet above, we will break out of this loop when a value of c is reached such that i is divisible by c i.e. i when divided by c gives 0 as the remainder.
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