I am trying to create a deck of cards in C. The way I want to implement this is by having a 2 dimensional array of deck[51][1], which will have 52 slots of 2 slots each. The first slot will contain the card value (1-52) and the second slot will contain the suit (1-4).
I have tried to assign this by using the below code:
int deck[51][1];
int i;
int j;
int suit = 1;
int main()
{
for(i=0; i<52; i++){
for(j=0; j<2; j++){
if(j==0){
deck[i][j] = i+1;
} else {
deck[i][j] = suit % 4;
}
suit++;
}
}
I then try and make it print out every card's value using the following double loop:
for(i=0; i<52; i++){
for(j=0; j<2; j++){
printf("%i ",deck[i][j]);
}
printf("\n");
}
return 0;
}
However instead of resulting in 52 lines of the card value followed by its suit, it just displays a weird
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
and so on until
51 52
52 0
I can't work out why it's not assigning the suit % 4 value to the second item of every array, which should result in a neat
1 1
2 2
3 3
4 4
5 1
6 2
7 3
8 4
Although array indexes in C are zero-based, it does not mean that the compiler would add 1 to each dimension on a declaration. Your declaration makes an array that is 51x1, not 52x2. For 52x2 array use
int deck[52][2];
Your current implementation has undefined behavior, which makes the output of your program incorrect: accessing deck[x][1] goes past the boundaries of the array, producing incorrect output.
Related
I have an assignment to implement a board game. I come up with an idea to print integer and char using the same statement for example,
int main() {
char c[2];
c[0]=1;
c[1]='X';
for (int i = 0;i<=1;++i) {
printf("%d", c[i]);
}
return 0;
}
this is not working as I have integer and char in the array. how could i modify this to just use one for loop?
EDIT:
I am trying to implement a noughts and crosses game. So I display my board as
1 2 3
4 5 6
7 8 9
and whenever a player put down a X or O at a position, I want to display my board for example,
1 X 3
4 5 6
7 8 9
You can just print chars. Since your digits are always 1 to 9 you can use chars '1' to '9' (49 to 57) instead.
It's not exactly a code you'd be writing in production, but it's a nice case of a little puzzle and what you can do with C.
int main() {
char c[2];
c[0]='1';
c[1]='X';
for (int i = 0;i<=1;++i) {
printf("%c", c[i]);
}
return 0;
}
I've slightly modified your code to make it clear how that might work.
Your code won't work as intended as you're mixing up two distinct data types. int and char are not the same type of element. They don't even have the same size; the size of char is defined as 1, and the size of int varies by implementation, but is usually 4 or 8. So your array will not even be able to hold ints. When you say:
c[0] = 1;
what is actually happening is that the array stores the char with the ASCII value of 1, which is the "Start of Heading" character.
To do what you want, do not use the int type at all. Use char throughout. That is, write something like this:
c[0] = '1';
Putting the '1' in single quotes makes it a char, not an int. You can use this to fill your 2D array and then make replacements with 'X' and '0' when needed.
You're doing to mistakes here.
You're using c[0]=1; instead of c[0]='1';. You want the character 1 and not the number 1.
You're using printf("%d instead of printf("%c. You want to print a character and not a number.
Here is some example code to achieve what you want:
void print_board(char *board) {
for(int i=0; i<9; i++) {
printf("%c ", board[i]);
if(i % 3 == 2)
printf("\n");
}
printf("\n");
}
void init_board(char *board) {
for(int i=0; i<9; i++)
board[i] = '1' + i;
}
int main(void) {
char board[9];
init_board(board);
print_board(board);
board[2] = 'X';
print_board(board);
board[5] = 'O';
print_board(board);
init_board(board);
print_board(board);
}
The above is not really production code. But it's enough to get you going.
Output:
$ ./a.out
1 2 3
4 5 6
7 8 9
1 2 X
4 5 6
7 8 9
1 2 X
4 5 O
7 8 9
1 2 3
4 5 6
7 8 9
I'm currently working on a program in C where I input matrix dimensions and elements of a matrix, which is represented in memory as dynamic 2D array. Program later finds maximum of each row. Then it finds minimal maximum out of maximums of all rows.
For example,
if we have 3x3 matrix:
1 2 3
7 8 9
4 5 6
maximums are 3, 9, 6 and minimal maximum is 3. If minimal maximum is positive, program should proceed with rearranging order of rows so they follow ascending order of maximums, so the final output should be:
1 2 3
4 5 6
7 8 9
I made a dynamic array which contains values of maximums followed by row in which they were found, for example: 3 0 6 1 9 2. But I have no idea what should I do next. It crossed my mind if I somehow figure out a way to use this array with indices I made that I would be in problem if I have same maximum values in different rows, for example if matrix was:
1 2 3
4 5 6
7 8 9
1 1 6
my array would be 3 0 6 1 9 2 6 3. I would then need additional array for positions and it becomes like an inception. Maybe I could use some flag to see if I've already encountered the same number, but I generally, like algorithmically, don't know what to do. It crossed my mind to make an array and transfer values to it, but it would waste additional space... If I found a way to find order in which I would like to print rows, would I need an adress function different than one I already have? (which is, in double for loop, for current element - *(matrix+i * numOfCols+currentCol) ) I would appreciate if somebody told me am I thinking correctly about problem solution and give me some advice about this problem. Thanks in advance!
I don't know if I have understood it correctly, but what you want to do is to rearrange the matrix, arranging the rows by the greatest maximum to the least...
First, I don't think you need the dynamic array, because the maximums are already ordered, and their position on the array is enough to describe the row in which they are.
To order from maximum to minimum, I would make a loop which saved the position of the maximum and then, use it to store the correspondent row in the input matrix into the output matrix. Then, change the value of that maximum to 0 (if you include 0 in positives, then change to -1), and repeat the process until all rows have been passed to the output matrix. Here is a sketch of what it would look like:
for(k = 0; k < n_rows; ++k)
for(i = 0; i < n_rows; ++i)
if (max[i] > current_max)
current_max = max[i];
max_row = i;
for(c = 0; c < n_columns; ++c)
output_matrix[row][c] = inputmatrix[max_row][c];
max[max_row] = 0;
Array is not dynamic because we can not change the size of array, so in this case you can use double pointer, for example, int **matrix to store the value of 2D array.
The function for searching the max value of each row and the row index of each max value:
int * max_of_row(int n, int m, int **mat) {
// allocate for n row and the row index of max value
int *matrix = malloc (sizeof(int) * n*2);
for(int i = 0; i < 2*n; i++) {
matrix[i] = 0;
}
int k = 0;
for(int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if(matrix[k] < mat[i][j]) {
matrix[k] = mat[i][j];
}
}
matrix[k+1] = i;
k += 2;
}
return matrix;
}
The main function for test:
int main(int argc, char const *argv[])
{
// allocate for 4 rows
int **matrix = malloc (sizeof (int) * 4);
for (int i = 0; i < 4; i++) {
// allocate for 3 cols
matrix[i] = malloc(sizeof(int) * 3);
for(int j = 0; j < 3; j++){
matrix[i][j] = i+j;
}
}
int * mat = max_of_row(4, 3,matrix);
printf("matrix:\n");
for (int i = 0; i < 4; i++) {
for(int j = 0; j < 3; j++){
printf("%d ",matrix[i][j]);
}
printf("\n");
}
printf("max of row and positon\n");
for (int i = 0; i < 8; i++) {
printf("%d ", mat[i]);
}
printf("\nmax of row\n");
for (int i = 0; i < 8; i += 2) {
printf("%d ", mat[i]);
}
printf("\n");
return 0;
}
Output:
matrix:
0 1 2
1 2 3
2 3 4
3 4 5
max of row and positon
2 0 3 1 4 2 5 3
max of row
2 3 4 5
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
I want to obtain the following output:
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 9 10
The code am running is as follows:
#include <stdio.h>
int main(void) {
int i=1,flag=0,lines=0; //0 for forward, 1 for reverse
while(i!=0 && lines<3){
if(!flag){
printf("%d ",i);
if(i==10){
flag=1;
printf("\n");
lines++;
}
else
i++;
}
else if(flag){
printf("%d ",i);
if(i==1){
lines++;
flag=0;
printf("\n");
}
else
i--;
}
}
return 0;
}
Am getting the desired output from the above code but not sure if it's an optimal code. Any other method/suggestion? Considering unlimited space but time complexity should be kept minimum.
Condition: Use only one loop
Use forloops, minimize code that is repeated
#include <stdio.h>
int main(void) {
int lines, flag=1, val;
for(lines=0;lines<3;lines++)
{
if(flag == 1)
for(val=1;val<=10;val++)
printf("%d ", val);
else
for(val=10;val>0;val--)
printf("%d ", val);
printf("\n");
flag = -flag;
}
return 0;
}
Hint: you can use for loops to iterate in either direction:
for (int i = 1; i <= 10; ++i)
or
for (int i = 10; i >= 1; --i)
Also, a for loop is better than a while here because it really shows to the reader "I am iterating i from this to that."
Use an array and iterate it normally at first iteration, vice versa in the second iteration and then normally again.
Sample code:
#include <stdio.h>
#define SIZE 10
void print_arr(int* array, int size);
void print_rev_arr(int* array, int size);
int main(void)
{
int array[SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int iter = 3;
for(int i = 0; i < iter; ++i)
if(i % 2)
print_arr(array, SIZE);
else
print_rev_arr(array, SIZE);
return 0;
}
void print_arr(int* array, int size)
{
for(int i = 0; i < size; ++i)
printf("%d ", array[i]);
printf("\n");
}
void print_rev_arr(int* array, int size)
{
for(int i = size - 1; i >= 0; --i)
printf("%d ", array[i]);
printf("\n");
}
Output:
Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out
10 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
IO completely dominates this problem.
But the fastest way to iterate forwards is
for(i=0;i<N;i++)
and the fastest and most elegant way to iterate backwards is
int i = N;
while(N--)
You can do this:
Use a for loop that will start from 1 and reach 10. Print its
counter.
Use a for loop that will start from 10 and stop at 1. Print its
counter.
Use a for loop that will start from 1 and reach 10. Print its
counter.
Sample code:
#include <stdio.h>
#define LEN 10
#define ITER 3
int main(void)
{
for(int i = 0; i < ITER; ++i)
{
if(i % 2)
for(int j = 1; j <= LEN; ++j)
printf("%d ", j);
else
for(int j = LEN; j >0; --j)
printf("%d ", j);
printf("\n");
}
return 0;
}
Output:
Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out
10 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
There are 2 things to consider.
First is whether the program is optimal or not. Is is quite easy to prove that your program is optimal (at least asymptotically optimal). You need to display 3n numbers, so you need at least 3n iterations. You have 3n iterations, so it's fine. You might be able to further optimize the iterations themselves, but that will arise as an implicit result of the second paragraph.
The second is readability. Your code is a bit verbose and unflexible. Consider the following:
int pattern[] = {1,2,3,4,5,6,7,8,9,10};
int patternSize = sizeof(pattern)/sizeof(int);
for (int i=0; i < 3; i++)
for (int j=0; j<patternSize; j++) {
if (i % 2)
printf("%d", pattern[patternSize - j - 1]);
else
printf("%d", pattern[i])
}
The code is shorter and clearer. Also, it is more maintable. It is clear what you have to do to chanelge the pattern. I could hardcode the pattern size as 10, but that would requite 2 changes when you change the pattern. I could generate the pattern, from the value of j, but that would limit the number of patterns that could be shown.
But what if the pattern is all the numbers from 1 to 200? Of course I'm not going to write them by hand. Just replace the array with a for loop that fills up the array. You don't have to change the code that displays the array. This is a small example of separation of concerns - one part of thr code does pattern generation, another part does the display, and they can be modified independently.
While this is asymptotically optimal, there are optimizations that can be made. For examples, using that array to store the pattern is not as efficient as generating the pattern from j. But in practice, unless more efficiency is needed, the advantages of this method outweigh the small performance penalty.
Okay, here's my take, I think it's more pleasant than most:
#include <stdio.h>
int main(void)
{
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 10; ++j)
{
const int v = (i % 2) ? 10 - j : j + 1;
printf("%d ", v);
}
putchar('\n');
}
return 0;
}
Some points:
Doesn't use an array, instead just generates the very simple pattern from the line number (i) and position (j).
Not designed for "pluggable" patterns by using an array, since the pattern was very simplistic and repeating, that is exploited to simplify the code.
Re-use the inner loop, rather than duplicating it.
Prints a linefeed in the proper place, to actually get separate lines (not all posted solutions to that).
The inner loop's body could be shortened to a single line by folding v into the printf() of course, but I aimed for readability and clarity, there.
I'm learning about 2D arrays in C and I'm a bit confused. I have the following program which reads a 2D arrays and adds its values in another array.
#include <stdio.h>
int main() {
int arr[4][5] = {{1,2,3,4,5},
{3,1,1,5,2},
{4,1,4,1,5},
{2,5,3,3,4}};
int many[4];
int i;
for (i=0;i<4;i++) {
many[i] = arr[i][i] + arr[i][i];
printf("%d\n", many[i]);
}
The output of this program is:
2
2
8
6
But I think it should be 3, 3, 9, 7 because the for loop starts at 1 and the first column and row gets 1 and second column and row get 2 because there is already 1 which means 1+1 = 2 and 2 + 1 = 3, for second number it is same idea.
For the third number I got 9 because we get 4 from row 2 column 2. 4 + 4 + 1 = 9 and for last number I got 7 because last row has 3 in row 3 column 3.
The output you get is absolutely right for this loop.
for (i=0;i<4;i++)
{
many[i] = arr[i][i] + arr[i][i];
printf("%d\n", many[i]);
}
You can easily get to know it by tracing.
so let's trace it...
during i=0
arr[0][0] denotes 1st element (as indices start from 0) of 1st array which is 1
many[0] = arr[0][0]+arr[0][0] // 1+1=2
during i=1
arr[1][1] denotes 2nd element of 2nd array which is also 1
many[0] = arr[1][1]+arr[1][1] // 1+1=2
during i=2
arr[2][2] denotes 3rd element of 3rd array which is 4
many[2] = arr[2][2]+arr[2][2] // 4+4=8
during i=3
arr[3][3] denotes 4th element of 4th array which is 3
many[3] = arr[3][3]+arr[3][3] // 3+3=6
Therefore,The output of this program is:
2
2
8
6
Note: arr[m][n] denotes (n+1)th element of (m+1)th array
You need 2 loops to iterate through your 2D array
#include <stdio.h>
int main() {
int arr[4][5] = {{1,2,3,4,5},
{3,1,1,5,2},
{4,1,4,1,5},
{2,5,3,3,4}};
int many[4];
int i;
int j;
for(i=0;i<4;i++)
{
many[i] = 0;
for(j=0;j<5;j++)
{
many[i] += arr[i][j];
}
printf("%d\n", many[i]);
}
}
I don't know what's happening with this code.
#include<stdio.h>
int main()
{
int ii[5], i;
for (i=1; i<=5; i++)
{
scanf("%d", &ii[i]);
}
printf("----------------------\n");
for(i=1; i<=5; i++)
printf("%d\n", ii[i]);
return 0;
}
After compiling when I provide input as
1 2 3 4 5
then it prints as it is,
but when I provide input in reverse order:
5 4 3 2 1
it keeps on asking up to some more digits and after that it prints out some random digits from given set of input.
How can I fix this?
c uses 0 indexing that means that array indexes start at 0 not 1. A for loop over an array should look like this:
int array[ARRAY_LENGTH], i;
for (i = 0; i < ARRAY_LENGTH; ++i) {
This will ensure that i will go from 0 to ARRAY_LENGTH - 1 and will not go outside the bounds of your array.
These lines:
for(i=1; i<=5; i++)
printf("%d\n", ii[i]);
will Access element 5 of ii where the maximum index is 4. This will cause Undefined Behavior which is likely why you are seeing random numbers appear.