Below is a function in the game of fifteen which should search for the "0" tile and once found, allow adjacent tiles to move into its place. It works for the first few moves but then doesn't allow moves that it should permit when the zero tile is at the top row (it starts on the bottom right). Note below the "0" tile is drawn as an underscore. For example:
8 7 6
5 4 3
2 1 _
Tile to move: 3
8 7 6
5 4 _
2 1 3
Tile to move: 6
8 7 _
5 4 6
2 1 3
Tile to move: 7
Illegal move.
Here is the code:
bool move(int tile)
{
int blankrow;
int blankcol;
for (int i = 0; i < d; i++)
{
for (int j = 0; j < d; j++)
{
if (board[i][j] == 0)
{
blankrow = i;
blankcol = j;
}
}
}
for (int i = 0; i < d; i++)
{
for (int j = 0; j < d; j++)
{
if ((board[i][j] == tile) && ((board[i+1][j] == 0 || board[i-1][j] == 0) &&
(board[i][j+1] == 0 || board[i][j-1] == 0)))
{
int swapped = board[i][j];
board[blankrow][blankcol] = swapped;
board[i][j] = 0;
return true;
}
}
}
return false;
}
Just by looking, I'm pretty sure you need to change:
((board[i+1][j] == 0 || board[i-1][j] == 0) &&
(board[i][j+1] == 0 || board[i][j-1] == 0))
To:
(board[i+1][j] == 0 || board[i-1][j] == 0 ||
board[i][j+1] == 0 || board[i][j-1] == 0)
EDIT: I agree with the user comment below. Better code would look something like:
bool move(int tile)
{
int blankrow, blankcol, tilerow, tilecol;
for (int i = 0; i < d; i++) {
for (int j = 0; j < d; j++) {
if (board[i][j] == 0) {
blankrow = i;
blankcol = j;
}
else if (board[i][j] == tile) {
tilerow = i;
tilecol = j;
}
}
}
if( (blankrow == tilerow && abs(blankcol - tilecol) == 1) ||
(blankcol == tilecol && abs(blankrow - tilerow) == 1) ) {
board[blankrow][blankcol] = board[tilerow][tilecol];
board[tilerow][tilecol] = 0;
return true;
}
return false;
}
You found the blankrow and blankcol. Do the same thing to find the tilerow and tilecol. Then verify either
((blankrow == tilerow) && (abs(blankcol - tilecol) == 1))
or
((blankcol == tilecol) && (abs(blankrow - tilerow) == 1))
Swap if either of those conditions is met. The problem with the existing code is that you can have array accesses out-of-bounds. For example, if i is 0, then board[i-1][j] is an out-of-bounds access.
I think you should change the if statement in the second loop from
if ((board[i][j] == tile) &&
((board[i+1][j] == 0 || board[i-1][j] == 0) &&
(board[i][j+1] == 0 || board[i][j-1] == 0)))
to
if ((board[i][j] == tile) &&
((i+1==blankrow && j==blankcol) ||
(i-1==blankrow && j==blankcol) ||
(i==blankrow && j+1==blankcol) ||
(i==blankrow && j-1==blankcol)))
In the original you are requiring a row offset of one and a column offset of zero and a row offset of zero and a column offset of one simultaneously. Also you're potentially taking a negative index into the array or reading past its end.
Related
My code seems to be working fine, but I get a Segmentation fault when there is just one value as input. It should print a square shape based on a number as character input.
test case : ["2", "2"]
"oo\noo\n"
test case: ["", ""]
""
test case : ["2"]
SIGSEGV (signal 11)
#include <string.h>
#include <stdlib.h>
void my_square(int *x, int *y)
{
int i , j;
if (*x == 0 || *y == 0) {
printf("");
}
else{
for(i = 0; i < *x; i++){
for(j = 0; j < *y; j++){
if(*x<=2 && j == 0){
printf("o");
}else if(*x<=2 && j == 1){
printf("o\n");
}else if(*y<=2 && i == 0){
printf("o");
}else if(*y<=2 && i == 1){
printf("o\n");
}else{
//printf(" i: %d, j: %d ", i, j);
if(i == 0 && j == 0 || i == *y-1 && j == 0 || i == 0 && j == *x-1 || i == *y-1 && j == *x-1){
printf("o");
}
if(i >= 1 && j == 0 && i != *y-1) {
printf("|");
}
if(i >= 1 && j == *x-1 && i != *y-1) {
printf("|");
}
if(i == 0 && j >= 1 && j != *y-1|| i == *x-1 && j >= 1 && j != *y-1){
printf("-");
}
if(i >= 1 && j >= 1 && i < *x-1 && j < *y-1){
printf(" ");
}
if(j == *x-1){
printf("\n");
}
}
//printf("> %d, %d", i, j);
}
}
}
}
int main(int ac, char **av)
{
int x = atoi(av[1]);
int y = atoi(av[2]);
my_square(&x, &y);
return 0;
}```
You should always check ac before accessing av, otherwise it may lead to undefined behaviour (and cause a segmentation fault).
That's how you could do it (the first value is always the program file name):
int main(int ac, char **av)
{
int x, y;
if (ac <= 3)
{
x = atoi(av[1]);
y = x; // if there's only one argument, we use it for both x and y
if (ac == 3)
{
y = atoi(av[2]);
}
my_square(&x, &y);
}
return 0;
}
So I am building a map with borders and filling up with ' * '
Now what I want to do is empty all of the ' * ' and fill them up with blank spaces.
I am not getting the expected output and can't figure out what I am doing wrong, I'd really appreciate if someone could help me.
#include <stdio.h>
#define gotoxy(x,y) printf("\033[%d;%dH", (y), (x))
int height=5;
int width=5;
void fill_blank_spaces()
{
gotoxy(0,0);
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{ if(i!=0 && j!=0 && i!=height-1 && j!=width-1)
printf(" ");
}
printf("\n");
}
}
I expect the output to be:
X---X
| |
| |
| |
X---X
But the displayed output is:
X---X
*|
*|
*|
X---X
int main()
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if ((i == 0 && j == 0) || (i == 0 && j == width - 1) || (j == 0 && i == height - 1) || (j == width - 1 && i == height-1))
printf("X");
else if ((j == 0) || (j == width - 1))
printf("|");
else if (i == height - 1 || i == 0)
printf("-");
else
printf("*") ;
}
printf("\n");
}
fill_blank_spaces();
}
I am new here so excuse my unconventional description.
The top left corner is at ( 1, 1).
The first space on the following lines should go in
( 2, 2), ( 2, 3) and ( 2, 4)
#include <stdio.h>
#define gotoxy(x,y) printf("\033[%d;%dH", (y), (x))
int height=5;
int width=5;
void fill_blank_spaces()
{
for ( int i = 1; i < height - 1; i++)
{
for ( int j = 1; j < width - 1; j++)
{
gotoxy ( j + 1, i + 1);
printf ( " ");
}
}
printf ( "\n");
printf ( "\n");
}
int main ( void)
{
gotoxy ( 1, 1);
for ( int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if ((i == 0 && j == 0) || (i == 0 && j == width - 1) || (j == 0 && i == height - 1) || (j == width - 1 && i == height-1))
printf("X");
else if ((j == 0) || (j == width - 1))
printf("|");
else if (i == height - 1 || i == 0)
printf("-");
else
printf("*") ;
}
printf("\n");
}
fill_blank_spaces();
}
You don't need fill_blanck_spaces, simply replace * by a space :
int main()
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if ((i == 0 && j == 0) || (i == 0 && j == width - 1) || (j == 0 && i == height - 1) || (j == width - 1 && i == height-1))
printf("X");
else if ((j == 0) || (j == width - 1))
printf("|");
else if (i == height - 1 || i == 0)
printf("-");
else
printf(" ") ; //<=== Here
}
printf("\n");
}
return 0;
}
Can you guys please help me out here?
I have to print that kind of pattern Example for pattern
in that example the input for the size is 21.
for (int row = 0; row < size; row++)
for (int col = 0; col < size; col++) {
if (row == 0 && col == 0 || row == 0 && col == size - 1 || row == size - 1 && col == 0 || row == size - 1 && col == size - 1)
printf("+");
if ((row == 0 || row == size - 1) && (col > 0 && col < size - 1))
printf("-");
if ((row > 0 && row < size - 1) && (col == 0 || col == size - 1))
printf("|");
if ((row > 0 && row < size - 1) && (col > 0 && col < size - 1)) {
if (row == col)
printf("\\");
else
if (col == size - 2)
printf("/");
else
if (row == x && col == x)
printf("X");
else
printf(" ");
}
}
This is the code i wrote but it is not good .
How can I fix it ?
Thank you!
Here is another solution ,
int main()
{
int size =5;
int counter = 0;
printf("+");
for(int k=1;k<=size+1;k++){
printf("-");
}
printf("+");
printf("\n");
}
for(int i=1;i<=size;i++){
printf("|");
for(int j=1;j<=size;j++){
if(j==0 || j==i )
printf("\\");
else
printf(" ");
if(counter==0){
if(j==size){
printf("/");
counter++;
}
}
else if(j==size-i+1)
printf("/");
if(j==size)
printf("|");
}
printf("\n");
}
printf("+");
for(int k=1;k<=size+1;k++){
printf("-");
}
printf("+");
printf("\n");
return 0;
}
You missed couple of things, read the comments in the code below to check what I corrected.
Here is the working code:
#include <stdio.h>
int main(void)
{
int size = 21;
int x = size / 2; // You want x in the middle so its size / 2;
int i = 1;
for (int row = 0; row < size; row++, i++) // Incrementing 'i' too
{
for (int col = 0; col < size; col++)
{
// In this first if statement below you should put parenthesis around && conditions for better readability and to get rid of any warnings compiler might put out
if ((row == 0 && col == 0) || (row == 0 && col == size - 1) || (row == size - 1 && col == 0) || (row == size - 1 && col == size - 1))
printf("+");
if ((row == 0 || row == size - 1) && (col > 0 && col < size - 1))
printf("-");
if ((row > 0 && row < size - 1) && (col == 0 || col == size - 1))
printf("|");
if ((row > 0 && row < size - 1) && (col > 0 && col < size - 1))
{
if (row == x && col == x) // This should be your first check because in case you are in the middle you want to put 'x' and don't care about rest of the if-else statement
printf("X");
else if (row == col)
printf("\\");
else if (col == size - i) // Instead size - 2, you put here size - i, which is initialized to 1 and incremented by 1 in the outer for loop
printf("/");
else
printf(" ");
}
}
printf("\n"); // You want to print out the new line at the end of every row
}
return 0;
}
Im trying to write a function that scans in IP addresses on user input and has three main conditions:
If the IP address is valid, valid_addresses += 1
If the IP address is precisely -1.-1.-1.-1 then stop scanning for any further IP addresses and return valid_addresses (should contain the number of valid addresses).
If the IP address contains any value that is either below 0 or above 255, printf("Invalid input.\n") but continue scanning for further IP addresses (don't terminate the loop).
My current attempt is simply printing "Invalid input":
Main:
#include <stdio.h>
int LENGTH = 5; /* Tells the function how many IP addresses the user needs to provide on input */
char dot; /* Stores the points between digits */
struct ipaddr{ /* Making the ip address struct */
int octet1;
int octet2;
int octet3;
int octet4;
}; typedef struct ipaddr ipaddr_t;
int get_valid_ip_addrs(ipaddr_t addr_array[], int addr_array_len); /* Function prototype */
int main(){
struct ipaddr addr_array[LENGTH]; /* Variable declaration */
get_valid_ip_addrs(addr_array, LENGTH); /* Function call */
}
Function definition
int get_valid_ip_addrs(ipaddr_t addr_array[], int addr_array_len){
int valid_inputs = 0, i, k;
for(i = 0; i < addr_array_len; i++){
scanf("%i%c%i%c%i%c%i", &addr_array[i].octet1, &dot, &addr_array[i].octet2, &dot,
&addr_array[i].octet3, &dot, &addr_array[i].octet4);
/* Condition 1. (if the address is valid) */
for(k = 0; k < addr_array_len; k++){
if(addr_array[k].octet1 > 0 && addr_array[k].octet1 < 256 &&
addr_array[k].octet2 > 0 && addr_array[k].octet2 < 256 &&
addr_array[k].octet3 > 0 && addr_array[k].octet3 < 256 &&
addr_array[k].octet4 > 0 && addr_array[k].octet4 < 256){
valid_inputs = valid_inputs + 1;
}
/* Condition 2 (if the address is -1.-1.-1.-1) */
else if(addr_array[k].octet1 == -1 &&
addr_array[k].octet2 == -1 &&
addr_array[k].octet3 == -1 &&
addr_array[k].octet4 == -1){
return valid_inputs;
}
/* Condition 3 - if the address is invalid */
else if(addr_array[k].octet1 < 0 || addr_array[k].octet1 > 255 ||
addr_array[k].octet2 < 0 || addr_array[k].octet2 > 255 ||
addr_array[k].octet3 < 0 || addr_array[k].octet3 > 255 ||
addr_array[k].octet4 < 0 || addr_array[k].octet4 > 255){
printf("Invalid input.\n");
}
}
}
return valid_inputs;
}
I cant seem to figure out why my program doesn't do what i'm expecting it to do, any help for a beginner is greatly appreciated!
Try this :
typedef enum
{
IP_GET_OK,
IP_GET_ERROR,
IP_GET_END,
}IP_STATUS_t;
IP_STATUS_t getIP4(char *buff, int *ip4)
{
IP_STATUS_t result = IP_GET_ERROR;
if(buff && ip4 && fgets(buff, 32, stdin))
{
if(sscanf(buff, "%d.%d.%d.%d", &ip4[0], &ip4[1], &ip4[2], &ip4[3]) == 4)
{
int allminusone = 1;
for(size_t index = 0; index < 4; index++)
{
allminusone = allminusone && (ip4[index] == -1);
}
if(allminusone)
{
result = IP_GET_END;
}
else
{
result = IP_GET_OK;
for(size_t index = 0; index < 4; index++)
{
if(ip4[index] < 0 || ip4[index] > 0xff )
{
result = IP_GET_ERROR;
break;
}
}
}
}
}
return result;
}
You have an extra inner k loop. in which in the first case you only have one input but you still iterate over all the elements for which the behavior may be undefined.
int get_valid_ip_addrs(ipaddr_t addr_array[], int addr_array_len){
int valid_inputs = 0, i, k;
for(i = 0; i < addr_array_len; i++){
scanf("%d%c%d%c%d%c%d", &addr_array[i].octet1, &dot,
&addr_array[i].octet2, &dot,&addr_array[i].octet3, &dot, &addr_array[i].octet4);
/* Condition 1. (if the address is valid) */
if(addr_array[i].octet1 > 0 && addr_array[i].octet1 < 256 &&
addr_array[i].octet2 > 0 && addr_array[i].octet2 < 256 &&
addr_array[i].octet3 > 0 && addr_array[i].octet3 < 256 &&
addr_array[i].octet4 > 0 && addr_array[i].octet4 < 256){
valid_inputs = valid_inputs + 1;
}
/* Condition 2 (if the address is -1.-1.-1.-1) */
else if(addr_array[i].octet1 == -1 &&
addr_array[i].octet2 == -1 &&
addr_array[i].octet3 == -1 &&
addr_array[i].octet4 == -1){
return valid_inputs;
}
/* Condition 3 - if the address is invalid */
else if(addr_array[i].octet1 < 0 || addr_array[i].octet1 > 255 ||
addr_array[i].octet2 < 0 || addr_array[i].octet2 > 255 ||
addr_array[i].octet3 < 0 || addr_array[i].octet3 > 255 ||
addr_array[i].octet4 < 0 || addr_array[i].octet4 > 255){
printf("Invalid input.\n");
}
}
return valid_inputs;
}
My code
#include <stdlib.h>
#include <stdio.h>
int main()
{
int i=0;
int j=0;
size_t count=0;
float numbers[20][100];
float velocity[21][101];
char *line = NULL;
FILE *myFile;
myFile = fopen("vel.txt", "r");
if (myFile == NULL)
{
printf("Error Reading File\n");
exit (0);
}
while(i < 20 && getline(&line, &count, myFile)!=-1) {
int len = 0, pos = 0;
j = 0;
while(j < 100 && 1 == sscanf(line + pos, "%f%n", &numbers[i][j++], &len))
pos += len;
i++;
}
free(line);
fclose(myFile);
i=1;
for( j = 0; j < 101; j++ )
{
if( j == 1 )
{
velocity[i][j]=numbers[i][j];
}
else if ( j == 101 )
{
velocity[i][j]=numbers[i][j];
}
else
{
velocity[i][j]=(numbers[i][j-1]+numbers[i][j])/2;
}
}
for (j=0 ; j<101 ; j++) {
printf("\n%f", velocity[i][j]);
}
}
I need to calculate velocities for 21,101 two dimensional mesh.If i==1 ,that is my code above and works fine.The sam conditions apply if i==21.But for all other values (2 to 20) calculations are different.How should I change
if( i== from 2 to 20 &&j == 1 )
{
do something
}
else if (i== from to to 20 && j == 101 )
{
do something 2
}
else(means i goes from 2,20 j goes from 2,100)
{
do something 3
}
Do you want something like this: if(i >= 2 %% i <= 20)? Means: 2 <= i <= 20 or if i is greater or the same as 2 and i is lower or the same as 20 it is true.
If your example:
if(i >= 2 && i <= 20 && j == 1)
{
//do something
}
else if(i >= 2 && i <= 20 && j == 101)
{
//do something 2
}
else if(i >= 2 && i <= 20 && j >= 2 && j <= 100) //means i goes from 2,20 j goes from 2,100
{
//do something 3
}
or is there anything I missed?