Time Exceeded for a project Euler test - c

I just got into problem solving on project Euler (and a beginner with C code).
Problem 1 states: If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000. I'm pretty sure my code is correct (or maybe not). Now when I compile my code on a website like codepad.org or ideone.com, it says "time exceeded". I'm guessing the code takes too long to run? Why is this the case?
My solution:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
int main (int argc, char *argv[]){
int i, j = 0;
for (i = 1; i <= 1000; i++){ //Traverses all the positive numbers under 1000
while ( (i % 5 == 0) || (i % 3 == 0)){
j = j + i; //If it's a multiple of 3 or 5 add it to the sum
}
}
printf("The sum of all multiples of 3 and 5 under 1000 is: %d", j);
return 0;
}

You have a while statement in there which should be an if statement. while takes you into an infinite loop as you never change the value of i inside the loop when the condition you are testing for is met.

Related

Problem with continue instruction after rand() function

I just wanted to solve an exercise that asks me to write a routine to generate a set of even random numbers between 2 to 10.
The problem is when printing, because I want the last number not to be followed by a comma.
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int i, a, b, c;
i = a = b = c = 0;
srand(time(NULL));
for (i = 2; i <= 10; i++)
{
a = rand() % 8 + 2;
if ((i <= 10) && (a % 2) != 0)
{
continue;
}
printf((i < 10) ? "%d, " : "%d\n", a);
}
return 0;
}
And these are two execution examples:
4, 4, 2, 8,
2, 8, 6, 4, 2
In one the comma does not appear at the end but in another it does. When debugging I see that the error happens when the last number is odd, because the continue statement causes it to go to the next iteration.
As Retired Ninja has said, there are many unnecessary conditionals that can be avoided. I have revised your code so that a will always generate an even number between 2 and 10, thereby removing the need for the logic you implemented. This is what I have assigned this new a value as:
a = ((rand() % 4) * 2 + 2);
This generates a random value between [0,4], multiplies it by 2, and adds 2, for an integer between 2 and 10, noninclusive. Since your new a is always even, I removed your logic to check whether the number is even.
Revised code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int i, a, b, c;
i = a = b = c = 0;
srand(time(NULL));
for (i = 2; i <= 10; i++)
{
a = ((rand() % 4) * 2 + 2);
printf((i < 10) ? "%d, " : "%d\n", a);
}
return 0;
}
Note that this code will always produce 9 numbers, as you have not specified how many values to print each time, just that you need to "write a routine to generate a set of even random numbers between 2 to 10". You can always change the amount of numbers printed by changing the value of i in the for loop. The comma issue, however, is not a problem anymore.
If my solution has helped you, please mark my answer as the correct answer :)

New to programming. Trying to make a program in C that prints even numbers till 10. Can't figure out the logic error

#include <stdio.h>
main()
{
int n=10;
for(int a=n;a>=1;a++) //for bringing out numbers from 1-10
{
int e=a%2; //int e to figure out if the number is even(divisible by 2)
if(e==0)
printf("%d\n",a); //printing the even numbers
}
}
I am new to programming. Learning C.
Here I am trying to make a program that prints even numbers till 10. Executing this code leads to endless even numbers starting from 10.
Can't seem to figure out the logic error here. Some help, please?
The logic for the for loop is not correct.
int n = 10;
for(int a = 0; a <= n; a++) {
if(a%2==0){
printf(a);
}
}
Notice that this is stating at 0, because in CS almost all the time the count starts at 0.
Your loop will never end, it should be:
for(int a = 1; a <= 10; a++)
The entire program should be like that:
#include <stdio.h>
int main(void)
{
for(int a = 1; a <= 10; a++) //for bringing out numbers from 1-10
{
int e = a % 2; //int e to figure out if the number is even(divisible by 2)
if(e == 0)
printf("%d\n", a); //printing the even numbers
}
}
Output:
2
4
6
8
10

C How to Keep a Random Variable From Repeating the Same Number

