Is my code correctly portraying the diagram? - c

What my function does, is it takes the values of the profit (function declared as fieldProfit) and the field score (function declared as fieldScore); and if both are above 10, then you earn a badge, hence, innerbadge = 1. BUT, there's also another condition that must be met, the field or (x, y) coordinates, have to fall in the area depicted as the shaded in box that has a hole in the middle. I've written the code for it, and I just wanted to make sure that my logic/syntax is correct! Any help is appreciated!
Here's my code:
int badgeInnerCircle(int x, int y) {
double fprofit, fscore;
int innerbadge;
if ((x >= 1 && x <= 20) && (y >= 1 && y <= 20)) {
if (((x == 7 || x == 8) && (y >= 7 && y <= 14)) || ((x == 13 || x == 14)
&& (y >= 7 && y <= 14)) || ((x >= 7 && x <= 14) && (y == 7 || y == 8))
|| ((x >= 7 && x <= 14) && (y == 13 || y == 14))) {
fprofit = fieldProfit(x, y);
fscore = fieldScore(x, y);
if (fprofit >= 10 && fscore >= 10) {
innerbadge = 1;
}
else {
innerbadge = 0;
}
}
}
else {
innerbadge = -1;
}
return innerbadge;
}

no, your code is not correct.
int innerbadge;
if (condition) {
if (condition) {
if (condition) {
innerbadge = 1;
}
else {
innerbadge = 0;
}
}
//else unidentified!
}
else {
innerbadge = -1;
}
you should change the initialisazion to "int innerbadge = 0;" or something approriate

Related

Function only returning return value it is not supposed to reach

