2D array update in function in c - c

I was trying to use the function Initialize to update the value of array distance, here is my code:
#include <stdio.h>
#define NOT_CONNECTED -1
int nodesCount;
void Initialize(int (*distance)[nodesCount], int nodesCount) {
int i, j;
for(i = 0; i <= nodesCount; ++i) {
for(j = 0; j <= nodesCount; ++j) {
distance[i][j] = NOT_CONNECTED;
}
distance[i][i] = 0;
}
for(int i = 0; i <= nodesCount; i++)
printf("distance[%d] = %d\n", i, distance[i][i]);
}
int main() {
scanf("%d", &nodesCount);
int distance[nodesCount + 1][nodesCount + 1];
Initialize(distance, nodesCount);
for(int i = 0; i <= nodesCount; i++)
printf("distance[%d] = %d\n", i, distance[i][i]);
}
But the test result printed out shows the updated array value is wired, could anybody explain what might have happened to this code?
distance[0] = 0
distance[1] = 0
distance[2] = 0
distance[3] = 0
distance[4] = 0
distance[5] = 0
distance[0] = 0
distance[1] = -1
distance[2] = -1
distance[3] = -1
distance[4] = -1
distance[5] = 32677

In
void Initialize(int (*distance)[nodesCount], int nodesCount)
compiler has no idea what is nodesCount in int (*distance)[nodesCount] because it has not seen it yet declared. This should be
void Initialize(int nodesCount, int (*distance)[nodesCount])
Then, you should pass nodesCount+1 to Initialize function
Initialize(nodesCount+1, distance);
Note that in function Initializeyou have to change every occurrence of <=nodesCount in for loops to <nodesCount.
for (i=0; i<nodesCount; ++i){ /* ... */ }

Related

When I print all the variables of a list it gives me an unexpected value that is inconsistent in c. Can you tell me what went wrong?

Here is the code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
struct rule {
int id;
int allow[3];
};
char key_id[10] = { '\\', '/', '`', '#', '_', '*', '#', '%', '>', '<' };
struct rule def_rule(int id, int *arr, int arr_size) {
struct rule temp;
temp.id = id;
for (int i; i < arr_size; i++) {
temp.allow[i] = arr[i];
}
return temp;
}
void collapse(int *map, int map_w, int map_h) {
srand(time(0));
//finding adj indexes
int nth;
int wst;
int sth;
int est;
int map_a = map_h * map_w;
int dir[4] = { nth, wst, sth, est };
for (int i = 0; i < map_w * map_h; i++) {
if ((i - 4) >= 0) {
nth = map[i - 4];
}
if ((i + 1) < map_a) {
wst = map[i + 1];
}
if (i + 4 <= 15) {
sth = map[i + 4];
}
if (i - 1 >= 0) {
est = map[i - 1];
}
}
}
void main(void) {
//define some rules
struct rule rules[0];
int arr[3] = { 0, 1, 2 };
rules[0] = def_rule(0, arr, 3);
//collapse
int map_w = 4;
int map_h = 4;
int map[map_w * map_h];
for(int i = 0; i < 15; i++) {
map[i] = 0;
}
collapse(map, map_w, map_h);
for (int i = 0; i < map_w; i++) {
for (int j = 0; j < map_h; j++) {
printf(" %d ", map[(i * 4) + j]);
}
printf("\n");
}
}
When I compile it it doesn't give me any errors or warnings and I think when I access map[i] I am not out of range.
However it gives me this output in my terminal:
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 21896
When I run it again 21896 changes to a different number.
I am trying to turn zeros in an array into other numbers depending on some rules.
I made the code for checking adjacency such that it doesn't change the variable map.
The only time variable map is changed is when I iterate over it to set everything to 0.
I have tested all the code and it seemed to work however when I added structs it started to do this.
Edit:
The problem was that I was accessing all but the last index of map so I was trying to print an undefined variable I think.
The initialization loop for map is incorrect: you never initialize the last element. You should use:
int map[map_w * map_h];
for (int i = 0; i < map_w * map_h; i++) {
map[i] = 0;
}

