How do I print a cross to the console in C? - c

I've just started studying information technologies and I am currently stuck on a programming assignment.
I have to write a code in C which displays a cross to the console, the size of the cross being determined by an initial input.
So the console output should look like this:
size?: 5(user input)
xooox
oxoxo
ooxoo
oxoxo
xooox
(replace the os with blank space)
I've now come as far as this:
#include <stdio.h>
int main(void)
{
int n;
printf("size?: ");
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if( (i==j) )
printf("*");
else
printf(" ");
}
printf("\n");
}
return 0;
}
But this only displays one diagonal of the cross, I'm thinking that the opposite diagonal can be created by another condition after the if however I am lost as to what that condition might be.

You're definitely on the right track! Don't give up.
The way to think about this is to think about the loop counters. You've figured out one half of it. If the row and column are the same, you need to output a *. So what's the other condition? Well, think about counting backwards. If the row is the same as the column counted backwards, we also want a *.
I don't want to do your homework for you, so I'll hold off on writing the code, but hopefully that gives you a hint as to what you need to do.

Replace if( (i==j) ) with if( (i==j)||(i+j)==n+1 ), That is,:
#include <stdio.h>
int main(void)
{
int n;
printf("size?: ");
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if( (i==j)||(i+j)==n+1 )
printf("*");
else
printf(" ");
}
printf("\n");
}
return 0;
}

Should you need some help, you have to check the column from the other side as well:
#include <stdio.h>
int n;
int main(void) {
printf("size?: ");
scanf("%d",&n);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if (i == j || i == n - j + 1) printf("*");
else printf(" ");
}
printf("\n");
}
return 0;
}
Edit: There are suggestions to do i + j == n + 1, but I believe i == n - j + 1 makes more sense, since:
i is your current row
j is your current column
n is the size of your square (max row / max column)
i == n - j + 1 means draw * at max - current + 1 column

First thing's first, C compilers don't like
for (int i = 0; i < n; i++)
They like
int i = 0;
for (i = 0; i < n; i++)
But if you're using a C++ compiler, you probably won't get that problem.
Now; back to solving the problem at hand!
On the line:
if( (i==j) )
With this conditional, you're plotting points at (1, 1), (2, 2), (3, 3) ...
You want to also plot points at (1, n), (2, n - 1), (3, n - 2) ...
So you need to add a second conditional to this if statement:
if ( (i==j) || (i == (n - j) + 1 ) )
Then you can simplify this up a bit if you want...
if ( (i==j) || (i == n - j + 1 ) )
And there you go! It now prints a cross, like you described in your question.

Related

Index Value goes to 5 million for nested for loop - C

I am programming a board game and I need to assign character values to a 2D array. To do this, I am using a nested for loop with the i as the row index and j as the column index. With a 4x4 dimension (n=4) The loop works fine until the second row. Using the debugger on codelite, I've noticed that the value of j does not increase from 0 to 1 like it should, but it increases to 5,560,570, disrupting the loop. I've also noticed that when using a dimension larger than 4, the program fails to display anything at all. Is this a memory error? I am stumped and have showed this to multiple other people as well.
int main(void){
int n;
char board[n][26];
printf("Enter the board dimension: ");
scanf("%d", &n);
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if((i == (n/2)-1 && j == (n/2)-1) || (i == (n/2) && j == (n/2))){
board[i][j] = 'W';
}
else if((i == (n/2) && j == (n/2)-1) || (i == (n/2)-1 && j == (n/2))){
board[i][j] = 'B';
}
else{
board[i][j] = 'U';
}
}
}
It appears that you are using n before you set it, in the declaration of board. Because this is undefined behavior, absolutely anything is permitted to happen; in this case, that is disrupting the value of other variables.
To fix this, you should probably wait until after initializing n in scanf to declare board, like so:
int main(void) {
int n;
printf("Enter the board dimension: ");
scanf("%d", &n);
char board[n][26];
...
}
As has been pointed out in the comments, this still will cause problems if n > 26, and can be wasteful for n != 26. Due to the way that arrays work in C, fixing that would probably require rethinking how the board is stored altogether.

issues randomly populating a 2d array of structure type in C

