How to Avoid repeating number randomized in C - c

int i,j,vec[15]={0};
srand (time(NULL));
for (i=0;i<15;i++){
vec[i]=rand() % 25+1;
for (j=0;j<15;j++){
if (i!=j){
while(vec[i]==vec[j]){
vec[i]=rand() % 25+1;
}
}
}
printf("%d\n",vec[i]);
}
return 0;
}
the code still gives me repeated numbers
EXAMPLE:
24
3
7
20
18
10
12
17
9
7
4
25
13
15
21
I cant figure out what to do with it

You have your loops mixed up. The logic is: Generate a random number until you have found one that isn't in the list.
The way you do it, you generate a new number inside the checking loop. But that doesn't work. Say you're generating the 4th number and find it is equal to the third. Then you generate a new one which might well be equal to any you have already checked against.
You also check uninitialised elements when j > i. Your inner loop should only run up to i.
So:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main()
{
int vec[15] = { 0 };
int i, j;
srand(time(NULL));
for (i = 0; i < 15; i++) {
int okay = 0;
while (!okay) {
vec[i] = rand() % 25 + 1;
okay = 1;
for (j = 0; j < i; j++) {
if (vec[i] == vec[j]) okay = 0;
}
}
printf("%d\n", vec[i]);
}
return 0;
}
That still looks a bit awkward with that okay variable. In my opinion, checking for duplicates should be a separate function:
int contains(int arr[], int n, int x)
{
while (n--) {
if (arr[n] == x) return 1;
}
return 0;
}
int main()
{
// snip ...
for (i = 0; i < 15; i++) {
do {
vec[i] = rand() % 25 + 1;
} while (contains(vec, i, vec[i]));
printf("%d\n", vec[i]);
}
// snip ...
}
In your case the range of possible numbers isn't mich bigger than the number of array elements. You could also create an ordered array {1, 2, 3, ..., 25}, then shuffle it and use only the first 15 elements.

Reset j in the while loop:
for (j=0;j<i;j++){ //Use j<i
if (i!=j){
while(vec[i]==vec[j]){
vec[i]=rand() % 25+1;
j=-1;//-1 because in the next iteration,j will start from 0
}
}
}

