Generating random number between 2 variables - c

I'm struggling to find a way to generate a random number only between 20 and 30. I have this so far but its getting numbers below 20.
int num1 = 30;
int num2 = 20;
int num_random = rand()%num1;
while (num_random < num2){
num_random = rand()%30;
}

To get numbers between 20 and 30 use:
(rand() % 10) + 20
General formula would be:
(rand() % (difference_between_upper_and_lower_limit)) + lower_limit
The resultant of Difference between upper and lower limit will be:
(0, no_of_numbers_between_upper_and_lower_limit)

Maybe you can try rand()/10 + 20.

Try this:
int num1 = 30;
int num2 = 20;
int num_random;
while (1){
num_random = rand()%num1;
if(num_random < num2)
break;
}

Related

Im trying to do Luhn's algorith to check on valid credit cards, but i cant get to sum the numbers

Im trying to get the sum with Luhn's algorithm with this credit card number: 4003600000000014
I'm getting this output:
Sum single numbers: 4195600
Multiplied numbers: 0
I'm trying to get 13 and 7...
Appreciate some help!
#include <stdio.h>
int main(void)
{
do
{
long card_number = get_long("Write your card's number:");
} while (card_number < 0);
// Sum of numbers that wont be multiplied by two
int non_mult_numbers = card_number;
while (non_mult_numbers > 0)
{
int last_digit = non_mult_numbers % 10;
int sum_non_mult_numbers = sum_non_mult_numbers + last_digit;
non_mult_numbers = non_mult_numbers / 100;
}
printf("Sum single numbers: %i\n", sum_non_mult_numbers);
// Sum of numbers that will be multiplied by two and their digits added
int mult_numbers = card_number;
mult_numbers = mult_numbers / 10;
while (mult_numbers > 0)
{
last_digit = mult_numbers % 10;
int digit_times_two = last_digit * 2;
int add_digits = add_digits + digit_times_two % 10 + digit_times_two / 10;
mult_numbers = mult_numbers / 100;
}
printf("Multiplied numbers: %i\n", add_digits);
}
While your code does not compile, I assume that several of your variables have wrong scope/lifetime.
Check add_digits, sum_non_mult_numbers, card_number.
Focus on the fact that {} mark a scope boundary for the variables defined inside.

How to add product digits rather than products themselves in C?

