How to randomize a to p without repitition - c

I want to randomize a to p without repetition.
int main(){
int array2[4][4];
bool arr[100]={0};
int i;
int j;
srand(time(NULL));
for(i=0; i<=3; i++){
for(j=0; j<=3; j++){
int randomNumber1;
randomNumber1 = (rand() % (82-65+1))+65;
if (!arr[randomNumber1])
{
printf("%c ",randomNumber1);
array2[i][j]=randomNumber1;
}
else
{
i--;
j--;
arr[randomNumber1]=1;
}
}
printf("\n");
}
return;
the output still has repeat alphabet. I want to have the output in 4x4 with with all a to p without it repeating.

There are some errors in your code. IMHO the most serious is that arr[randomNumber1]=1; is is the wrong branch of the test. That means that your current code does not invalidate once a number was used but only if it has already been invalidated => if you control the arr array at the end of the program all value are still 0.
That is not all. When you get a duplicate, you should only reset the inner loop, and you are currently off by 2 in your maximum ascii code: you go up to R when you want to stop at P.
Your code should be:
for (i = 0; i <= 3; i++) {
for (j = 0; j <= 3; j++) {
int randomNumber1;
randomNumber1 = (rand() % (81 - 65)) + 65;
if (!arr[randomNumber1])
{
printf("%c ", randomNumber1);
array2[i][j] = randomNumber1;
arr[randomNumber1] = 1;
}
else
{
//i--;
j--;
}
}
printf("\n");
}
But this kind of code is terribly inefficient. In my tests it took 30 to 60 steps to fill 16 values, because random can return duplicates. This is the reason why you were advised in comments to use instead the modern algorithm for Fisher-Yates shuffle:
int main() {
int array2[16];
unsigned i, j, k=0;
// initialize array with alphabets from A to P
for (i = 0; i < sizeof(array2); i++) {
array2[i] = 'A' + i;
}
// Use Fisher-Yates shuffle on the array
srand(time(NULL));
for (i = 15; i > 0; i--) {
j = rand() % (i + 1);
if (j != i) {
int c = array2[i];
array2[i] = array2[j];
array2[j] = c;
}
}
// Display a 4x4 pattern
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
printf("%c ", array2[k++]);
}
printf("\n");
}
return 0;
}
Which shuffles the array in only 16 steps.

Here is the outline
// Need some #includes here - exercise for the reader
char items[] = "abcdefghijklmnopqrstuvwxyz";
int len = sizeof(items);
srand(time(NULL));
while (len > 0) {
int r = rand() % len;
printf("%c", items[r]);
len--;
items[r] = items[len];
}
This should do the trick to print the whole alphabet in random order without repeats. Modify to do what you need it to do

Related

c : How to generate random numbers without duplication in a two-dimensional array of languages

I want to put random numbers from 1 to 16 in a two-dimensional array without duplication.
I made a code that eliminates duplicates and puts new random numbers back into the array, but it keeps printing duplicate numbers.
Which part is wrong and why?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int A[4][4];
int i, j, k, l;
int num;
srand(time(NULL));
int count;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
//Re:
num = rand() % 16 + 1;
A[i][j] = num;
for(k = 0; k <= i; k++)
{
count = 0;
for(l = 0; l <= j; l++)
{
if(A[k][l] == num)
{
if(k != i && l != j)
{
j--;
count = 1;
break;
// goto Re;
}
}
}
if(count == 1)
break;
}
}
}
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
printf("%3d", A[i][j]);
}
printf("\n");
}
}
I want to put random numbers from 1 to 16 in a two-dimensional array without duplication. I made a code that eliminates duplicates and puts new random numbers back into the array, but it keeps printing duplicate numbers.
Put the numbers 1,…,16 into an array tmp.
Perform a Fisher-Yates shuffle on tmp.
Iterate through tmp to copy its elements to A using the mapping A[i/4][i%4] = tmp[i].
If you’re not convinced, try a few values of i by hand to assure yourself this works.