Are you actually trying to shuffle the numbers, rather than fill the array with randoms? (It looks like you want an array with numbers from 1 to 25, but in random order.) rand() can give you duplicate numbers (they're random, after all!)
Try this:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
int
main( int argc, char **argv )
{
int i, vec[25];
for (i = 0; i < 25; ++i) vec[i] = i + 1;
/* Shuffle entries */
srand( time( 0 ) );
for (i = 0; i < 1000; ++i) {
int a = rand( ) % 25;
int b = rand( ) % 25;
if (a != b) {
int tmp = vec[a];
vec[a] = vec[b];
vec[b] = tmp;
}
}
/* Print shuffled array */
for (i = 0; i < 25; ++i) printf( "%d: %d\n", i, vec[i] );
return 0;
}

#include<stdio.h>
#include<stdlib.h>
int inArray(int, int, int*);
int main()
{
int i,j,vec[15]={0};
int temp;
srand (time(NULL));
for (i=0;i<15;i++){
temp =rand() % 25+1;
while(inArray(i+1,temp, vec) == 1){
temp = rand() % 25+1;
}
vec[i] = temp;
printf("VECT[%d] \t= %d\n",i,vec[i]);
}
return 0;
}
int inArray(int count, int input, int* array){
int i = 0;
for(i=0; i<count; i++){
if(input == array[i]){
return 1;
}
}
return 0;
}
Gave an output:
VECT[0] = 24
VECT[1] = 19
VECT[2] = 1
VECT[3] = 25
VECT[4] = 22
VECT[5] = 18
VECT[6] = 7
VECT[7] = 8
VECT[8] = 12
VECT[9] = 21
VECT[10] = 11
VECT[11] = 6
VECT[12] = 23
VECT[13] = 20
VECT[14] = 15
The checking was off, you would change and not break allowing it to be changed to a previous value.

You can use an array
int randNumbers[25]; // fill it starting 0 to 25 then
randomize the number in a range between 0 and 25 after swap the number in the randomized index with the last number in your array
randomize 0 to 23
and so on....
int main(int argc, char **argv) {
static const int size = 25;
int numbers[size];
for( int i = 0; i < size; i++ ){
numbers[i] = i;
}
srand (time(NULL));
for( int i = 0; i < size; i++ ){
int rIndex = rand()%(size - i);
int rNum = numbers[rIndex];
numbers[rIndex] = numbers[size-i];
printf("%d ", rNum);
}
return 0;
}
O(n) complexity...

Related

I am trying to write a simple tsp question but meet some problems

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define max 100
void tsp(int Dis[max][max],int v[],int N,int count,int currPos,int cost,int ans){
/*for(j=1;j<N+1;j++){
if(visited[j]==0){
sum+=Dis[i][j];
visited[j] = 1;
DFS(visited,j,Dis,sum);
}
}*/
if(count == N&&Dis[1][currPos]>0){
if(ans> cost+Dis[1][currPos]) ans = cost+Dis[1][currPos];
//ans = min(ans,cost + Dis[1][currPos]);
return;
}
for (int i = 0;i<N+1;i++){
if(v[i]==0&&Dis[currPos][i]>0){
v[i] = 1;
tsp(Dis,v,N,count + 1,cost + Dis[currPos][i],ans);
v[i] = 0;
}
}
};
int main(int argc, char const *argv[])
{
int N;
int size = 1;
int count = 1;
char x[100] = {0};
FILE *fp=fopen(argv[1],"r");
if(fp==NULL){
printf("Cannot open the file,strike any key to exit!\n");
getchar();
exit(0);
}
for (int i = 0;!feof(fp);i++){
fscanf(fp,"%hhd",&x[i]);
}
N=x[0];
int Dis[N][N], City[N];
for(int i=1;i<N;i++){
size=size*i;
}
char y[size];
for (int i=1;i<size+1;i++){
y[i] = x[i];
//printf("%d\n",y[i]);
}
for(int i=2; i < N + 1; i++){
for(int j=1; j < i ; j++){
Dis[j][i] = y[count];
Dis[i][j] = y[count];
count+=1;
printf("(%d,%d),(%d,%d)",j,i,i,j);
printf("%d\n",Dis[j][i]);
}
}
for(int i=0;i<N;i++){
City[i]=i + 1;//create the number of city with 1 ...... N
}
int curr_constraint = 0;
int v[N+1];
for (int i = 1; i < N+1; i++){
v[i] = 0;
}
for(int i = 1;i<N+1;i++){
curr_constraint += Dis[i][i+1];
}
v[1]= 1;
int ans = INT_MAX;
printf("The orginal constraint is %d\n",curr_constraint);
tsp(Dis[N][N],v,N,0,1,0,ans);
return 0;
}
The question asks me to implement a tsp question which always starts with the number 1 city, it will read the data including the numbers of nodes and length between two citys from a txt file in the position of argv[1]. And then find the smallest way for all city without going back the first city.
The file is like following:
4
5
40 9
11 6 8
which means:
the number of citys N = 4
Distance: d[1][2] = 5, d[1][3] = 40, d[2][3] = 9, d[1][4] = 11, d[2][4] = 6, d[3][4] = 8.
I want to create a array including the distance in tsp function, but the lenght I read only in the main function. How to solve this problem?

Printing randomly from 1 to 10 in C

I have written a code for randomly printing a number from 1 to 10 without any repetition, but it isn't working properly sometimes I get the number that is already written.
In short, I'm trying to print numbers from 1-10 randomly with no repetition.
Here is my code :
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
main() {
int no = 0, repeat[100] = { 0 }, i = 0, x = 0, j = 0;
srand(time(NULL));
while (true) {
no = (rand() % 10) + 1;
for (i = 0; i < 100; i++) {
if (no != repeat[i]) {
x = 1;
} else if (no == repeat[i]) {
x = 0;
}
}
if (x == 1) {
repeat[j] = no;
printf("\n%d", repeat[i]);
j = j + 1;
}
getch();
}
}
Don't use rand() to generate the numbers directly, instead fill a sequential array, and then use rand() to shuffle the array, e.g.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/** shuffle integer array of size 'n'
* (using fisher-yates method)
*/
void shuffle (int *a, int n)
{
int i, tmp;
while (n-- > 1) {
i = rand() % (n + 1);
tmp = a[i];
a[i] = a[n];
a[n] = tmp;
}
}
int main (void) {
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
srand (time(NULL));
shuffle (arr, 10);
for (int i = 0; i < 10; i++)
printf (" %d", arr[i]);
putchar ('\n');
}
By shuffling the array and swapping random elements within it, you eliminate all possibility of a duplicate number.
Example Use/Output
$ ./bin/shuffle_arr
3 10 7 8 4 5 6 9 1 2
#include <stdio.h>
#define N1 1
#define N2 10
void main() {
int len = N2 - N1 + 1, i, r, temp;
int num[len];
//Fill array with numbers
for (temp = 0, i = N1; temp < len; i++, temp++)
num[temp] = i;
srand(time(NULL));
for (i = len - 1; i > 0; i--) {
r = rand() % i; //pop random number
//swaping
temp = num[i];
num[i] = num[r];
num[r] = temp;
}
/*Random Numbers are stored in Array*/
//print that array
for (i = 0; i < len; i++)
printf("%d\n", num[i]);
}

for loop unexpectedly jumping down in value

Goldbach's conjecture states that every even integer over 4 is the sum of two primes, I am writing a program in C to find these pairs. To do this it first finds all the primes less than a user given number. I have a for loop to iterate from 4 to the user given number and find the pairs within the loop body. When that loop gets to about around 40, suddenly jumps back down by about 30 and then continues to iterate up (with user input 50 it jumped from 38 to 9, with input 60 it jumped from 42 to 7). I can't figure out why this is happening. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <unistd.h>
struct pair{
int a;
int b;
}pair_t;
int main(){
int N;
int numPrimes = 1;
int *primes = malloc(100*sizeof(int));
int isPrime = 1;
primes[0] = 2;
int timesRealloc = 0;
int availableSlots = 100;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
struct pair pairs[N/2 + 4];
int j = 0;
int i;
for (i = 3; i <= N; i+=2){
j = 0;
isPrime = 1;
while (primes[j] <= sqrt(i)) {
if (i%primes[j] == 0) {
isPrime = 0;
break;
}
j++;
}
if (isPrime == 1){
primes[numPrimes] = i;
numPrimes++;
}
if (availableSlots == numPrimes){
timesRealloc++;
availableSlots += 100;
primes = realloc(primes, availableSlots*sizeof(int));
}
}
printf("The largest prime I found was %d\n", primes[(numPrimes-1)]);
int k;
for (i=4; i<=N; i+=2){
printf("i is %d, N is %d\n", i, N);
if (i > N){ break; }
for (j=0; j<numPrimes; j++){
for (k=0; k<numPrimes; k++){
int sum = primes[j] + primes[k];
if(sum == i){
pairs[i].a = primes[j];
pairs[i].b = primes[k];
}
}
}
}
for (i=4; i<=N; i+=2){
printf("%d is the sum of %d and %d\n", i, pairs[i].a, pairs[i].b);
}
return 0;
}
You attempt to be space efficient by compressing the pairs array to just hold every other (even) number and start from 4 instead of zero. However, you miscalculate its size and then when you go to use it, you treat it like it hasn't been compressed and that there's a slot for every natural number.
The code suffers from having the prime array calculation in main() along with the other code, this is best separated out. And when it looks for pairs, it doesn't quit when it finds one, nor when it starts getting sums greater than the target. My rework below attempts to address all of these issues:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#define INITIAL_SLOTS (100)
struct pair {
int a;
int b;
} pair_t;
int compute_primes(int limit, unsigned **primes, int size) {
int numPrimes = 0;
(*primes)[numPrimes++] = 2;
for (int i = 3; i <= limit; i += 2) {
bool isPrime = true;
for (int j = 0; (*primes)[j] <= i / (*primes)[j]; j++) {
if (i % (*primes)[j] == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
(*primes)[numPrimes++] = i;
}
if (numPrimes == size) {
size *= 2;
*primes = realloc(*primes, size * sizeof(unsigned));
}
}
return numPrimes;
}
int main() {
int N;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
unsigned *primes = calloc(INITIAL_SLOTS, sizeof(unsigned));
int numPrimes = compute_primes(N, &primes, INITIAL_SLOTS);
printf("The largest prime I found was %d\n", primes[numPrimes - 1]);
struct pair pairs[(N - 4) / 2 + 1]; // compressed data structure
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
bool found = false;
for (int j = 0; ! found && j < numPrimes; j++) {
for (int k = 0; ! found && k < numPrimes; k++) {
int sum = primes[j] + primes[k];
if (sum == i) {
pairs[offset].a = primes[j];
pairs[offset].b = primes[k];
found = true;
} else if (sum > i) {
break;
}
}
}
}
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
printf("%d is the sum of %d and %d\n", i, pairs[offset].a, pairs[offset].b);
}
free(primes);
return 0;
}
OUTPUT
> ./a.out
Please enter the largest even number you want to find the Goldbach pair for:
10000
The largest prime I found was 9973
4 is the sum of 2 and 2
6 is the sum of 3 and 3
8 is the sum of 3 and 5
10 is the sum of 3 and 7
12 is the sum of 5 and 7
14 is the sum of 3 and 11
...
9990 is the sum of 17 and 9973
9992 is the sum of 19 and 9973
9994 is the sum of 53 and 9941
9996 is the sum of 23 and 9973
9998 is the sum of 31 and 9967
10000 is the sum of 59 and 9941
>

