Randomize 4 different numbers - c

I'm trying to randomize 4 different numbers in C and trying the next code:
{
int num1 = 0, num2 = 0, num3 = 0, num4 = 0;
int i = 0;
while (num1 == num2 && num1 == num3 && num1 == num4 && num2 == num3 && num2 == num4 && num3 == num4 && num3 == num2)
{
num1 = rand() % 7;
num2 = rand() % 7;
num3 = rand() % 7;
num4 = rand() % 7;
}
printf("%d %d %d %d\n", num1, num2, num3, num4);
}
The code suppose to check if the numbers are not equal and if they are equal, it needs to generate new numbers until they are all distinct.
But for some reason, it's not working well and even right numbers it puts them as wrong and it becomes and endless loop.
What am I missing?

This code will pick 4 different numbers in the range 0 .. 6, it works by creating an array of available numbers, as each is picked it is removed from the list.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define RANGE 7 // how many different numbers
#define PICK 4 // how many to pick
int main(void) {
int pool[RANGE];
int size, n, i;
for (size=0; size<RANGE; size++) {
pool[size] = size; // create number pool 0..6
}
srand((unsigned)time(NULL));
// pick different numbers
for(i=0; i<PICK; i++) {
n = rand() % size; // random array index
printf("%d ", pool[n]); // select number from pool
pool[n] = pool[--size]; // remove from pool
}
printf("\n");
return 0;
}

Try like this
void
get_random_values(int *values)
{
int source[] = {0, 1, 2, 3, 4, 5, 6};
for (int i = 0 ; i < 7 ; ++i)
{
int saved;
int j = rand() % 7;
int k = rand() % 7;
saved = source[j];
source[j] = source[k];
source[k] = saved;
}
values[0] = source[0];
values[1] = source[1];
values[2] = source[2];
values[3] = source[3];
}
int
main(void)
{
int values[4];
srand(time(NULL));
get_random_values(values);
for (int i = 0 ; i < 4 ; ++i)
fprintf(stderr, "%d ", values[i]);
fprintf(stderr, "\n");
return 0;
}
Don't forget to set the random seed srand() at the program startup or you will get the same sequence always.

To get a random, unbiased sequence:
#include <stdio.h>
#include <stdlib.h>
#define N 7
int main(int argc, char **argv)
{
// seed random number generator with first argument for easier testing
if (argc > 1) {
srand(atoi(argv[1]));
}
int array[N] = {0,1,2,3,4,5,6};
// Fisher–Yates shuffle:
// https://en.wikipedia.org/w/index.php?oldid=697311634#The_modern_algorithm
for (unsigned i = 0; i < N - 1; ++i) {
unsigned modulo = N - i;
// unbiased rand() % modulo:
// https://stackoverflow.com/a/10989061/416224
unsigned j;
do {
j = rand();
} while (j >= RAND_MAX - (RAND_MAX % modulo));
j %= modulo;
if (j > 0) {
int tmp = array[i];
array[i] = array[i + j];
array[i + j] = tmp;
}
}
for (unsigned i = 0; i < N; ++i) {
printf("%u. %d\n", i + 1, array[i]);
}
return 0;
}
Please follow the referenced links in the code.

I would suggest universal solution:
array of any size
lower and upper bounds sent as parameters.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void random(int* values, int amount, int lower_bound, int upper_bound)
{
int i=0, j=0, temp;
if(amount > upper_bound - lower_bound + 1)
return; // if there are more numbers than given bound
for(i=0; i<amount; )
{
temp = rand() % ( upper_bound - lower_bound + 1 ) + lower_bound;
for(j=i-1; j>=0; --j)
if(temp==values[j])
break;
if(temp==values[j])
continue;
values[i]=temp;
++i;
}
}
int main()
{
srand(time(NULL));
int arr[4]={0,0,0,0};
random(arr, 4, 5, 10);
for(int i=0; i<4; ++i)
printf("%d\n", arr[i]);
}
With this you can have (for example) 10 numbers of original values from -6 to 7.

Related

Remove all digits from array