I am working on a project for a programming class, where the goal is to verify a strength of a password based on different security levels. My problem is that with 2nd level, the:
Counter of numbers and special characters isn't working properly and isn't detecting numbers (it was working before I put it in its own function), but more importantly, the function only returns the value set in the very end. I have no idea what else to try.
int level2() {
while ((fgets(given_string, 100, stdin) != NULL)) {
for (int i = 0; given_string[i] != '\n'; i++) {
if (given_string[i] >= 'a' && given_string[i] <= 'z') {
lowerCaseLetterFound++;
} else if (given_string[i] >= 'A' && given_string[i] <= 'Z') {
upperCaseLetterFound++;
} else if (given_string[i] >= '0' && given_string[i] <= '9') {
numberFound++;
} else {
specialCharacterFound++;
}
}
}
printf("%d %d %d %d\n", lowerCaseLetterFound, upperCaseLetterFound, numberFound, specialCharacterFound);
if (param == 1 || param == 2) {
if (lowerCaseLetterFound >= 1 && upperCaseLetterFound >= 1) {
return 1;
} else {
return 0;
}
} else if (param == 3) {
if (((lowerCaseLetterFound >= 1 && upperCaseLetterFound >= 1) && numberFound >= 1) ||
((lowerCaseLetterFound >= 1 && upperCaseLetterFound >= 1) && specialCharacterFound >= 1)) {
return 1;
} else {
return 0;
}
} else if (param >= 4) {
if (lowerCaseLetterFound >= 1 && upperCaseLetterFound >= 1 && numberFound >= 1 &&
specialCharacterFound >= 1) {
return 1;
} else {
return 0;
}
}
return 0;
}
PS: This is my first time asking question here, and I am a programming newbie. Thanks for your help.
Update: Adding the whole code as I have it RN.
char given_string[100];
int lowerCaseLetterFound = 0;
int upperCaseLetterFound = 0;
int numberFound = 0;
int specialCharacterFound = 0;
int repeatedCharacter = 0;
int param;
int level;
int level1 () {
while ((fgets(given_string, 100, stdin) != NULL)) {
for (int i = 0; given_string[i] != '\n'; i++) {
if (given_string[i] >= 'a' && given_string[i] <= 'z') {
lowerCaseLetterFound++;
} else if (given_string[i] >= 'A' && given_string[i] <= 'Z') {
upperCaseLetterFound++;
}
}
}
if (lowerCaseLetterFound >= 1 && upperCaseLetterFound >= 1) {
return 1;
} else {
return 0;
}
}
int level2() {
while ((fgets(given_string, 100, stdin) != NULL)) {
for (int i = 0; given_string[i] != '\n'; i++) {
if (given_string[i] >= 'a' && given_string[i] <= 'z') {
lowerCaseLetterFound++;
} else if (given_string[i] >= 'A' && given_string[i] <= 'Z') {
upperCaseLetterFound++;
} else if (given_string[i] >= '0' && given_string[i] <= '9') {
numberFound++;
} else {
specialCharacterFound++;
}
}
}
printf("%d %d %d %d\n", lowerCaseLetterFound, upperCaseLetterFound, numberFound, specialCharacterFound);
if (param == 1 || param == 2) {
if (lowerCaseLetterFound >= 1 && upperCaseLetterFound >= 1) {
return 1;
} else {
return 0;
}
} else if (param == 3) {
if (((lowerCaseLetterFound >= 1 && upperCaseLetterFound >= 1) && numberFound >= 1) ||
((lowerCaseLetterFound >= 1 && upperCaseLetterFound >= 1) && specialCharacterFound >= 1)) {
return 1;
} else {
return 0;
}
} else if (param >= 4) {
if (lowerCaseLetterFound >= 1 && upperCaseLetterFound >= 1 && numberFound >= 1 &&
specialCharacterFound >= 1) {
return 1;
} else {
return 0;
}
}
return 0;
}
/*
int level3() {
while ((fgets(given_string, 100, stdin) != NULL)) {
for (int i = 0; given_string[i] != '\n'; i++) {
if (given_string[i] >= 'a' && given_string[i] <= 'z') {
lowerCaseLetterFound++;
} else if (given_string[i] >= 'A' && given_string[i] <= 'Z') {
upperCaseLetterFound++;
} else if (given_string[i] >= '0' && given_string[i] <= '9') {
numberFound++;
} else {
specialCharacterFound++;
}
}
}
}
*/
int main(int argc, const char *argv[]) {
//ukládám argumenty, prozatím pouze 2 ze 3
if (argc <= 1) {
printf("Not enough arguments provided. Please, provide LEVEL and PARAM arugments.\n");
} else if (argc >= 5) {
printf("Too many arguments provided.\n");
}
int level = atoi(argv[1]);
int param = atoi(argv[2]);
if (level <= 0 || level >= 5) {
printf("Level must be 1 through 4.\n");
}
if (param <= 0) {
printf("Parameter is not a full positive number.\n");
}
//vyhodnocování na základě zadaných parametrů - kontrola
//LEVEL = 1
if (level == 1) {
level1();
if (level1() == 1) {
printf("Password passed check 1.\n");
} else {
printf("Password did not pass check 1.\n");
}
}
if (level == 2) {
if (level1() == 1) {
if (level2() == 1) {
printf("Password did pass the check.\n");
}
} else {
printf("Password did not pass the check.\n");
}
if (level1() == 0) {
printf("Password did not pass the check.\n");
}
}
if (level == 3) {
}
}
Try to put your code in more than one function.
I think you can't print sth in your function. You should return just one thing you want to get from your function and then in another function, get input the first function's return.
It looks like the problem is that you’re re-defining your global variables in your main function. For example, when you do int param = atoi(argv[2]); in your main, param is scoped to your main. As soon as you leave your main function, you will be accessing the global param which has never been set.
You can either remove the variable type in your main so you are setting the global variables:
param = atoi(argv[2]);
Or get rid of the global variables and pass the ones created in main to any function that needs them.

Fruit disappears sometimes Snake in C