Random Array with no repeated numbers

So what I am trying to do is create a random array of 5 elements, those elements should be filled with numbers from 1 to 6 and they shall not repeat, I can't tell where my logic is wrong.
void genNumber(int vet[]){
int max, i, j, atual;
srand(time(NULL));
max = 7;
for (i=0;i<5;i++){
vet[i] = rand() % max;
while(vet[i] == 0){
vet[i] = rand() % max;
}
for(j=0;j<i;j++){
atual = vet[j];
while((vet[i] == atual)||(vet[i] == 0)){
vet[i] = rand() % max;
atual = vet[j];
}
}
}
}
Update: Fixed
void genNumber(int vet[]){
int max, i, j;
srand(time(NULL));
max = 7;
for (i=0;i<5;i++){
vet[i] = rand() % (max-1) + 1;
for(j=0;j<i;j++){
while(vet[j] == vet[i]){
vet[i] = rand() % (max-1) + 1;
j = 0;
}
}
}
}
The logical flaw is in the way you produce a new random number when a duplicate is found.
Imagine you already have vel = {1,2,0,0,0,...} and are trying to find a number for vel[2]. If you randomly draw a 2, you'll find it's already there and draw again. But if you draw a 1 this time you won't notice, because you only compare to the last value seen, 2 in the example. So you'd get vel = {1,2,1,...}.
"Solution": Every time you draw a new random number you have to compare it against all numbers already in the list.
Another way of solving this is the one I tried to outline in the comments: You have to keep the information about which numbers are still valid for a draw somewhere. You can either use the "output" array for that as you're doing now, or you can use another store from which you "remove" an entry once it was drawn.
when generating a random number,you have to check if it is found in the array,so iterate over the array and check.if the number is found,generate another random number and check,until the new number is not found in the array.after that assign it.and repeat.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int check(int vet[],size_t size,int val);
void genNumber(int vet[],size_t size);
int main(void)
{
srand(time(NULL));
int vet[5];
size_t size = 5;
genNumber(vet,size);
for( size_t n = 0 ; n < size ; n++ )
{
printf("%d ",vet[n]);
}
}
void genNumber(int vet[],size_t size)
{
int num = rand() % 6 + 1;
vet[0] = num;
for( size_t n = 1 ; n < size ; n++ )
{
num = rand() % 6 + 1;
while( 1 )
{
if( check(vet,n,num) )
{
num = rand() % 6 + 1;
}
else
{
vet[n] = num;
break;
}
}
}
}
int check(int vet[],size_t size,int val)
{
for( size_t n = 0 ; n < size ; n++ )
{
if( vet[n] == val )
{
return 1;//FOUND
}
}
return 0;//NOT FOUND
}
As an alternative you can fill an array with a value from 1 to 6. Afterwards you can shuffle the array at random indicies.
#define MAX 6
void swap (int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void genNumber(int *vet) {
int i;
for(i=0;i<MAX;i++) {
vet[i] = i+1;
}
for(i = MAX-1;i > 0;i--) {
// Pick a random index from 0 to i
int j = rand() % (i+1);
// Swap vet[i] with the element at random index
swap(&vet[i], &vet[j]);
}
}
Also you shouldn't call srand(time(NULL)); inside of the genNumber function if you intend to call it more than once, becaues otherwise it will give you the same numbers if you call it more than once a second.
Afterwards just use the first five elements from the array. So you would call it like this from main
int vet[MAX] = {0};
srand(time(NULL));
genNumber(vet);
for(i=0;i<5;i++) {
printf("after num %d\n", vet[i]);
}

I would like to have numbers be replaced with their own summ in C language

I have to
1. create an array from N elements, which contains natural numbers
2. And then I have to replace each number in array with its own summ.
For example
23 -> 2 + 3 = 5;
2 -> 2;
845 -> 8 + 4 + 5 = 17
All this have to be created in C . Could anyone help me?
here is the program:
#include <stdio.h>
int getSum(int value){
int sum = 0;
int index = 0;
while (value > 0){
sum += value % 10;
value = value / 10;
}
return sum;
}
int main(int argc, char *argv[])
{
int arr[] = { 23, 2, 845 };
int i = 0;
int sizeArr = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sizeArr; i++){
arr[i] = getSum(arr[i]);
printf("%d\n", arr[i]);
}
return(0);
}
#include <stdio.h>
int main()
{
int a[5]={11,23,485,561,452}, i=0;
int tmp =i;
int total = 0;
for(i=0;i<5;i++)
{
tmp = a[i];
while(tmp>0)
{
total = (tmp %10) + total;
tmp = tmp /10;
}
a[i] = total;
total =0;
}
// print array
for(i=0;i<5;i++)
{
printf("%d = %d\n",i,a[i]);
}
return 0;
}
// Output
0 = 2
1 = 5
2 = 17
3 = 12
4 = 11

Resources