So I'm just learning C and I would like to know how you could prevent a variable randomized with the rand() function from repeating the same number. I have a script which simply randomizes and prints a variable in a for loop 4 times. How could I make it so the variable never gets the same number after each time it uses the rand() function?
#include <stdio.h>
#include <stdlib.h>
int randomInt;
int main()
{
srand(time(0));
for (int i = 0; i < 4; ++i) {
randomInt = rand() % 4;
printf("%d\n", randomInt);
}
return 0;
}
On most machines, int is 32 bits. So after 232 iterations, you are sure that you'll get some repetition (and probably much before).
If you restrict yourself to much less loops, consider e.g. keeping an array of previously met random numbers (or some hash table, or some binary tree, or some other container).
For a loop repeated only 4 times, keeping an array of (at most 4-1) previously emitted numbers is quite simple, and efficient enough.
Read also about the pigeonhole principle.
A slightly different approach.
int set[] = {0, 1, 2, 3 } ;
srand(time(0));
shuffle(set,4);
using the shuffle algorithm given in this question
https://stackoverflow.com/a/6127606/9288531
I'm guessing that you are getting the same numbers because your are running your program multiple times within the same second. If time(0) hasn't changed, you will have the same seed and the same random numbers generated. Unless your program runs extremely quickly, I imagine using a seed based on microseconds instead of seconds would work:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
int randomInt;
int main()
{
struct timeval my_microtimer;
gettimeofday(&t1, NULL);
srand(t1.tv_sec * my_microtimer.tv_usec);
for (int i = 0; i < 4; ++i) {
randomInt = rand() % 4;
printf("%d\n", randomInt);
}
return 0;
}
What you could do is keeping track of each number you already generated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int hasMyNumberAlreadyBeenGenerated(int number, int generatedNumbers[], int size){
for(int i = 0; i < size + 1; i++){
//If you already generated the number, it should be present somewhere in your array
if(generatedNumbers[i] == number) return 1;
//If you did not, find the first available space in your array, and put the number you generated into that space
if(generatedNumbers[i] == 0){
generatedNumbers[i] = number;
break; //No need to continue to check the array
}
}
return 0;
}
int main()
{
int randomInt;
int generatedNumbers[4];
//We set "0" in all the array, to be sure that the array doesn't contain unknown datas when we create it
memset(generatedNumbers, 0x0, sizeof(generatedNumbers));
srand(time(0));
for (int i = 0; i < 4; ++i) {
randomInt = rand() % 4 + 1;
//As long as the number you generate has already been generated, generate a new one
while(hasMyNumberAlreadyBeenGenerated(randomInt, generatedNumbers, i) == 1){
randomInt = rand() % 4 + 1;
}
printf("generated : %d\n", randomInt);
}
return 0;
}
The problem with this method is that you can't generate a 0, because if you do you'll endlessly loop.
You can bypass this problem using a dynamic array using malloc() function.
If you want to write clean code you should define how many numbers you want to generate with a #define.
What you seem to be asking is a non-random set of numbers 0 to 3 in a random order. Given that;
int set[] = {0, 1, 2, 3 } ;
int remaining = sizeof(set) / sizeof(*set) ;
while( remaining != 0 )
{
int index = rand() % sizeof(set) / sizeof(*set) ;
if( set[index] > 0 )
{
printf( "%d\n", set[index] ) ;
set[index] = -1 ;
remaining-- ;
}
}
For very large sets, this approach may not be practical - the number of iterations necessary to exhaust the set is non-deterministic.

C backtracking generating numbers of 123456789 (1 to 9 digits, all different)

I'd like to generate all numbers like these:
1 digit: 1,2,3,4,5,6,7,8,9 - (I know there are 9 numbers of 1
digit)
2 digits: 12,13..19 then 21,23...29 .......91,92,93,...98 (I know
there are 9*8=72 numbers of 2 digits)...
...
9 digits: 123456789....987654321 (I know there are 9! numbers of 9
digits) all the digits are different from each other
I don't think it's a great idea to write all the loops by hand. So I know for a fact that you most probably have to use backtracking method, but I haven't used it for a while.
You want to generate all k-permutations of n with n = 9. The question Partial permutations has several helpful answers for C++. I ported one implementation to C and adapted it to your need:
#include <stdio.h>
#include <string.h>
void comb(char *rest, int n)
{
static int sofar;
static char sogood[10];
if (n == 0)
puts(sogood);
else
for (int i = 0; i < strlen(rest); i++)
{
sogood[sofar] = rest[i];
char substring[10];
strcpy(memcpy(substring, rest, i)+i, rest+i+1);
++sofar, comb(substring, n-1), --sofar;
}
}
int main()
{
for (int k = 1; k <= 9; ++k)
comb("123456789", k);
}

Print a random number from my own array

I've been trying to understand how to print out some random numbers from my own array, dont confuse this with that i want to generate random numbers into an array, which is not what im trying to accomplish.
However, my code is like this
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(NULL));
int myarray[] = { 2, 5, 10 };
//Its here where i dont know how to use rand() in to make the program generate one random number from my array, either 2, 5 or 10. I've tried, but failed.
return 0;
}
Ive not found any similar question to this either, so would greatly appreciate some help.
int number = myarray[rand() % 3];
This generates a random number : 0 1 2 and then accesses that element from the array.
You can use the following formula to generate a random number within a range:
rnd(min, max) = (rand() % (max - min)) + min;
In your case you, min = 0 and max = 3, which gives you rand() % 3.
The other answers use rand() % 3 for generating a (pseudo-)"random" number between 0 and 2 (including both). This might work for you, but is not really random, since the numbers returned by rand() between RAND_MIN and RAND_MAX are not distributed uniformly in terms of their divisibility through a given number n (because the equivalence classes of the modulo relation have unequal amounts of members if RAND_MAX is not a multiple of n).
A better algorithm for getting (pseudo-)random numbers in a given range is:
int RangeRandom(int min, int max) {
int n = max - min + 1;
int remainder = RAND_MAX % n;
int x;
do
{
x = rand();
} while (x >= RAND_MAX - remainder);
return min + x % n;
}
You can then use the function RangeRandom as follows:
int myArray[] = { 0, 3, 5 };
printf("%d", myArray[RangeRandom(0, 2)]);

Resources