Im making a snake game in c, most things seem to be working right but I found a bug that I can't seem to fix. The fruit in my game sometimes just disappears for no reason. First, I thought that the problem was that I was generating it outside of the play-area but I put a restriction on that and the problem still exists.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <math.h>
#include <time.h>
int gameOver = 0, width = 20, height = 20, x, y, fruitX, fruitY, score;
int s;
int totalTail;
int tailX[100], tailY[100];
void Setup() {
srand((unsigned int)time(NULL));
x = height / 2;
y = width / 2;
score = 0;
do {
fruitX = rand() % height;
fruitY = rand() % width;
} while (fruitX <= 0 || fruitY <= 0 || fruitX == x || fruitY == y || fruitX > height || fruitY > width);
}
void Draw() {
system("cls");
for (int i = 0; i < height;i++) {
for (int j = 0; j < width; j++) {
if (i == 0 || j == 0 || i == width - 1 || j == height - 1) {
printf("#");
}
else if (i == x && j == y) { //generates head
printf("O");
}
else if (fruitX == i && fruitY == j) { //generates fruit
printf("F");
}
else {
int print = 0; //generates tail
for (int k = 0; k < totalTail; k++) {
if (tailX[k] == i && tailY[k] == j) {
printf("o");
print = 1;
}
}
if (print == 0) {
printf(" ");
}
}
}
printf("\n");
}
printf("Score: %d", score); //displays score
}
void Input() {
if (_kbhit()) {
switch (_getch()) {
case 'w':
s = 1;
break;
case 's':
s = 2;
break;
case 'a':
s = 3;
break;
case 'd':
s = 4;
break;
case 'x':
gameOver = 1;
break;
}
}
}
void Logic() {
int prevX = tailX[0];
int prevY = tailY[0];
int prev2X, prev2Y;
tailX[0] = x;
tailY[0] = y;
for (int i = 1; i < totalTail; i++)
{
prev2X = tailX[i];
prev2Y = tailY[i];
tailX[i] = prevX;
tailY[i] = prevY;
prevX = prev2X;
prevY = prev2Y;
}
switch (s) {
case 1:
x--;
break;
case 2:
x++;
break;
case 3:
y--;
break;
case 4:
y++;
break;
default:
break;
}
for (int i = 0; i < totalTail; i++) { //checks if the head and tail have collided
if (tailX[i] == x && tailY[i] == y) {
gameOver = 1;
}
}
if (x > 18 || y > 18 || x <= 0 || y <= 0) { //checks if player is out of the area
gameOver = 1;
}
if (x == fruitX && y == fruitY) { // adds point to score and regenerates fruit, I think the problem is here, not sure though
score += 1;
totalTail++;
do {
fruitX = rand() % height;
fruitY = rand() % width;
} while (fruitX <= 0 || fruitY <= 0 || fruitX == x || fruitY == y || fruitX > height || fruitY > width);
}
}
int main()
{
Setup();
while (gameOver != 1) {
Input();
Logic();
Draw();
Sleep(10);
}
return 0;
}

function in queen's Attack II returns wrong answer