My program doesn't deal cards correctly after the first round

I have a program that has to go until one of the players get 30 points, if I play it only 1 round it works perfectly but when I try to deal the cards again (different cards per round) it deals the last card it gave the round before and the other 2 are the same (sometimes it doesn't even deal them).
while (Player1Point != 30 && Player2Point != 30){
for (int i = CardCount; i < Count; i++){
DealCard(Deck, i, &Hand1, &Hand2, Count, j);
j++;
}
Count = Count + 4;
CardCount = CardCount + 4;
Here's the function DealCard:
void DealCard(int Deck[CARDS][PLAYERS], int i, int Hand1[NUMBER][SUITS], int Hand2[NUMBER][SUITS], int Count, int j){
if (i < Count && j < 3){
Hand1[j][0] = Deck[i][0];
Hand1[j][1] = Deck[i][1];
Hand2[j][0] = Deck[i+3][0];
Hand2[j][1] = Deck[i+3][1];
}
}
The arrays I use for the cards:
char* suit[SUITS] = {"Espada", "Oro", "Copa", "Basto"};
char* num[NUMBER] = {"uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "diez", "once", "doce"};
When i try to deal for the second time it gives me the last card and 2 "uno de Espada" or 2 "uno de (null)"
EDIT:
The MRE (still 66 lines)
#include <stdio.h>
#include <time.h>
#include <string.h>
#define SUITS 4
#define NUMBER 10
#define CARDS 40
#define PLAYERS 3
char* suit[SUITS] = {"Espada", "Oro", "Copa", "Basto"};
char* num[NUMBER] = {"uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "diez", "once", "doce"};
int main(){
int Player2Point = 0, Player1Point = 0, CardCount = 0, j = 0, Count = 3;
int Deck[CARDS][PLAYERS];
int Hand1[NUMBER][SUITS];
int Hand2[NUMBER][SUITS];
srand(time(0));
InitDeck(Deck);
ShuffleDeck(Deck);
while (Player1Point != 30 && Player2Point != 30){
for (int i = CardCount; i < Count; i++){
DealCard(Deck, i, &Hand1, &Hand2, Count, j);
j++;
}
PrintCard(Hand1, 3);
Count = Count + 4;
CardCount = CardCount + 4;
Player1Point++;
}
return 0;
}
void InitDeck(int Deck[CARDS][PLAYERS]){
int suit, num, row;
row = 0;
for (suit = 0; suit < 4; suit++){
for (num = 0; num < 10; num++){
Deck[row][0] = suit;
Deck[row][1] = num;
row++;
}
}
}
void ShuffleDeck(int Deck[CARDS][PLAYERS]){
int Src, Dest, i;
for(i = 0; i < CARDS; i++){
Src = i;
Dest = rand()%CARDS;
SwapCards(Deck, i, Dest);
}
}
void SwapCards(int Deck[CARDS][PLAYERS], int Src, int Dest){
int Temp;
Temp = Deck[Dest][0];
Deck[Dest][0] = Deck[Src][0];
Deck[Src][0] = Temp;
Temp = Deck[Dest][1];
Deck[Dest][1] = Deck[Src][1];
Deck[Src][1] = Temp;
}
void DealCard(int Deck[CARDS][PLAYERS], int i, int Hand1[NUMBER][SUITS], int Hand2[NUMBER][SUITS], int Count, int j){
if (i < Count && j < 3){
Hand1[j][0] = Deck[i][0];
Hand1[j][1] = Deck[i][1];
Hand2[j][0] = Deck[i+3][0];
Hand2[j][1] = Deck[i+3][1];
}
}
void PrintCard(int Hand1[NUMBER][SUITS], int size){
printf("Your cards: \n");
int psuit, pnum;
for (int i = 0; i < size; i++){
psuit = Hand1[i][0];
pnum = Hand1[i][1];
printf("Card: %s de %s\n", num[pnum], suit[psuit]);
}
printf("\n");
}

Unshuffled string is different from original string after shuffling and unshuffling

I'm actually implementing a shuffling function with an un-shuffling function. I'm using the Fisher-Yates algorithm with pseudo random number generator with a fixed seed. The unshuffled string doesn't look like the initial string, however.
I've checked if my random array is the same in the shuffling function and the un-shuffling function. The unshuffling function is the same as the shuffling function but in reverse.
Here is my shuffling function :
void shuffle(char * phrase)
{
int size_phrase = strlen(phrase);
srand(seed);
int * rdm_array = (int*)malloc(sizeof(int)*size_phrase);
int i;
for(i = 0; i < size_phrase; i++)
{
rdm_array[i] = rand()%size_phrase;
//printf("%d", rdm_array[i]);
}
//begin shuffle here
int j;
int k = 0;
for(j = size_phrase -1 ; j > 0 ; j-- , k++)
{
int rdm_nb = rdm_array[k];
char temp = phrase[j];
phrase[j] = phrase[rdm_nb];
phrase[rdm_nb] = temp;
}
free(rdm_array);
}
And here is my unshuffling function :
void unshuffle(char * phrase)
{
int size_phrase = strlen(phrase);
srand(seed);
int * rdm_array = (int*)malloc(sizeof(int)*size_phrase);
int i;
for(i = 0; i < size_phrase; i++)
{
rdm_array[i] = rand()%size_phrase;
//printf("%i", rdm_array[i]);
}
//On commence le mélange ici
int j;
int k = size_phrase-1;
for(j = 0 ; j < size_phrase ; j++ , k--)
{
int rdm_nb = rdm_array[k];
char temp = phrase[j];
phrase[j] = phrase[rdm_nb];
phrase[rdm_nb] = temp;
}
free(rdm_array);
}
And here is my Output :
It looks like it's missing one loop or something like that.
Add a printf to show what gets exchanged in both shuffle and unshuffle like this
/* after this line */
int rdm_nb = rdm_array[k];
/* insert debug output */
printf("%d <-> %d\n", j, rdm_nb);
You will see that in function shuffle variable j counts from size_phrase -1 to 1 while in unshuffle it counts from 0 to size_phrase -1.
Probably you should change the for loop in shuffle to
for(j = size_phrase -1 ; j >= 0 ; j-- , k++)

How to Avoid repeating number randomized in 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...

Enumerating Permutations of a set of subsets

I have sets S1 = {s11,s12,s13), S2 = {s21,s22,s23) and so on till SN.I need to generate all the permutations consisting elements of S1,S2..SN.. such that there is only 1 element from each of the sets.
For eg:
S1 = {a,b,c}
S2 = {d,e,f}
S3 = {g,h,i}
My permuations would be:
{a,d,g}, {a,d,h}, {a,d,i}, {a,e,g}, {a,e,h}....
How would I go about doing it? (I could randomly go about picking up 1 from each and merging them, but that is even in my knowledge a bad idea).
For the sake of generality assume that there are 'n' elements in each set. I am looking at implementing it in C. Please note that 'N' and 'n' is not fixed.
It's just a matter of recursion. Let's assume these definitions.
const int MAXE = 1000, MAXN = 1000;
int N; // number of sets.
int num[MAXN]; // number of elements of each set.
int set[MAXN][MAXE]; // elements of each set. i-th set has elements from
// set[i][0] until set[i][num[i]-1].
int result[MAXN]; // temporary array to hold each permutation.
The function is
void permute(int i)
{
if (i == N)
{
for (int j = 0; j < N; j++)
printf("%d%c", result[j], j==N-1 ? '\n' : ' ');
}
else
{
for (int j = 0; j < num[i]; j++)
{
result[i] = set[i][j];
permute(i+1);
}
}
}
To generate the permutations, simply call permute(0);
If you know exactly how many sets there are and it's a small number one might normally do this with nested loops. If the number of sets is greater than 2 or 3, or it is variable, then a recursive algorithm starts to make sense.
And if this is homework, it's likely that implementing a recursive algorithm is the object of the entire assignment. Think about it, for each set, you can call the enumeration function recursively and have it start enumerating the next set...
If they are in a container, just iterate through each:
#include <stdio.h>
int main(void)
{
int set1[] = {1, 2, 3};
int set2[] = {4, 5, 6};
int set3[] = {7, 8, 9};
for (unsigned i = 0; i < 3; ++i)
{
for (unsigned j = 0; j < 3; ++j)
{
for (unsigned k = 0; k < 3; ++k)
{
printf("(%d, %d, %d)", set1[i], set2[j], set3[k]);
}
}
}
return 0;
}
Generic solution:
typedef struct sett
{
int* nums;
int size;
} t_set;
inline void swap(t_set *set, int a, int b)
{
int tmp = set->nums[a];
set->nums[a] = set->nums[b];
set->nums[b] = tmp;
}
void permute_set(t_set *set, int from, void func(t_set *))
{
int i;
if (from == set->size - 1) {
func(set);
return;
}
for (i = from; i < set->size; i++) {
swap(set, from, i);
permute_set(set, from + 1, func);
swap(set, i, from);
}
}
t_set* create_set(int size)
{
t_set *set = (t_set*) calloc(1, sizeof(t_set));
int i;
set->size = size;
set->nums = (int*) calloc(set->size, sizeof(int));
for(i = 0; i < set->size; i++)
set->nums[i] = i + 1;
return set;
}
void print_set(t_set *set) {
int i;
if (set) {
for (i = 0; i < set->size; i++)
printf("%d ", set->nums[i]);
printf("\n");
}
}
int main(int argc, char **argv)
{
t_set *set = create_set(4);
permute_set(set, 0, print_set);
}
This is a fairly simple iterative implementation which you should be able to adapt as necessary:
#define SETSIZE 3
#define NSETS 4
void permute(void)
{
char setofsets[NSETS][SETSIZE] = {
{ 'a', 'b', 'c'},
{ 'd', 'e', 'f'},
{ 'g', 'h', 'i'},
{ 'j', 'k', 'l'}};
char result[NSETS + 1];
int i[NSETS]; /* loop indexes, one for each set */
int j;
/* intialise loop indexes */
for (j = 0; j < NSETS; j++)
i[j] = 0;
do {
/* Construct permutation as string */
for (j = 0; j < NSETS; j++)
result[j] = setofsets[j][i[j]];
result[NSETS] = '\0';
printf("%s\n", result);
/* Increment indexes, starting from last set */
j = NSETS;
do {
j--;
i[j] = (i[j] + 1) % SETSIZE;
} while (i[j] == 0 && j > 0);
} while (j > 0 || i[j] != 0);
}
You may think about the elements of a set as values of a cycle counter. 3 sets means 3 for cycles (as in GMan answare), N sets means N (emulated) cycles:
#include <stdlib.h>
#include <stdio.h>
int set[3][2] = { {1,2}, {3,4}, {5,6} };
void print_set( int *ndx, int num_rows ){
for( int i=0; i<num_rows; i++ ) printf("%i ", set[i][ndx[i]] );
puts("");
}
int main(){
int num_cols = sizeof(set[0])/sizeof(set[0][0]);
int num_rows = sizeof(set)/sizeof(set[0]);
int *ndx = malloc( num_rows * sizeof(*ndx) );
int i=0; ndx[i] = -1;
do{
ndx[i]++; while( ++i<num_rows ) ndx[i]=0;
print_set( ndx, num_rows );
while( --i>=0 && ndx[i]>=num_cols-1 );
}while( i>=0 );
}
The most efficient method I could come up with (in C#):
string[] sets = new string[] { "abc", "def", "gh" };
int count = 1;
foreach (string set in sets)
{
count *= set.Length;
}
for (int i = 0; i < count; ++i)
{
var prev = count;
foreach (string set in sets)
{
prev = prev / set.Length;
Console.Write(set[(i / prev) % set.Length]);
Console.Write(" ");
}
Console.WriteLine();
}

Resources