I'm trying to populate a 20x20 matrix where each entry is of structure type. My goal is to randomly assign 100 ants and 5 doodlebugs on this 2D array. Even though I got it to work, I don't always get the amount of ants or doodlebugs I need in the matrix. I added a counting function to always verify how many of them I have each time I run the program, but I'm always slightly short. I'm trying to force those number to work (100 ants and 5 doodlebugs) by using a do/while loop in my populating function, although it's not working. Can someone spot where is my logic is failing me?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#define N 20
struct cellState {
int emptyInt;
int antInt;
int dBInt;
char emptyChar;
char antChar;
char dBChar;
};
struct cellState gridState[N][N];
// function to populate world
void pop_mtx(struct cellState gridState[N][N], int antsNeeded, int dBNeeded) {
int i, j;
do {
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if ((gridState[i][j].emptyInt = rand() % 3) == 0) {
gridState[i][j].emptyChar = '.';
} else
if (((gridState[i][j].antInt = rand() % 3 == 1) && antsNeeded != 0)) {
gridState[i][j].antChar = 'a';
antsNeeded--;
} else
if (((gridState[i][j].dBInt = rand() % 3 == 2) && dBNeeded != 0)) {
gridState[i][j].dBChar = 'D';
dBNeeded--;
}
}
}
} while (dBNeeded != 0 && antsNeeded != 0);
}
//function to display current state of the world
void display_mtx(struct cellState gridState[N][N]) {
int i, j;
char charToDisplay;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (gridState[i][j].antChar == 'a')
charToDisplay = 'a';
else
if (gridState[i][j].dBChar == 'D')
charToDisplay = 'D';
else
charToDisplay = '.';
printf("%c ", charToDisplay);
}
printf("\n");
}
printf("\n\n");
}
//function to count ants and doodlebugs
void count_mtx(struct cellState gridState[N][N]) {
int i, j, antCount = 0, dBcount = 0;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (gridState[i][j].antChar == 'a')
antCount++;
else
if (gridState[i][j].dBChar == 'D')
dBcount++;
}
}
printf("ant count: %i, doodlebug count: %i\n", antCount, dBcount);
}
int main(void) {
srand((unsigned int)time(NULL));
//populate grid state with 5 doodlebugs and 100 ants
int antsNeeded = 100, dBNeeded = 5;
pop_mtx(gridState, antsNeeded, dBNeeded);
count_mtx(gridState);
display_mtx(gridState);
}
There are several problems. First, each time you call rand() you obtain a different value, so it is possible that none of the three tests pass. You should call rand () once and save the value.
Second, there is nothing that guarantees that over NxN calls of rand() you will get as many ones and twos as you need. The outer loop is therefore necessary. You should also preserve already populated squares from one iteration to the next because it might take a long time before you reach an iteration that produces enough ones and twos.
Third, this method is biased toward the squares at the beginning of the grid. It will not give you one out of all possible distributions of 100 ants and 5 doodlebugs over 400 squares with equal probability.
Here is the proper way to do it:
Consider the grid as a uni-dimensional array. First fill it, in order, with 100 ants, 5 doodlebugs, and empty spaces. Then perform a random shuffle of the array.
This procedure will return each possible distribution of the ants and doodlebugs on the grid with equal probability.

Wrong output with the N Queen