I'm solving Queen's Attack II problem in Hackerrank. My idea is traverse through every obstacles to find the closest obstacle in each directions (left, right, up down and 4 diagons. My function only passed half of testcases. Then I search on the Internet and I found a similar solution but different in code structure, obsiously it passed all testcases.
My function:
int queensAttack(int n, int k, int r_q, int c_q, int obstacles_rows, int obstacles_columns, int **obstacles) {
long a[8];
a[0]=c_q-1;
a[1]=n-c_q;
a[2]=r_q-1;
a[3]=n-r_q;
a[4]=min(a[3], a[1]);
a[5]=min(a[2], a[1]);
a[6]=min(a[2], a[0]);
a[7]=min(a[3], a[0]);
int x=obstacles[i][1], y=obstacles[i][0];
for (int i=0; i<obstacles_rows; i++) {
if(y==r_q && x<c_q) a[0]=min(a[0], c_q-x-1);
else if(y==r_q && x>c_q) a[1]=min(a[1], x-c_q-1);
else if(x==c_q && y<r_q) a[2]=min(a[2], r_q-y-1);
else if(x==c_q && y>r_q) a[3]=min(a[3], y-r_q-1);
else if(y-r_q==x-c_q) a[4]=min(a[4], y-r_q-1);
else if(r_q-y==x-c_q) a[5]=min(a[5], r_q-y-1);
else if(r_q-y==c_q-x) a[6]=min(a[6], r_q-y-1);
else if(y-r_q==c_q-x) a[7]=min(a[7], y-r_q-1);
}
int result=0;
for (int i=0; i<8; i++) {
result+=a[i];
}
return result;
}
Their fucntion:
int queensAttack(int n, int k, int r_q, int c_q, int obstacles_rows, int obstacles_columns, int **obstacles) {
a[0] = c_q -1 ;
a[1] = n -r_q;
a[2] = n -c_q;
a[3] = r_q -1;
a[4] = min(a[0],a[1]);
a[5] = min(a[1],a[2]);
a[6] = min(a[2],a[3]);
a[7] = min(a[3],a[0]);
int x,y;
while (--k >= 0)
{
y = obstacles[k][0] - r_q;
x = obstacles[k][1] - c_q;
if (x == 0)
{
if (y > 0)
{
a[1] = min(a[1], y - 1);
}
else
{
a[3] = min(a[3], -(y + 1));
}
}
else if (y == 0)
{
if (x > 0)
{
a[2] = min(a[2], x - 1);
}
else
{
a[0] = min(a[0], -(x + 1));
}
}
else
{
float m = (float)y / x;
if (m == 1.0)
{
if (x > 0)
{
a[5] = min(a[5], x - 1);
}
else
{
a[7] = min(a[7], -y - 1);
}
}
else if (m == -1.0)
{
if (x > 0)
{
a[6] = min(a[6], x - 1);
}
else
{
a[4] = min(a[4], y - 1);
}
}
}
}
int result=0;
for (int i=0; i<8; i++) {
result+=a[i];
}
return result;
}
Where am I wrong?
Any help would be appreciated.
Some issues:
1) This line should not occur before the loop, but as a first statement inside the loop body:
int x=obstacles[i][1], y=obstacles[i][0];
2) The second half of the loop has conditions which cause a problem. For instance when y-r_q==x-c_q is true, then also r_q-y==c_q-x is true, and vice versa. So this expression tells you whether an obstacle is on a queen's diagonal, but not on which side of the queen. As a consequence, the argument you pass to the min function could be negative, and this should never happen. You need an additional condition, much like you have in the first half of that if-chain. So change the second half to this:
else if(y-r_q==x-c_q && y>r_q) a[4]=min(a[4], y-r_q-1);
else if(r_q-y==x-c_q && y<r_q) a[5]=min(a[5], r_q-y-1);
else if(r_q-y==c_q-x && y<r_q) a[6]=min(a[6], r_q-y-1);
else if(y-r_q==c_q-x && y>r_q) a[7]=min(a[7], y-r_q-1);
It took me some time to figure out this one. My first code couldn't get through the time execution time limits. So, some math comes handy. First I calculate the total number of moves as there are no obstacles, just using math. If there are no obstacles that is the answer.
If there are obstacles, loop through them, using boolean to close each direction that is found and using math calculate the non moves. But I still had error, because the obstacles had to be sorted from the queen to the farthest obstacles position.
Here is my code in Java.
int vertHor = n - 1;
int d1 = Math.min(n - c_q, n - r_q) + Math.min(r_q - 1, c_q - 1);
int d2 = Math.min(c_q - 1, n - r_q) + Math.min(n - c_q, r_q - 1);
int total = vertHor * 2 + d1 + d2;
if (k == 0) {
return total;
}
boolean u = false;
boolean d = false;
boolean l = false;
boolean r = false;
boolean ul = false;
boolean ur = false;
boolean dl = false;
boolean dr = false;
Arrays.sort(obstacles, (int[] x, int[] y) -> Math.min(Math.abs(x[0] - r_q), Math.abs(x[1] - c_q))
- Math.min(Math.abs(y[0] - r_q), Math.abs(y[1] - c_q)));
for (int[] obs : obstacles) {
int oRow = obs[0];
int oCol = obs[1];
if (oRow == r_q) {
if (oCol < c_q && !l) {
total -= oCol;
l = true;
} else if (!r) {
total -= n - oCol + 1;
r = true;
}
} else if (oCol == c_q) {
if (oRow < r_q && !d) {
total -= oRow;
d = true;
} else if (!u) {
total -= n - oRow + 1;
u = true;
}
} else if (Math.abs(c_q - oCol) == Math.abs(r_q - oRow)) {//oCol != c_q && oRow != r_q) {
if (oCol < c_q && oRow > r_q && !ul) {
total -= Math.min(n - oRow + 1, oCol);
ul = true;
} else if (oCol < c_q && oRow < r_q && !dl) {
total -= Math.min(oRow, oCol);
dl = true;
} else if (oCol > c_q && oRow < r_q && !dr) {
total -= Math.min(oRow, n - oCol + 1);
dr = true;
} else if (oCol > c_q && oRow > r_q && !ur) {
total -= Math.min(n - oRow, n - oCol) + 1;
ur = true;
}
}
if (u && d && l && r && ul && ur && dl && dr) {
break;
}
}
return total;