I am trying to finish an assignment in C for the CS50 course in which I must implement Luhn's algorithm to validate a credit card number. Here is a quick example to elaborate:
credit card number: 4003600000000014.
Now for every other digit, starting with the number’s second-to-last digit:
1-0-0-0-0-6-0-4
Let’s multiply each of the digits by 2:
1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2
That gives us:
2 + 0 + 0 + 0 + 0 + 12 + 0 + 8
Now let’s add those products’ digits (i.e., not the products themselves) together:
2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13
Now let’s add that sum (13) to the sum of the digits that weren’t multiplied by 2 (starting from the end):
13 + 4 + 0 + 0 + 0 + 0 + 0 + 3 + 0 = 20
Yup, the last digit in that sum (20) is a 0, so the number is valid.
I figured out how to extract each number in the credit card individually (I know my way is boring and probably not practical), so the next step is to multiply every other number by two and add (the products' digits, not the digits themselves) and this is what I need help of how to do it?
MY code:
#include <cs50.h>
#include <stdio.h>
#include <math.h>
int main(void)
{
long credit_card_number;
do
{
credit_card_number = get_long("Enter your credit card number: ");
}
while (credit_card_number < 1 || credit_card_number > 9999999999999999);
//American Express uses 15-digit numbers. American Express numbers start with 34 or 37
//MasterCard uses 16-digit numbers. MasterCard numbers start with 51, 52, 53, 54, or 55.
//Visa uses 13- and 16-digit numbers. Visa numbers start with 4.
// checksum
long last_number;
long credit_card_without_last_number;
long second_to_last_number;
long credit_card_without_second_number;
long third_number;
long credit_card_without_third_number;
long fourth_number;
long credit_card_without_fourth_number;
long fifth_number;
long credit_card_without_fifth_number;
long sixth_number;
long credit_card_without_sixth_number;
long seventh_number;
long credit_card_without_seventh_number;
long eighth_number;
long credit_card_without_eighth_number;
long ninth_number;
long credit_card_without_ninth_number;
long tenth_number;
long credit_card_without_tenth_number;
long eleventh_number;
long credit_card_without_eleventh_number;
long twelfth_number;
long credit_card_without_twelfth_number;
long thirteenth_number;
long credit_card_without_thirteenth_number;
long fourteenth_number;
long credit_card_without_fourteenth_number;
long fifteenth_number;
long credit_card_without_fifteenth_number;
long sixteenth_number;
long multiply_digits;
//separating each number starting from the last (right)in its own variable.
last_number = credit_card_number % 10;
credit_card_without_last_number = credit_card_number / 10;
second_to_last_number = credit_card_without_last_number % 10;
credit_card_without_second_number = credit_card_without_last_number / 10;
third_number = credit_card_without_second_number % 10;
credit_card_without_third_number = credit_card_without_second_number / 10;
fourth_number = credit_card_without_third_number % 10;
credit_card_without_fourth_number = credit_card_without_third_number / 10;
fifth_number = credit_card_without_fourth_number % 10;
credit_card_without_fifth_number = credit_card_without_fourth_number / 10;
sixth_number = credit_card_without_fifth_number % 10;
credit_card_without_sixth_number = credit_card_without_fifth_number / 10;
seventh_number = credit_card_without_sixth_number % 10;
credit_card_without_seventh_number = credit_card_without_sixth_number / 10;
eighth_number = credit_card_without_seventh_number % 10;
credit_card_without_eighth_number = credit_card_without_seventh_number / 10;
ninth_number = credit_card_without_eighth_number % 10;
credit_card_without_ninth_number = credit_card_without_eighth_number / 10;
tenth_number = credit_card_without_ninth_number % 10;
credit_card_without_tenth_number = credit_card_without_ninth_number / 10;
eleventh_number = credit_card_without_tenth_number % 10;
credit_card_without_eleventh_number = credit_card_without_tenth_number / 10;
twelfth_number = credit_card_without_eleventh_number % 10;
credit_card_without_twelfth_number = credit_card_without_eleventh_number / 10;
thirteenth_number = credit_card_without_twelfth_number % 10;
credit_card_without_thirteenth_number = credit_card_without_twelfth_number / 10;
fourteenth_number = credit_card_without_thirteenth_number % 10;
credit_card_without_fourteenth_number = credit_card_without_thirteenth_number / 10;
fifteenth_number = credit_card_without_fourteenth_number % 10;
credit_card_without_fifteenth_number = credit_card_without_fourteenth_number / 10;
sixteenth_number = credit_card_without_fifteenth_number % 10;
//Here I need the help to multiply these numbers by two and then add each product's
//digits to the rest of the unused numbers.
multiply_digits = (second_to_last_number*2)+(fourth_number*2)+(sixth_number*2)+(eighth_number*2)+(tenth_number*2)+(twelfth_number*2)+(fourteenth_number*2)+(sixteenth_number*2);
}
Try doing this instead
int main(){
long cNo = 4003600000000014;
int arr[16];
for(int i=0; i<16; i++){
arr[15-i] = cNo % 10;
cNo /= 10;
}
int multipliedSum = 0;
for(int i=0; i<16; i++){
if(i%2==1)
multipliedSum += arr[i];
else{
if(arr[i]*2<10){
multipliedSum += (arr[i]*2);
}else{
int num = arr[i]*2;
while(num){
multipliedSum += num%10;
num/=10;
}
}
}
}
printf("valid = %s\n",multipliedSum%10==0?" True": " False");
}
You will get the following
valid = True
A general algorithm for adding digits (assuming an integer type):
Initialize your sum to 0: sum = 0
Extract the lowest digit from the number using the % modulus operator: digit = number % 10
Add the value of that digit to the sum: sum += digit (shorthand for sum = sum + digit)
Divide the number by 10: number /= 10 (shorthand for number = number / 10
If the number is non-zero after dividing by 10, go back to 2
End
The modulus operator % returns the integer remainder of an integer division - 123 / 10 == 12 rem 3. So the remainder of dividing the number by 10 is the least significant decimal digit of the number. Notice that integer division gives you an integer result - 123 / 10 == 12, not 12.3.
You'll want to put this in a separate function, so you can write something like
int sumdig( int v )
{
...
}
int main( void )
{
int value = 123;
int sum = sumdig( value ); // sumdig will return 1 + 2 + 3, or 6
...
}
When you find yourself creating a bunch of separate variables of the same type with the same name except for some tacked-on ordinal (var1, var2, var3 or first_thing, second_thing, third_thing), that's a real strong hint you want to use an array. You can use an array to store the individual digits of your card number:
int number[16];
and use the % 10 method as described above to extract the individual digits:
long tmp = credit_card_number; // use a temporary so we preserve the original card number
for ( int i = 0; i < 16; i++ )
{
number[i] = tmp % 10;
tmp /= 10;
}
This means that the least significant (rightmost) card number digit will be stored in number[0] and the most significant (leftmost) card number digit will be stored in number[15], so be aware of that. For the purposes of validating the number it doesn't matter, but if you want to display the contents of the array you'll have to take that into account.
Using an array makes it easier to extract subsets of digits:
for ( int i = 1; i < 16; i += 2 ) // hit every other element starting at element 1
{
number[i] *= 2; // multiply these digits by 2
}
That loop above executes the "1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2" portion of your algorithm.
You should be able to figure out the rest from there. Hope this helps.
Hint: to extract one digit from a number, mod it by 10.
So say that you want to figure out the sum of the digits of a number, say 123456, you will do the following:
(pseudocode)
number=123456;
sum=0;
loop if number is not 0{
sum+=number % 10;
number-=number % 10;
number=(int)(number/10);
}
Now try to implement it as a function, say digit(), and when you are trying to add some numbers digit-wise, say 123 and 456, just do digit(123)+digit(456) instead.

Generating random numbers in conditions

I'm trying to generate three random numbers in three conditions and the three numbers must be from 0 to 100:
an odd number
an even number
a number larger than 50
Here is my code:
#include <stdio.h>
#include <time.h>
int main (void) {
int num1 = 0, num2 = 0, num3 = 0;
srand(time(NULL));
num1 = rand() % 100;
while (num1 % 2 != 0) {
num1 = rand() % 100;
}
num2 = rand() % 100;
while (num2 % 2 == 0) {
num2 = rand() % 100;
}
num3 = rand() % 100;
while (num3 > 50) {
num3 = rand() % 100;
}
printf("your numbers\n%d\n%d\n%d\n", num1, num2, num3);
return 0;
}
the compiler answers me:
warning: implicit declaration of function 'srand' [-Wimplicit-function-declaration]
srand(time(NULL));
and I do have stand in the requirements of the school:
it must be in loops
I cannot use break nor TRUE nor FALSE
Your srand() issue is simply because you haven't included stdlib.h, where that call (and rand() for that matter) is declared.
In any case, there's no real need to use a loop while discarding "invalid" numbers, you can use math for this :-) (a)
Assuming 0 to 100 inclusive:
num1 = rand() % 50 * 2 + 1 // 1, 3, 5, ..., 99
num2 = rand() % 51 * 2 // 0, 2, 4, ..., 100
num3 = rand() % 50 + 51 // 51, 52, ..., 100
For num1, the % gives a value 0..49 which, when doubled and incremented, gives you an odd number in the desired range. The second one is similar but with the range expanded slightly since there are even numbers at both ends. The third simply gives a number 0..49 which maps to 51..100 when 51 is added.
Similar results can be obtained if the range is only half-open (0..99 inclusive):
num1 = rand() % 50 * 2 + 1 // 1, 3, 5, ..., 99
num2 = rand() % 50 * 2 // 0, 2, 4, ..., 98
num3 = rand() % 49 + 51 // 51, 52, ..., 99
If, for some bizarre reason it has to use a loop (despite the inefficiencies), you have some problems with the conditions you use - they're basically all the wrong sense. In other words, you want (for example) the first loop to run while the number is even so that it will eventually produce an odd number.
You should be able to use something like the following. Each block consists of initialising the variable to a value that will force the loop to start then the loop that continues until a value with the desired properties is found:
int num1 = 0; // even forces loop entry
while ((num1 % 2) == 0) // wait for odd
num1 = rand() % 100;
int num2 = 1; // odd forces loop entry
while ((num2 % 2) == 1) // wait for even
num2 = rand() % 100;
int num3 = 1; // 50 or less forces loop entry
while (num3 <= 50) // wait for 51+
num3 = rand() % 100;
All of these limit the range of potential values to 0..99 inclusive, If you want to include 100, simply change the expressions to be rand() % 101.
(a) I'm actually not a fan of these sorts of limitations when set by educators. They're actually teaching inefficient ways to code. It would be far better if it was something that was a lot harder to do with a simple mathematical operation (like ensuring the number was neither 11, 17, 43 nor 97).
I suspect you could find a mathematical way to detect that but it would be far easier just to use a series of conditionals. Now I'm just waiting for someone to show me up by providing the mathematical formula for detecting those four :-)
There are some mistakes in the posted code:
a missing #include <stdlib.h>
the first test should be while (num1 % 2 == 0)
the second test should be while (num2 % 2 != 0)
the third test should be while (num3 <= 50)
Here is a modified version with loops but without looping :)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main (void) {
int num1, num2, num3;
srand(time(NULL)); /* or better randomness with srand(clock()); */
num1 = 1 + rand() % 50 * 2; /* 1, 3, ..., 99 */
while (num1 % 2 == 0) {
num1 = rand() % 100;
}
num2 = rand() % 50 * 2; /* 0, 2, ..., 98 */
while (num2 % 2 != 0) {
num2 = rand() % 100;
}
num3 = 51 + rand() % 49; /* 51, 52, ..., 99 */
while (num3 <= 50) {
num3 = rand() % 100;
}
printf("your numbers\n%d\n%d\n%d\n", num1, num2, num3);
return 0;
}
For those interested, both gcc and clang detect that the first 2 loops can be eliminated, but not the third as they do not make the assumption that rand() return a non negative number: https://godbolt.org/z/ucpV-y
You need to #include <stdlib.h> to get rid of this warning.
However, there's a bigger problem with your code: you have all the conditions inverted.
This will loop until the number is odd:
while (num1 % 2 != 0) {
This will loop until the number is even:
while (num2 % 2 == 0) {
And this will loop until the number is less than or equal to 50:
while (num3 > 50) {
To fix that, simply invert the conditions:
while (num1 % 2 == 0) { /* until we get an even number */
/* ... */
while (num2 % 2 != 0) { /* until we get an odd number */
/* ... */
while (num3 <= 50) { /* until num3 is greater than 50 */

Swap number digit order by separate a number into arrays and then merge

I can't elaborate a program with arrays language C.
The console received 4 numbers. I want to change the first number digits and multiply with the other.
Example input: 1260
Desire output: Change 12 to 21 and them multiple by 60 -> so output will be 1260 (as 21 * 60)
This is my current code:
int main() {
int number, temp;
int newnumber[4];
int n = 3;
printf("put the number");
scanf("%d", &number);
do {
newnumber[n] = number % 10;
number = number / 10;
n--;
} while (n >= o);
temp = newnumber[1];
newnumber[1] = newnumber[2];
newnumber[2] = temp;
}
know how i do 21 multiply with 60?
If we look at your example:
1260 => change 2 with 1, and multiply 21 with 60.
The permutation in your main function is wrong, cause you changed numbers at the index 1 (second position) and 2 (third position).
Back to your question, you can get the result you're looking for by doing the oppisite of what you did to get the units, tens and hundreds...
int main() {
int number, temp1, temp2;
int newnumber[4];
int n = 3;
printf("put the number");
scanf("%d", &number);
do {
newnumber[n] = number % 10;
number = number / 10;
n--;
} while (n >= 0);
temp1 = newnumber[0];
newnumber[0] = newnumber[1];
newnumber[1] = temp1;
temp1 = newnumber[0] * 10;
temp1 += newnumber[1];
temp2 = newnumber[2] * 10;
temp2 += newnumber[3];
printf("%d", temp1 * temp2);
}
I would have go with slightly different approach: first separate the numbers. Then call function to change the number order.
If you always get numbers with 2 digit you can do this:
int first = number / 100;
int second = number % 100;
And a function to swap the digit:
function swapDigits(int num) {
int ans = 0;
while (num > 0) {
ans = ans * 10 + num % 10;
num /= 10;
}
return ans;
}
Now just do second * swapDigits(first) to get your result.
I'm not c expert so verify my code before use...
If your conditions always hold you can keep it simple and do something like this:
int main() {
int number;
int newnumber[4];
int n = 3;
printf("put the number");
scanf("%d", &number);
do {
newnumber[n] = number % 10;
number = number / 10;
n--;
} while (n >= 0);
printf("And the result: %d\n", (newnumber[1] * 10 + newnumber[0]) * (newnumber[2] * 10 + newnumber[3]));
}
Then you are not getting the individual digits, but pairs and the like. Just get the last two digits in one shot:
int rem = number % 100; /* last two digits */
number /= 100;
int msd = number % 10; /* next, third digit */
number /= 10;
int lsd = number % 10; /* most significant digit */
/* I don't assume you have more digits, because you are doing different
* operations with them, no pattern up to here, but you should continue
* your approach here. */
int out = (msd * 10 + lsd) * rem;
should give you a solution. No arrays needed.

simple C problem

I have had to start to learning C as part of a project that I am doing. I have started doing the 'euler' problems in it and am having trouble with the first one. I have to find the sum of all multiples of 3 or 5 below 1000. Could someone please help me. Thanks.
#include<stdio.h>
int start;
int sum;
int main() {
while (start < 1001) {
if (start % 3 == 0) {
sum = sum + start;
start += 1;
} else {
start += 1;
}
if (start % 5 == 0) {
sum = sum + start;
start += 1;
} else {
start += 1;
}
printf("%d\n", sum);
}
return(0);
}
You've gotten some great answers so far, mainly suggesting something like:
#include <stdio.h>
int main(int argc, char * argv[])
{
int i;
int soln = 0;
for (i = 1; i < 1000; i++)
{
if ((i % 3 == 0) || (i % 5 == 0))
{
soln += i;
}
}
printf("%d\n", soln);
return 0;
}
So I'm going to take a different tack. I know you're doing this to learn C, so this may be a bit of a tangent.
Really, you're making the computer work too hard for this :). If we figured some things out ahead of time, it could make the task easier.
Well, how many multiples of 3 are less than 1000? There's one for each time that 3 goes into 1000 - 1.
mult3 = ⌊ (1000 - 1) / 3 ⌋ = 333
(the ⌊ and ⌋ mean that this is floor division, or, in programming terms, integer division, where the remainder is dropped).
And how many multiples of 5 are less than 1000?
mult5 = ⌊ (1000 - 1) / 5 ⌋ = 199
Now what is the sum of all the multiples of 3 less than 1000?
sum3 = 3 + 6 + 9 + ... + 996 + 999 = 3×(1 + 2 + 3 + ... + 332 + 333) = 3×∑i=1 to mult3 i
And the sum of all the multiples of 5 less than 1000?
sum5 = 5 + 10 + 15 + ... + 990 + 995 = 5×(1 + 2 + 3 + ... + 198 + 199) = 5×∑i = 1 to mult5 i
Some multiples of 3 are also multiples of 5. Those are the multiples of 15.
Since those count towards mult3 and mult5 (and therefore sum3 and sum5) we need to know mult15 and sum15 to avoid counting them twice.
mult15 = ⌊ (1000 - 1) /15 ⌋ = 66
sum15 = 15 + 30 + 45 + ... + 975 + 990 = 15×(1 + 2 + 3 + ... + 65 + 66) = 15×∑i = 1 to mult15 i
So the solution to the problem "find the sum of all the multiples of 3 or 5 below 1000" is then
soln = sum3 + sum5 - sum15
So, if we wanted to, we could implement this directly:
#include <stdio.h>
int main(int argc, char * argv[])
{
int i;
int const mult3 = (1000 - 1) / 3;
int const mult5 = (1000 - 1) / 5;
int const mult15 = (1000 - 1) / 15;
int sum3 = 0;
int sum5 = 0;
int sum15 = 0;
int soln;
for (i = 1; i <= mult3; i++) { sum3 += 3*i; }
for (i = 1; i <= mult5; i++) { sum5 += 5*i; }
for (i = 1; i <= mult15; i++) { sum15 += 15*i; }
soln = sum3 + sum5 - sum15;
printf("%d\n", soln);
return 0;
}
But we can do better. For calculating individual sums, we have Gauss's identity which says the sum from 1 to n (aka ∑i = 1 to n i) is n×(n+1)/2, so:
sum3 = 3×mult3×(mult3+1) / 2
sum5 = 5×mult5×(mult5+1) / 2
sum15 = 15×mult15×(mult15+1) / 2
(Note that we can use normal division or integer division here - it doesn't matter since one of n or n+1 must be divisible by 2)
Now this is kind of neat, since it means we can find the solution without using a loop:
#include <stdio.h>
int main(int argc, char *argv[])
{
int const mult3 = (1000 - 1) / 3;
int const mult5 = (1000 - 1) / 5;
int const mult15 = (1000 - 1) / 15;
int const sum3 = (3 * mult3 * (mult3 + 1)) / 2;
int const sum5 = (5 * mult5 * (mult5 + 1)) / 2;
int const sum15 = (15 * mult15 * (mult15 + 1)) / 2;
int const soln = sum3 + sum5 - sum15;
printf("%d\n", soln);
return 0;
}
Of course, since we've gone this far we could crank out the entire thing by hand:
sum3 = 3×333×(333+1) / 2 = 999×334 / 2 = 999×117 = 117000 - 117 = 116883
sum5 = 5×199×(199+1) / 2 = 995×200 / 2 = 995×100 = 99500
sum15 = 15×66×(66+1) / 2 = 990×67 / 2 = 495 × 67 = 33165
soln = 116883 + 99500 - 33165 = 233168
And write a much simpler program:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("233168\n");
return 0;
}
You could change your ifs:
if ((start % 3 == 0) || (start % 5 == 0))
sum += start;
start ++;
and don´t forget to initialize your sum with zero and start with one.
Also, change the while condition to < 1000.
You would be much better served by a for loop, and combining your conditionals.
Not tested:
int main()
{
int x;
int sum = 0;
for (x = 1; x <= 1000; x++)
if (x % 3 == 0 || x % 5 == 0)
sum += x;
printf("%d\n", sum);
return 0;
}
The answers are all good, but won't help you learn C.
What you really need to understand is how to find your own errors. A debugger could help you, and the most powerful debugger in C is called "printf". You want to know what your program is doing, and your program is not a "black box".
Your program already prints the sum, it's probably wrong, and you want to know why. For example:
printf("sum:%d start:%d\n", sum, start);
instead of
printf("%d\n", sum);
and save it into a text file, then try to understand what's going wrong.
does the count start with 1 and end with 999?
does it really go from 1 to 999 without skipping numbers?
does it work on a smaller range?
Eh right, well i can see roughly where you are going, I'm thinking the only thing wrong with it has been previously mentioned. I did this problem before on there, obviously you need to step through every multiple of 3 and 5 and sum them. I did it this way and it does work:
int accumulator = 0;
int i;
for (i = 0; i < 1000; i += 3)
accumulator += i;
for (i = 0; i < 1000; i +=5) {
if (!(i%3==0)) {
accumulator += i;
}
}
printf("%d", accumulator);
EDIT: Also note its not 0 to 1000 inclusive, < 1000 stops at 999 since it is the last number below 1000, you have countered that by < 1001 which means you go all the way to 1000 which is a multiple of 5 meaning your answer will be 1000 higher than it should be.
You haven't said what the program is supposed to do, or what your problem is. That makes it hard to offer help.
At a guess, you really ought to initialize start and sum to zero, and perhaps the printf should be outside the loop.
Really you need a debugger, and to single-step through the code so that you can see what it's actually doing. Your basic problem is that the flow of control isn't going where you think it is, and rather than provide correct code as others have done, I'll try to explain what your code does. Here's what happens, step-by-step (I've numbered the lines):
1: while (start < 1001) {
2: if (start % 3 == 0) {
3: sum = sum + start;
4: start += 1;
5: }
6: else {
7: start += 1;
8: }
9:
10: if (start % 5 == 0) {
11: sum = sum + start;
12: start += 1;
13: }
14: else {
15: start += 1;
16: }
17: printf("%d\n", sum);
18: }
line 1. sum is 0, start is 0. Loop condition true.
line 2. sum is 0, start is 0. If condition true.
line 3. sum is 0, start is 0. sum <- 0.
line 4. sum is 0, start is 0. start <- 1.
line 5. sum is 0, start is 1. jump over "else" clause
line 10. sum is 0, start is 1. If condition false, jump into "else" clause.
line 15. sum is 0, start is 1. start <- 2.
line 16 (skipped)
line 17. sum is 0, start is 2. Print "0\n".
line 18. sum is 0, start is 2. Jump to the top of the loop.
line 1. sum is 0, start is 2. Loop condition true.
line 2. sum is 0, start is 2. If condtion false, jump into "else" clause.
line 7. sum is 0, start is 2. start <- 3.
line 10. sum is 0, start is 3. If condition false, jump into "else" clause.
line 15. sum is 0, start is 3. start <- 4.
line 17. sum is 0, start is 4. Print "0\n".
You see how this is going? You seem to think that at line 4, after doing sum += 1, control goes back to the top of the loop. It doesn't, it goes to the next thing after the "if/else" construct.
You have forgotten to initialize your variables,
The problem with your code is that your incrementing the 'start' variable twice. This is due to having two if..else statements. What you need is an if..else if..else statement as so:
if (start % 3 == 0) {
sum = sum + start;
start += 1;
}
else if (start % 5 == 0) {
sum = sum + start;
start += 1;
}
else {
start += 1;
}
Or you could be more concise and write it as follows:
if(start % 3 == 0)
sum += start;
else if(start % 5 == 0)
sum += start;
start++;
Either of those two ways should work for you.
Good luck!
Here's a general solution which works with an arbitrary number of factors:
#include <stdio.h>
#define sum_multiples(BOUND, ...) \
_sum_multiples(BOUND, (unsigned []){ __VA_ARGS__, 0 })
static inline unsigned sum_single(unsigned bound, unsigned base)
{
unsigned n = bound / base;
return base * (n * (n + 1)) / 2;
}
unsigned _sum_multiples(unsigned bound, unsigned bases[])
{
unsigned sum = 0;
for(unsigned i = 0; bases[i]; ++i)
{
sum += sum_single(bound, bases[i]);
for(unsigned j = i + 1; bases[j]; ++j)
sum -= sum_single(bound, bases[i] * bases[j]);
}
return sum;
}
int main(void)
{
printf("%u\n", sum_multiples(999, 3, 5));
return 0;
}

Resources