So I have to do a modified version of the N queen problem, where we are given an initial configuration of the chess board filled with pawns, and we need to find the maximum number of queens we can have so that they don't attack each other. The input consists of an integer in the first line giving the dimension of the board ( NxN) and n lines defining the setup of the chess board.The characters will be either a ā€˜pā€™ (meaning there is already a pawn in that location) or an ā€˜eā€™ (meaning that location is empty).
For example, for this input,
5
epepe
ppppp
epepe
ppppp
epepe
the output will be 9.
Here is my code, everything seems clear, but I don't see why it doesnt give the correct output
#include <stdio.h>
#include <malloc.h>
/* function headers */
void do_case(int);
int solve(char **,int,int);
int canPlace(char **,int,int,int);
/* Global vars */
int queens;
int main(void)
{
int n;
scanf("%d",&n);
getchar();
while( n != 0 )
{
do_case(n);
scanf("%d",&n);
getchar();
}
return 0;
}
void do_case(int n)
{
int i,j; //counters for input
//board configuration allocation
char **configuration = (char **)malloc(n*sizeof(char *));
for(i = 0 ; i < n ;i++ )
configuration[i] =(char *)malloc(n*sizeof(char));
queens = 0;
//get input
for( i = 0; i < n; i++ )
{
for( j = 0; j < n; j++ )
{
scanf("%c",&configuration[i][j]);
}
getchar();
}
//solve
solve(configuration,n,0);
printf("%d \n",queens);
}
//recursive solver
int solve(char **configuration,int N,int col)
{
int i,j;
//base case
if( col >= N )
return 1;
//consider this column
//try placing queen in non blocked spot in all rows
for(i = 0; i < N; i++)
{
if ( configuration[i][col] == 'e' && canPlace(configuration,N,i,col) )
{
//Place queen in configuration[i][col]
configuration[i][col] = 'q';
queens++;
//recursion on the rest
if( solve(configuration,N,col + 1) == 1 )
{
return 1;
}
//backtrack
configuration[i][col] = 'e';
queens--;
}
}
return 0;
}
//this function check if queen can be placed
int canPlace(char **configuration,int N, int row, int col)
{
int i, j;
/* Check this row on left side */
for (i = 0; i < col; i++)
{
if (configuration[row][i] == 'q')
{
return 0;
}
}
/* Check upper diagonal on left side */
for (i = row, j = col; i >= 0 && j >= 0; i--, j--)
{
if ( configuration[i][j] == 'q')
{
return 0;
}
}
/* Check lower diagonal on left side */
for (i = row, j = col; j >= 0 && i < N; i++, j--)
{
if (configuration[i][j] == 'q')
{
return 0;
}
}
return 1;
}
Basically, your code outputs 0 because it requires that we place exactly one queen in every column, which is not the case in your example.
That said, there are multiple problems with the algorithm (and I don't claim the list is complete, though it may be):
The code does not consider every possibility: it will only find the first possible arrangement, and then quit searching after a single "if( col >= N ) return 1;". Instead, it should go like "if( col >= N ) update the best possible value of queens in a separate variable, then return 0 to continue searching".
In the line "if( solve(configuration,N,col + 1) == 1 )", the code assumes there can not be two queens in a single column. The call should use col instead of col + 1, and somehow account for where we stopped at the current column.
To allow columns without queens, an unconditional call to "solve(configuration,N,col + 1)" should be placed somewhere in the solve function.
When we allow item 2, the function canPlace should be modified to also check the column.
The loops of canPlace should break whenever a pawn is found.
With pawns blocking the way, you shouldn't just move on to the next column because you can place more queens in the same column. You should modify your code to pass both a row and a column when you recurse, and only move to the next square, not the next column.
Also, it looks like your algorithm finds the first solution instead of the best solution. The original queens problem only cared about 1 possible solution, but with the modified problem, you need to make sure you check all solutions and remember the best one.
Also, your canPlace function is wrong. It doesn't account for pawns at all.

Updating my array board game

So I'm creating a game. It has a 5 by 5 board filled with characters a, b and c. I need to create a function where if the board detects the same letter next to each other, it disappears and the emptied cells are replaced with a new set of letters (a,b,c). So a bit like the candy crush game. I also need to display the number of moves that are made before the game ends. Here's where I am so far
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX 10
//creates board and fills in the letters randomly
int board()
{
char grid[MAX][MAX];
char letter[3] = {'a', 'b', 'c'};
int i,j,row,col;
printf("Please enter your grid size: ");
scanf("%d %d", &row, &col);
if(row < 10 && col < 10){
for(i=0; i < MAX; i++){
for(j=0; j < MAX; j++){
grid[i][j] = letter[rand()%3];
}
}
for(i=0; i < MAX; i++){
for(j=0; j < MAX; j++){
printf("%c ", grid[i][j]);
}
printf("\n");
}
}
else{
printf("Board is too big\n");
board();
}
return 0;
}
//the count doesn't quite do what I need it to
int moveCount()
{
char s;
printf("Press s to start: ");
scanf("%c", &s);
if(s == 's' || s == 'S'){
int count;
int max = 10;
for(count=1; count < max; count++)
if(count == max){
-printf("No more moves can be made");
}
else{
printf("Number of moves made: %d\n", count);
}
}
else{
printf("That is not s\n");
moveCount();
}
}
//Trying to check to make sure that n board is always atleast three cells
int inputCheck(){
int n, m;
if(n == 3 || n > 3 && m == 1 || m > 1){
moveCount();
}
}
int main()
{
board();
inputCheck();
}
What's the best way to implement a function that checks if neighbouring cells are the same and then deletes them. I would imagine doing something like if(myArray[0][0] == 'a' && myArray[0][1] == 'a'{do something}...but i don't know if that's the best way or how I would loop that. Also how to correctly implement a count that displays the move made?
I realise this code has a lot of flaws but I'm quite new so go easy please. Thanks for any help or a push in the right direction.
A serious bug here:
int n, m;
if(n == 3 || n > 3 && m == 1 || m > 1){
n and m are used uninitialized.
And you need to #include <stdlib.h> for rand()
In answer to your actual question, something like this would work. This is rather sloppy, but it's my 5 min answer. I assume grid is the actual board, which exists only in your board() function at the moment, so I simply added that as a parameter. AKA You're going to have to make it fit your actual game.
inline int clamp (int v, int min, int max) {
return (v < min) ? min: (v > max) ? max: v;
}
void place (char ltr, int x, int y, char grid[MAX][MAX])
{
grid[y][x] = ltr; // TODO: put bounds checking around x & y
for (int i = clamp(y - 1, 0, MAX); i <= clamp (y + 1, 0, MAX); i++) {
for (int j = clamp(x - 1, 0, MAX); j <= clamp(x + 1, 0, MAX); j++) {
if (i != y || j != x && grid[i][j] == ltr) {
grid[i][j] = '\0'; // TODO: replace null char with desired one.
}
}
}
}
The board function is set up just fine.
As the previous answers said parameters are the best way to check a value if you are going to check them within a different function, if you wish to check them within your function a simple if command would do the trick.
I would not pass an entire array as a parameter, instead I would use a pointer to that specific cell. Then, upon a person choosing a cell they are given a memory address that you could then compare the information stored inside that memory address with the other they are comparing.
Quick Pointer Lesson
- * is used to create a pointer. For instance, char *ch = array; would point to the memory address of the entire array. And then through more research you will be able to go to a specific memory address in a 2-D array, such as your board, see what is at that location and compare it to the contents contained in another memory address within your 2-D array.
Why would you want to to this?
Since this is not Java, we can about memory management in C and using an entire array as a parameter is the easy but more memory costly way of doing it. Plus, pointers are a fundamental element within most programming languages and knowing them well will make you a much better programmer.
Happy Travels!!
Also this will also be easier to go through your board to say, this person chose this address at array[3][2], there are only four memory address they would be choosing from at that point. Which ever way they choose to go, the memory address will be there and you will be able to compare both with minimal system usage and a quick response.

assigning and printing from 2d arrays C

/*
Program to calculate trip and plan flights
*/
#define TRIP 6
#define DEST 1
#include <stdio.h>
int main(void)
{
int type_num, cont_num, index, i, dest_code, trip_num, row, col;
int travelint[TRIP][DEST]= {{0}};
printf("Please enter the number of trips:");
scanf("%d", &trip_num);
for (i=0; i < trip_num ; i++)
{
printf("Please enter destination code:");
scanf("%d", &dest_code);
cont_num = dest_code / 10000;
type_num = dest_code/1000 - cont_num*10;
if ( (cont_num <= 7) && (cont_num > 0) && (type_num <= 5) && (type_num >=0) )
dest_code = travelint[i][0];
else
printf("Invalid code\n");
}
printf("%2d", travelint[0][0]);
return 0;
}
I'm having trouble printing from the array I'm not sure if I'm either printing it wrong or that the number isn't actually being assign in the array. I'm still having trouble with the concept of assign values from input into the array..
An array dimension with only one element in the row is a trifle pointless. You normally only use dimensions with more than one element in each row.
Additionally, you are never assigning to the travelint array - only reading from it. So, since it is initialized to all zeroes, all you will ever see when you print it are zeroes.
You probably simply need to change this:
if ( (cont_num <= 7) && (cont_num > 0) && (type_num <= 5) && (type_num >=0) )
dest_code = travelint[i][0];
to:
if ( (cont_num <= 7) && (cont_num > 0) && (type_num <= 5) && (type_num >=0) )
travelint[i][0] = dest_code;
This assigns to travelint.
To print out a full 2D array, you would normally use:
for (int j = 0; j < TRIP; j++)
{
for (int k = 0; k < DEST; k++)
printf("Trip[%d][%d] = %d\n", j, k, travelint[j][k]);
}
Given that the inner loop will be executed just once per iteration of the outer loop (in your example, where DEST is 1), you could simplify that to:
for (int j = 0; j < TRIP; j++)
{
printf("Trip[%d][%d] = %d\n", j, 0, travelint[j][0]);
}
You should validate the trip_num after the user enters it. You should check that scanf() actually converted a value; if the user types 'A', then your program will go into a rapid loop printing out "Invalid code" every time. Always check that inputs succeed. In theory, you should also check that outputs succeed, but that rule is more often ignored than honoured. Also, if the user is nasty and types 200, then your program is not going to be happy after the user enters the sixth trip destination. It should be between 0 and TRIP (inclusive), of course. You should handle the degenerate (0) case properly, of course. And the printing loop becomes:
for (int j = 0; j < trip_num; j++)
{
printf("Trip[%d][%d] = %d\n", j, 0, travelint[j][0]);
}

Resources