Counting work days between two dates in C

I am writing a code in C with two functions.
The first (WorkDay) takes a date and says if it is a working day (return 1) or not (return 0). I think the first function is OK, although it could be better, but it is working. It includes weekends and public holidays in my country.
The problem comes with the second function (CountWorkDays). It should take two dates and say if they are correct (return 1) and in that case also say how many working days is among them, including the entered dates (cnt=). If the dates aren't correct (first is bigger than second etc.), there is return 0. I've tried to make a helping function next_day(), but I am pretty sure it is wrong. Can you help me with the second function please?
I cannot use <time.h> and I put there some asserts, which I am testing the function with.
#include <stdio.h>
#include <math.h>
#include <assert.h>
int WorkDay ( int y, int m, int d )
{
int h, day;
h= (d + floor(((m+1)*26)/10) + y + floor(y/4) + 6*floor(y/100) + floor(y/400));
day=h%7;
if ((y%4!=0) && m==2 && d==29)
return 0;
else if (((y%4==0 || y%400==0) && (y%100!=0 || y%4000!=0)) && m==2 && d==29)
{
if (day==2 || day==3 || day==4 || day==1 || day==0)
return 1;
else
return 0;
}
else if ((d==1 && m==1) || (d==1 && m==5) || (d==8 && m==5) || (d==5 && m==7) || (d==6 && m==7) || (d==28 && m==9) || (d==28 && m==10) || (d==17 && m==11) || (d==24 && m==12) || (d==25 && m==12) || (d==26 && m==12) || day==0 || day==1 || (m==1 && (d>31 || d<1)) || (m==2 && (d>29 || d<1)) || (m==3 && (d>31 || d<1)) || (m==4 && (d>30 || d<1)) || (m==5 && (d>31 || d<1)) || (m==6 && (d>30 || d<1)) || (m==7 && (d>31 || d<1)) || (m==8 && (d>31 || d<1)) || (m==9 && (d>30 || d<1)) || (m==10 && (d>31 || d<1)) || (m==11 && (d>30 || d<1)) || (m==12 && (d>31 || d<1)) || y<2000 || m>12 || m<1)
return 0;
else if (day==2 || day==3 || day==4 || day==5 || day==6)
return 1;
else
return 0;
}
int next_day()
{
int y1, m1, d1;
static int days_in_month[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
unsigned short day_counter;
d1 += 1; day_counter++;
if (d1 > days_in_month[m1])
{
d1 = 1;
m1 += 1;
if (m1 > 12)
{
m1 = 1;
y1 += 1;
if (((y1%4==0 || y1%400==0) && (y1%100!=0 || y1%4000!=0)))
{
days_in_month[2] = 29;
}
else
{
days_in_month[2] = 28;
}
}
}
return 0;
}
int CountWorkDays ( int y1, int m1, int d1,
int y2, int m2, int d2,
int * cnt )
{
int i,x;
if ( (m1==1 && (d1>31 || d1<1)) || (m1==2 && (d1>29 || d1<1)) || (m1==3 && (d1>31 || d1<1)) || (m1==4 && (d1>30 || d1<1)) || (m1==5 && (d1>31 || d1<1)) || (m1==6 && (d1>30 || d1<1)) || (m1==7 && (d1>31 || d1<1)) || (m1==8 && (d1>31 || d1<1)) || (m1==9 && (d1>30 || d1<1)) || (m1==10 && (d1>31 || d1<1)) || (m1==11 && (d1>30 || d1<1)) || (m1==12 && (d1>31 || d1<1)) || y1<2000 || m1>12 || m1<1 ||(m2==1 && (d2>31 || d2<1)) || (m2==2 && (d2>29 || d2<1)) || (m2==3 && (d2>31 || d2<1)) || (m2==4 && (d2>30 || d2<1)) || (m2==5 && (d2>31 || d2<1)) || (m2==6 && (d2>30 || d2<1)) || (m2==7 && (d2>31 || d2<1)) || (m2==8 && (d2>31 || d2<1)) || (m2==9 && (d2>30 || d2<1)) || (m2==10 && (d2>31 || d2<1)) || (m2==11 && (d2>30 || d2<1)) || (m2==12 && (d2>31 || d2<1)) || y2<2000 || m2>12 || m2<1 || y2>y1 || (y1==y2 && m2>m1) || (y1==y2 && m1==m2 && d2>d1) )
return 0;
else
{
while (y1!=y2 && m1!=m2 && d1!=d2)
{
while (next_day())
{
if (WorkDay( y1, m1, d1 ) == 1)
i=0;
x=i++;
}
}
*cnt=x;
return 1;
}
}
int main ( int argc, char * argv [] )
{
int cnt;
assert ( WorkDay ( 2016, 11, 11 ) );
assert ( ! WorkDay ( 2016, 11, 12 ) );
assert ( CountWorkDays ( 2016, 11, 1,
2016, 11, 30, &cnt ) == 1
&& cnt == 21 );
assert ( CountWorkDays ( 2001, 1, 1,
2015, 2, 29, &cnt ) == 0 );
return 0;
}
The problem is in next_day() and CountWorkDays().
next_day() is using local variables d1, m1 and y1. It is calculating next day of some random day.
In CountWorkDays(), you are not incrementing d1, m1, y1.
Solution:
Modify next_day() to receive a day as input and return next day as output.
int next_day(int *d, int *m, int *y)
{
/* Use current day to start. */
int y1 = *y;
int m1 = *m;
int d1 = *d;
/* Your code to find next day. Remove day_counter here as it is unnecessary.*/
/* Return next day. */
*y = y1;
*m = m1;
*d = d1;
return 0;
}
In CountWorkDays() call next_day with d1, m1, y1 as below.
else
{
while (1)
{
if (y1!=y2 && m1!=m2 && d1!=d2) //Check if end day is reached.
{
if (WorkDay( y1, m1, d1 ) == 1)
x++; //At the beginning initialize x to 0.
}
else
{
break;
}
next_day(&d1, &m1, &y1); //Get the next day.
}
}
int CountWorkDays(int y1, int m1, int d1, int y2, int m2, int d2, int * cnt)
{
int i, x;
if( (m1 == 1 && (d1>31 || d1<1)) || (m1 == 2 && (d1>29 || d1<1)) || (m1 == 3 && (d1>31 || d1<1)) || (m1 == 4 && (d1>30 || d1<1)) || (m1 == 5 && (d1>31 || d1<1)) || (m1 == 6 && (d1>30 || d1<1)) || (m1 == 7 && (d1>31 || d1<1)) || (m1 == 8 && (d1>31 || d1<1)) || (m1 == 9 && (d1>30 || d1<1)) || (m1 == 10 && (d1>31 || d1<1)) || (m1 == 11 && (d1>30 || d1<1)) || (m1 == 12 && (d1>31 || d1<1)) || y1<2000 || m1>12 || m1<1 ||
(m2 == 1 && (d2>31 || d2<1)) || (m2 == 2 && (d2>29 || d2<1)) || (m2 == 3 && (d2>31 || d2<1)) || (m2 == 4 && (d2>30 || d2<1)) || (m2 == 5 && (d2>31 || d2<1)) || (m2 == 6 && (d2>30 || d2<1)) || (m2 == 7 && (d2>31 || d2<1)) || (m2 == 8 && (d2>31 || d2<1)) || (m2 == 9 && (d2>30 || d2<1)) || (m2 == 10 && (d2>31 || d2<1)) || (m2 == 11 && (d2>30 || d2<1)) || (m2 == 12 && (d2>31 || d2<1)) || y2<2000 || m2>12 || m2<1 ||
y2>y1 || (y1 == y2 && m2>m1) || (y1 == y2 && m1 == m2 && d2>d1))
...
x++;
Your logic is wrong and redundant. You need to check only once if day is less than 1. You are checking at least 20 times. Then you check it again another 20 times in another function. You repeat that for d2. This makes your code unreadable and prone to errors.
Also you are not initializing variables. The starting value of x is undefined. Put int x = 0; and i = 0;
Later you have:
i=0;
x=i++;
You could rewrite this as x = 1. But you probably mean to write x++
Here it seems you are checking for holidays:
else if((
d == 1 && m == 1) ||
(d == 1 && m == 5) ||
(d == 8 && m == 5) ||
(d == 5 && m == 7) ||
(d == 6 && m == 7) ||
(d == 28 && m == 9) ||
(d == 28 && m == 10) ||
(d == 17 && m == 11) ||
(d == 24 && m == 12) ||
(d == 25 && m == 12) ||
(d == 26 && m == 12) ||
This type of coding is not wrong, but it's not practical either. I would put the holidays in a structure:
struct holidays_t
{
int day, month;
};
struct holidays_t holidays[] = {
{ 1 , 1 },
{ 1 , 5 },
...
};
Then loop through holidays array to see if the dates match. If you have not learned structures yet, then put the days and months in two different arrays. Example:
int holiday_days[]={1,1,...};
int holiday_months[]={1,5,...};
Your formula for weekday is wrong. You need to fix that.
#include <stdio.h>
#include <math.h>
int is_leap_year(int y)
{
return (y % 4) == 0 && y % 100 != 0 || (y % 400 == 0 && y != 4000);
}
int get_days_in_month(int year, int month)
{
const int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if(month >= 1 && month <= 12)
{
int days = days_in_month[month - 1];
if(month == 2 && is_leap_year(year))
days++;
return days;
}
return 0;
}
int is_date_valid(int year, int month, int day)
{
if(get_days_in_month(year, month) == 0) return 0;
return day >= 1 && day <= get_days_in_month(year, month);
}
//this is wrong: ***************************************************
int get_weekday(int y, int m, int d)
{
int h = (d + floor(((m + 1) * 26) / 10) + y + floor(y / 4) + 6 * floor(y / 100) + floor(y / 400));
int weekday = h % 7;
return weekday;
}
struct holidays_t
{
int day, month;
};
int is_holiday(int m, int d)
{
const struct holidays_t holidays[] = {
{ 1 , 1 },
{ 1 , 5 },
{ 8 , 5 },
{ 5 , 7 },
{ 6 , 7 },
{ 28, 9 },
{ 28, 10 },
{ 17, 11 },
{ 24, 12 },
{ 25, 12 },
{ 26, 12 },
};
int count = sizeof(holidays) / sizeof(holidays[0]);
int i;
for(i = 0; i < count; i++)
if(holidays[i].month == m && holidays[i].day == d)
return 1;
return 0;
}
int CountWorkDays(int y1, int m1, int d1, int y2, int m2, int d2, int *ptr)
{
int count = 0;
*ptr = 0;
if(!is_date_valid(y1, m1, d1)) return 0;
if(!is_date_valid(y2, m2, d2)) return 0;
int y, m, d;
for(y = y1; y <= y2; y++)
{
int month_start = 1;
int month_end = 12;
if(y == y1) month_start = m1;
if(y == y2) month_end = m2;
for(m = month_start; m <= month_end; m++)
{
int day_start = 1;
int day_end = get_days_in_month(y, m);
if(y == y1 && m == m1) day_start = d1;
if(y == y2 && m == m2) day_end = d2;
for(d = day_start; d <= day_end; d++)
{
int test = 0;
if(is_holiday(m, d))
{
test = 1;
printf("holiday %d %d %d\n", y, m, d);
}
int weekday = get_weekday(y, m, d);
if(weekday == 0 || weekday == 6)
{
test = 1;
printf("weekend %d %d %d %s\n", y, m, d, (weekday == 0) ? "sunday" : "staurday");
}
if(!test)
{
count++;
}
}
}
}
*ptr = count;
//return success
return 1;
}
int main()
{
int count = 0;
CountWorkDays(2016, 1, 1, 2016, 12, 31, &count);
printf("count %d\n", count);
return 0;
}

Converting 2D array of numbers into chars

I am making a maze using Depth-First search algorithm as a school project. The maze is working pretty much as I want but I have a little problem. I have to use # as a wall and . as a path when printing the maze but I used 0 as a wall and 1 as a path at first thinking that it is gonna be easy to change it later but I was wrong. How can I change 0 and 1 into # and .?
Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void nahodne_suradnice(int *r, int *s, int n)
{
srand(time(NULL));
*r = ((rand() % n) - 1) + 2;
if (*r == 1 || *r == n)
{
*s = (rand() % n) + 2;
}
else
{
if (rand() % 2 == 1)
*s = 1;
else
*s = n;
}
}
int main()
{
int i, j, n, r, s,smer,posledny_smer[1500];
int maze[500][500];
scanf_s("%d", &n);
if (n < 10 || n > 100)
{
return 0;
}
//vynulovanie pola/bludiska
for (i = 1; i < n + 1; i++)
{
for (j = 1; j < n + 1; j++)
{
maze[i][j] = 0;
}
}
//nahodny vyber zaciatku bludiska
nahodne_suradnice(&r, &s, n);
//generovanie bludiska
j = 0;
maze[r][s] = 2;
for (i = 0 ;; i++)
{
//backtracking
if ((maze[r - 1][s] == 1 || maze[r - 2][s] == 1 || r - 2 <=1 || s==n || s==1) && (maze[r][s + 1] == 1 || maze[r][s + 2] == 1 || s + 2 >= n || r == n || r==1) && (maze[r + 1][s] == 1 || maze[r + 2][s] == 1 || r + 2 >= n || s == n || s==1) && (maze[r][s - 1] == 1 || maze[r][s - 2] == 1 || s - 2 <=1 || r == n || r==1))
{
if (posledny_smer[j-1] == 1)
if (maze[r + 1][s] == 1 && maze[r + 2][s] == 1)
{
r += 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (posledny_smer[j-1] == 2)
if (maze[r][s - 1] == 1 && maze[r][s - 2] == 1)
{
s -= 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (posledny_smer[j-1] == 3)
if (maze[r - 1][s] == 1 && maze[r - 2][s] == 1)
{
r -= 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (posledny_smer[j-1] == 4)
if (maze[r][s + 1] == 1 && maze[r][s + 2] == 1)
{
s += 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (j == 0)
{
if (r == n)
{
nahodne_suradnice(&r, &s,n);
maze[1][s] = 3;
maze[2][s] = 3;
}
if (r == 1)
{
nahodne_suradnice(&r, &s, n);
maze[n][s] = 3;
maze[n - 1][s] = 3;
}
if (s == n-2)
{
nahodne_suradnice(&r, &s, n);
maze[r][1] = 3;
maze[r][2] = 3;
}
if (s == 3)
{
nahodne_suradnice(&r, &s, n);
maze[r][n] = 3;
maze[r][n-1] = 3;
}
break;
}
}
//buranie stien
smer = (rand() % 4) + 1;
if (smer == 1)
{
if (r - 2 >1 && s<n && s>1)
{
if (maze[r - 1][s] == 1 || maze[r - 2][s] == 1)
continue;
maze[r - 1][s] = 1;
maze[r - 2][s] = 1;
r -= 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
if (smer == 2)
{
if (s + 2 < n && r < n && r>1)
{
if (maze[r][s+1] == 1 || maze[r][s+2] == 1)
continue;
maze[r][s + 1] = 1;
maze[r][s + 2] = 1;
s += 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
if (smer == 3)
{
if (r + 2 < n && s < n && s>1)
{
if (maze[r + 1][s] == 1 || maze[r + 2][s] == 1)
continue;
maze[r + 1][s] = 1;
maze[r + 2][s] = 1;
r += 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
if (smer == 4)
{
if (s - 2 >1 && r < n && r>1)
{
if (maze[r][s-1] == 1 || maze[r][s-2] == 1)
continue;
maze[r][s - 1] = 1;
maze[r][s - 2] = 1;
s -= 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
}
//vypis bludiska
for (i = 1; i < n + 1; i++)
{
for (j = 1; j < n + 1; j++)
{
printf("%d", maze[i][j]);
}
printf("\n");
}
system("PAUSE");
return 0;
}
`
Thanks.
Change the definition of maze to:
char maze[500][500]
and change all references to use char instead of int. Then return '#' and '.' instead of 0 and 1.
You can change from 0 and 1 to # and . (or any other representation) when printing. For instance you can change:
printf("%d", maze[i][j]);
to
switch(maze[i][j]) {
case 0:
printf("#");
break;
case 1:
printf(".");
break;
default:
printf("X"); /* in case you have some value other than 0 or 1 in the maze */
}
If you do it like this, you can change which letters you want to display the maze as without changing other parts of your code.

Resources