Print letters in lower triangle in C

I spent hours in printing a lower triangle in C. However, I just cannot figure out how to solve this same question with array.
Below is one of the solution I found on net:
int main(void)
{
char ch='A';
int i,j;
for(i=1;i<7;i++)
{
for(j=0;j<i;j++)
printf("%c",ch++);
printf("\n");
}
return 0;
}
Below is how I try to do the same thing:
#define SIZE 8
int main(void){
char Alphabet[SIZE];
int i, j;
for (i = 0, j = 'A'; i < SIZE, j < 'A' + SIZE; i++, j++){
Alphabet[i] = j;
}
for (i = 0; i <= 7; i++){
for (j = 0; j <= i; j++){
printf("%c", Alphabet[j+i]);
}
printf("\n");
}
return 0;
}
The result of the code above is :
A
BC
CDE
DEFG
EFGHI
FGHIJK
GHIJKLM
HIJKLMNO
What should I revise if I want to print as follow:
A
BC
DEF
GHIJ
KLMNO
PQRSTU
Thank you.
Keep a track of elements printed from the Alphabet array so far and in the inner loop start printing from next element onward. You can do:
#include <stdio.h>
#define SIZE 26
int main(void) {
char Alphabet[SIZE];
for (int i = 0; i < SIZE; i++) {
Alphabet[i] = 'A' + i;
}
// Or simply have the Alphabet array initialized like this
// char Alphabet[SIZE] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int k = 0;
for (int i = 0; i < 6; i++) {
for (int j = 0; j <= i && k < SIZE; j++) {
printf("%c", Alphabet[k++]);
}
printf("\n");
}
return 0;
}
Output:
# ./a.out
A
BC
DEF
GHIJ
KLMNO
PQRSTU
EDIT:
In the comments, a fellow SO contributor said that the above approach is same as the one OP already found as a solution and OP might be looking for approach of calculating the Alphabet array index using i and j only and without use of variable keeping track of array index. Below is the program which does not use any extra variable to keep the track of Alphabet array index to print characters in inner loop and calculating the index using i and j:
#include <stdio.h>
#define SIZE 26
#define ARRLOC(x) ((x * ((x + 1) / 2)) + ((x % 2 == 0) ? (x / 2) : 0))
int main(void) {
char Alphabet[SIZE];
for (int i = 0; i < SIZE; i++){
Alphabet[i] = 'A' + i;
}
// Or simply have the Alphabet array declared like this
// char Alphabet[SIZE] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int i = 0; i < 6; i++){
for (int j = 0; j <= i && (ARRLOC(i) + j) < SIZE; j++){
printf("%c", Alphabet[ARRLOC(i) + j]);
}
printf("\n");
}
return 0;
}
Output:
# ./a.out
A
BC
DEF
GHIJ
KLMNO
PQRSTU
You can just have a third 'index' variable that keeps track of which letter to output across both loops (I've called this k in the code below). Also, you need to make your Alphabet array bigger (26 seems like a reasonable number); then, if that k variable gets past 'Z', we can simply loop back to 'A' using the modulo operator (%):
#include <stdio.h>
#define SIZE 26
int main(void)
{
char Alphabet[SIZE];
int i, j, k;
for (i = 0; i < SIZE; i++) Alphabet[i] = 'A' + i;
int k = 0;
for (i = 0; i <= 7; i++) {
for (j = 0; j <= i; j++) {
printf("%c", Alphabet[k % 26]); // If past the end, loop back with the "%" operator
++k;
}
printf("\n");
}
return 0;
}
Or we can make the code a little more 'succinct' (though perhaps less clear) by initializing the k variable at the start of the outer loop and incrementing at the end of the inner loop:
for (k = i = 0; i <= 7; i++) { // Initialize "k" here ...
for (j = 0; j <= i; j++, k++) { // .. but increment it here!
printf("%c", Alphabet[k % 26]); // If past the end, loop back with the "%" operator
}
printf("\n");
}
If you want an 8 by 8 pyramid, you won't have enough characters to do it using the alphabet (requires 36), so I made the alphabet repeat itself (u could also make it go to numeric instead?)
#define SIZE 8
int area(int size);
int main(void){
char Alphabet[area(SIZE)];
int i, j;
for (i = 0, j = 'A'; i < area(SIZE); i++, j++){
if (j > 'Z') j = 'A';
Alphabet[i] = j;
}
int idx=0;
for (i = 0; i < SIZE; i++){
for (j = 0; j <= i; j++){
printf("%c", Alphabet[idx++]);
}
printf("\n");
}
return 0;
}
int area(int size) {
if (size==1) return 1;
return size + area(size - 1);
}

Removing duplicates in a C array

I am writing a program which determines the intersection of 2 integer arrays (size of 10 elements). I think I got every other parts covered except for sorting out duplicates. Does anyone know a way of checking duplicates without making a function or using an external C library?
#include <stdio.h>
#define SIZE 10
int main(void){
//Initialization
int array1[SIZE];
for (int i = 0; i < SIZE; i++)
{
printf("Input integer %d of set A: ", i + 1);
scanf("%d", &array1[i]);
}
int array2[SIZE];
for (int i = 0; i < SIZE; i++)
{
printf("Input integer %d of set B: ", i + 1);
scanf("%d", &array2[i]);
}
int intersection[SIZE];
for (int i = 0; i < SIZE; i++)
{
intersection[i] = '\0';
}
//Intersection check
for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
if (array1[i] == array2[j])
{
intersection[i] = array1[i];
break;
}
}
}
//duplicate check
int count = SIZE;
for (int i = 0; i < count; i++)
{
for (int j = i + 1; j < count; j++)
{
if (intersection[i] == intersection[j])
{
for (int k = j; j < count; i++)
{
intersection[k] = intersection[k + 1];
}
count--;
}
}
}
//printing set
for (int i = 0; i < SIZE ; i++)
{
//printf("%d\n", intersection[i]);
if (intersection[i] != '\0')
{
printf("%d\n", intersection[i]);
}
}
return 0;
}
In the code above i was trying one method although it didn't work and instead made the program stuck after inputting all the elements. I am open to other methods as long it doesn't require an external library to run. Thanks
As i see it now , in the third loop where you checking your duplicates i thing that you have to increese k not i :
for (int k = j; j < count; k++), also you must decrise the size of j in your code under the count--;.So your code for checking duplicates seems right but , you want the intersection of this two arrays you made , so you dont have to check for duplicates because in the array intersection[SIZE] you will put only one number from the two arrays, so you will not have duplicates .You should check for duplicates if you wanted to make the union of this two arrays .I make some changings to your code acording what you want to create and this code here find the intersection from two arrays.Try this and delete the duplicate check because that makes your code to run to infinity . One last thing your intersection check must be replace whith this :
//Intersection check
int i = 0, j = 0,k=0; // k is for the intersection array !
while (i < SIZE && j < SIZE) {
if (array1[i] < array2[j])
i++;
else if (array2[j] < array1[i])
j++;
else if(array1[i]==array2[j]) // if array1[i] == array2[j]
{
intersection[k]=array2[j];
//printf("intersection[%d]=%d\n",i,intersection[i]);
intersectCount++;
k++;
i++;
j++;
}
}
printf("intersectCount=%d\n",intersectCount);