Write a function remove_digits that receives two arrays of type int. The first array contains a number of integers, and the second array is an array of digits. It is necessary to remove all digits from second array which are present in first array.
The function returns 1 if the ejection was successful.The function returns 1 if the eject was successful, and 0 if the array of digits is incorrect for some reason, if the array contains a value less than 0 or greater than 9, or if one of the members is repeated.
EXAMPLE 1:
int first[2]={12345, -12345},second[2]={3,5};
OUTPUT: 124 -124
EXAMPLE 2:
int first[5]={25, 235, 1235, 252, 22552255},second[3]={2,3,5};
OUTPUT: 0 0 1 0 0
My algorithm:
check if digit in second array is less than 0 or grater than 9 or digit is repeated, and in that case return 0 (finish program)
for negative numbers make them positive and in the end of first (for) loop make them negative
in the second (while) loop break number into digits, and for every number check if it's present in second array
if it is present, remove last digit
continue to the rest of elements
Code:
#include <stdio.h>
#include <stdlib.h>
int sum_of_digits(int n) {
int i, sum = 0;
while (n > 0) {
sum++;
n /= 10;
}
return sum;
}
int divide(int n) {
int num_of_digits = sum_of_digits(n);
switch (num_of_digits) {
case 1:
break;
case 2:
break;
case 3:
n /= 10;
break;
case 4:
n /= 100;
break;
case 5:
n /= 1000;
break;
case 6:
n /= 1000;
break;
case 7:
n /= 10000;
break;
case 8:
n /= 100000;
break;
case 9:
n /= 1000000;
default:
break;
}
return n;
}
int remove_digits(int *first, int n, int *second, int vel) {
// first - removing digits from second
// second - searching for digits
int i, j, num, digit, neg = 0;
for (i = 0; i < vel; i++) {
// invalid digit
if (second[i] < 0 || second[i] > 9)
return 0;
for (j = i + 1; j < vel; j++)
// repeated digit
if (second[j] == second[i])
return 0;
}
for (i = 0; i < n; i++) {
// negative case
if (first[i] < 0) {
first[i] = abs(first[i]);
neg = 1;
}
num = first[i];
while (num > 0) {
digit = num % 10;
for (j = 0; j < vel; j++)
if (second[j] == digit)
// remove last digit
first[i] = divide(first[i]) - digit;
num /= 10;
}
if (first[i] <= 0)
first[i] = 0;
if (neg == 1)
first[i] *= -1;
}
return 1;
}
int main() {
int first[2] = {12345, 12345}, second[2] = {3, 5}, i;
remove_digits(first, 2, second, 2);
for (i = 0; i < 2; i++)
printf("%d ", first[i]);
return 0;
}
MY OUTPUT: 4 4
Could you help me to modify my algorithm to work correctly?
simplified approach for your problem would be as follows,
#include <stdio.h>
#include <stdlib.h>
int removeDigit(int src, int digit){
int neg = (src < 0)?-1:1;
int num = abs(src);
src = 0;
//remove digit
while(num){
int num_digit = num%10;
if(num_digit != digit){
src = src * 10 + num_digit;
}
num /= 10;
}
//reverse number
while(src){
num = num * 10 + src%10;
src /=10;
}
return num*neg;
}
int remove_digits(int *first, int n, int *second, int m) {
// first - removing digits from second
// second - searching for digits
int i, j;
for (i = 0; i < m; i++) {
// invalid digit
if (second[i] < 0 || second[i] > 9)
return 0;
for (j = i + 1; j < m; j++)
// repeated digit
if (second[j] == second[i])
return 0;
}
for (i = 0; i < n; ++i) {
for(j =0; j<m; ++j){
first[i]= removeDigit(first[i],second[j]);
}
}
return 1;
}
int main() {
{
printf("Test 1\n");
int first[] = {12345, 12345}, second[] = {3, 5}, i;
remove_digits(first, sizeof(first)/sizeof(first[0]), second, sizeof(second)/sizeof(second[0]));
for (i = 0; i < sizeof(first)/sizeof(first[0]); i++)
printf("%d ", first[i]);
}
{
printf("\n\nTest 2\n");
int first[] = {25, 235, 1235, 252, 22552255}, second[] = {2,3,5}, i;
remove_digits(first, sizeof(first)/sizeof(first[0]), second, sizeof(second)/sizeof(second[0]));
for (i = 0; i < sizeof(first)/sizeof(first[0]); i++)
printf("%d ", first[i]);
}
return 0;
}

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
>

In C, I would like to print 4 decimal numbers in a row and then print the next 4