Random number array without duplicates in C

I am trying to create random integer array generator with no duplicate by using this:
int pt_rand(int nbits) {
int mask;
if (0 < nbits && nbits < sizeof(int)*8) {
mask = ~(~((unsigned int) 0) << nbits);
}
else {
mask = ~((unsigned int) 0);
}
return rand() & mask;
}
int *gen_rand_int_array_nodups(int length, int nbits) {
int * a = malloc(sizeof(int)*length);
for (int i = 0; i < length; i++) {
a[i] = pt_rand(nbits);
for (int j = 0; j < i; j++) {
do {
a[i] = pt_rand(nbits);
} while (a[i] == a[j]);
}
}
shuffle_int_array(a, length);
return a;
}
This code is trying to generate unique random integers within given nbits by checking elements one by one. However, I'm still getting duplicates in the result and I've not figured it out why. I know this is a bad practice of using this method to generate unique random numbers but the requirement of my assignment requires me to somehow make use of nbits param. I've looked up for the easiest way to the same thing by filling an array with increment number and swap them around but that's just an alternative solution and I still have to confirm if I'm allowed to use that instead.
for (int j = 0; j < i; j++) {
do {
a[i] = pt_rand(nbits);
} while (a[i] == a[j]);
}
Say i=3, j=1, a={5,2,3,2}. Now you detect you already have the 2 ... so say pt_rand() gives you 5 now. How do you detect you already have 5?
Corrected version:
int *gen_rand_int_array_nodups(int length, int nbits) {
int * a = malloc(sizeof(int)*length);
for (int i = 0; i < length; i++) {
int duplicate;
do
{
duplicate = 0;
a[i] = pt_rand(nbits);
for (int j = 0; j < i; j++) {
if (a[j] == a[i])
{
duplicate = 1;
break;
}
}
} while (duplicate);
}
shuffle_int_array(a, length);
return a;
}