#include "stdio.h"
int main() {
int max = 1000;
for (int i = 0; i < max; ++i) {
printf("%d", i);
}
return 0;
}
If max is 1000 then this will print in the format shown below
0123 up to 1000
But I would like to print 4 values per line as shown below:
0123
4567
...
I would like to see the numbers not the just the digits. for a single digit numbers, it should be like this: 0123 for two digit numbers, it should be like this: 11121314 for a three digit numbers, it should be like this: 111112113114 up to 996997998999 up to 1000.
For your loop to print upto and including 1000 for max.size = 1000, you must use the <= operator.
Here is a modified version that will format the output with a maximum of 4 characters per line:
#include <stdio.h>
#include <limits.h>
int main(void) {
struct { int size; } max = { 1000 };
if (max.size >= 0) {
for (int col = 0, i = 0;; i++) {
char buf[2 + sizeof(int) * CHAR_BIT / 3];
int n = snprintf(buf, sizeof buf, "%d", i);
for (int j = 0; j < n; j++) {
putchar(buf[j]);
if (++col == 4) {
putchar('\n');
col = 0;
}
}
if (i == max.size) {
if (col > 0) {
putchar('\n');
}
break;
}
}
}
return 0;
}
It will print:
0123
4567
8910
1112
1718
...
6997
9989
9910
00
EDIT
From your updated question, it is actually much simpler: print a linefeed character after every 4th number, using the modulo operator %.
#include <stdio.h>
int main(void) {
int max = 1000;
for (int i = 0; i < max; ++i) {
printf("%d", i);
if (i % 4 == 3)
putchar('\n');
}
return 0;
}
Just check whether i+1 is divisible by 4 or not. Whenever it is divisible by 4, print a newline.
for (int i = 0; i < max.size; ++i) {
printf("%d", i);
if((i+1)%4 == 0)
printf("\n");
}
You can also do this without using a buffer:
#include <stdio.h>
void print_digit(int number);
int main(void) {
putchar('0');
int i;
for(i = 1; i <= 1000; i++) {
print_digit(i);
}
}
void print_digit(int number) {
static int digit_count = 1; // a zero is already printed
int i;
for(i = 1; i <= number; i *= 10);
for(i /= 10; i; i /= 10) {
putchar('0' + number % (i * 10) / i);
digit_count++;
if(digit_count == 4) {
digit_count = 0;
putchar('\n');
}
}
}
However, I have to admit that this code has nothing to do with elegance, because I don't know how to make print_digit consistent with zero.

Weird output after array is printed in C

I am writing a program that takes three numbers, first+second num is the length of each row, second num is the number of rows and third is a 1 or a 0. So given that the first two numbers are 7 and 4 and if 3rd num is a 1 I want to fill and print the array in the following way:
10000000000
01000000000
00100000000
00010000000
but when I print it I get weird output following my array:
10000000000
01000000000
00100000000
00010000000
��1�
1�
��1
Also if I change putchar(arr[i][j]) to printf("%d", arr[i][j]) in the last for loop, the output I get is:
4948484848484848484848
4849484848484848484848
4848494848484848484848
4848484948484848484848
-63-1234849-12048700
0400049-964868-55
-41-6500004900016
Can someone please explain why this is happening and what I need to do to get the clean output?
Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char *byte_to_binary(int x)
{
static char b[9];
b[0] = '\0';
int z;
for (z = 128; z > 0; z >>= 1)
{
strcat(b, ((x & z) == z) ? "1" : "0");
}
return b;
}
int main(int argc, char *argv[]) {
char* tmp;
int num1, num2, num3;
int x = 128;
int i, j;
num1 = strtol(argv[1], &tmp, 10);
num2 = strtol(argv[2], &tmp, 10);
num3 = strtol(argv[3], &tmp, 10);
int rlen = num1 + num2;
char arr[num2][rlen];
memset(arr, '0', num2 * rlen);
// find out if the first number is a 1 or a 0.
if ((num3 & x) == x) {
arr[0][0] = '1';
}
else {
arr[0][0] = '0';
}
for (i = 1; i < num1; i++) {
for (j = 0; j < rlen; j++) {
arr[i][i] = arr[0][0];
}
}
for (i = 0; i < num1; i++) {
for (j = 0; j < rlen; j++) {
putchar(arr[i][j]);
}
putchar('\n');
}
return 0;
}

Resources