Preventing duplicates from being stored when filling dynamic array with values from two different arrays

I need to know a method to keep duplicate numbers from being stored in a new array when taking numbers from two different arrays. The function is supposed to store each 'unique' value once and not store duplicate values again.
Here is my function code so far:
int * arrayIntersect(int *sizeOfResult, const int *a, const int *b, int sizeOfA, int sizeOfB){
int i;
int j;
int k = 0;
int c[(sizeOfA + sizeOfB)];
for(j = 0; j < sizeOfB; j++){
for(i = 0; i < sizeOfA; i++){
if(a[i] == b[j]){
c[k] = a[i];
(*sizeOfResult)++;
k++;
}
}
}
int *d = (int *)malloc(sizeof(int) * *sizeOfResult);
for(i = 0; i < *sizeOfResult; i++){
d[i] = c[i];
}
return d;
}
It prints the values I need, but I want to eliminate the same number from showing up multiple times when printing the contents of the new dynamic array.
Any idea on how to improve my code to allow prevent duplication?
The proper way to do it is having the arrays ordered and then doing a binary search for each insertion like #Murilo Vasoncelos pointed out.
Below is a quick and dirty solution that loops through a and b and for each iteration checks if the number has been inserted before. If it isn't, it inserts it.
int duplicate = 0;
*sizeOfResult = 0;
for(j = 0; j < sizeOfA; j++){
for(i = 0; i < (*sizeOfResult); i++){
if(c[i] == a[j]){
duplicate = 1;
break;
}
}
if (!duplicate)
{
c[(*sizeOfResult)] = a[i];
(*sizeOfResult)++;
}
duplicate = 0;
}
for(j = 0; j < sizeOfB; j++){
for(i = 0; i < (*sizeOfResult); i++){
if(c[i] == b[j]){
duplicate = 1;
break;
}
}
if (!duplicate)
{
c[(*sizeOfResult)] = b[i];
(*sizeOfResult)++;
}
duplicate = 0;
}
If your arrays a and b are ordered, you can simply use this linear algorithm for array intersection:
int* inter(int* szr, int* a, int* b, int sza, int szb)
{
int c[MAX(sza, szb)];
int i, j, k = 0;
for (i = 0, j = 0; i < sza && j < szb;) {
if (a[i] == b[j]) {
if (k == 0 || c[k - 1] < a[i]) {
c[k++] = a[i];
}
i++;
j++;
}
else if (a[i] < b[j]) {
i++;
}
else {
j++;
}
}
*szr = k;
int* ans = (int*)malloc(sizeof(int) * k);
for (i = 0; i < k; ++i) {
ans[i] = c[i];
}
return ans;
}

Resources