Check if the next move is check-mate - c++

I am trying to check if the next move of the knight will threaten both kind and queen at the same time, if there's such position it will output YES and the position, otherwise it will be NO.
The input will contain only K for king, Q for queen, and N for knight, and they won't be repeated more than once.
Sample input :
........
........
........
...K....
....Q...
........
N.......
........
this input for example indicates that the knight is 2A , Queen is in 4E ,King is in 5D .
here's my code :
#include <cmath>
#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <ctype.h>
#include <fstream>
#include <cstddef>
#include <sstream>
#include<string.h>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
int main ()
{
string temp ;
bool flag1 = false , flag2 = false ;
int row1 = 0 , col1 = 0 , row2 = 0 , col2 = 0 ;
int ik=0 , jk=0 , iq=0 , jq=0 , in=0 , jn=0 , i = 8 ;
while ( std::getline (std::cin,temp) )
{
for (int j = 0 ; j<=7 ; j++)
{
if(temp[j] == 'K')
{ ik = i ; jk = j+1 ; }
else if(temp[j] == 'Q')
{ iq = i ; jq = j+1 ; }
else if(temp[j] == 'N')
{ in = i ; jn = j+1 ; }
}
i-- ;
}
// j for columns , i for rows
// if jk = 1 means A , =2 means B , and so on
int threatk[8][2] = {0} , threatq[8][2]= {0} , expn[8][2] = {0} ;
// columns first ( position 0 )
// rows second ( position 1 )
threatk[0][0] = jk+1 ;
threatk[0][1] = ik+2 ;
threatk[1][0] = jk+1 ;
threatk[1][1] = ik-2 ;
threatk[2][0] = jk+2 ;
threatk[2][1] = ik+1 ;
threatk[3][0] = jk+2 ;
threatk[3][1] = ik-1 ;
threatk[4][0] = jk-1 ;
threatk[4][1] = ik+2 ;
threatk[5][0] = jk-1 ;
threatk[5][1] = ik-2 ;
threatk[6][0] = jk-2 ;
threatk[6][1] = ik+1 ;
threatk[7][0] = jk-2 ;
threatk[7][1] = ik-1 ;
threatq[0][0] = jq+1 ;
threatq[0][1] = iq+2 ;
threatq[1][0] = jq+1 ;
threatq[1][1] = iq-2 ;
threatq[2][0] = jq+2 ;
threatq[2][1] = iq+1 ;
threatq[3][0] = jq+2 ;
threatq[3][1] = iq-1 ;
threatq[4][0] = jq-1 ;
threatq[4][1] = iq+2 ;
threatq[5][0] = jq-1 ;
threatq[5][1] = iq-2 ;
threatq[6][0] = jq-2 ;
threatq[6][1] = iq+1 ;
threatq[7][0] = jq-2 ;
threatq[7][1] = iq-1 ;
expn[0][0] = jn+1 ;
expn[0][1] = in+2 ;
expn[1][0] = jn+1 ;
expn[1][1] = in-2 ;
expn[2][0] = jn+2 ;
expn[2][1] = in+1 ;
expn[3][0] = jn+2 ;
expn[3][1] = in-1 ;
expn[4][0] = jn-1 ;
expn[4][1] = in+2 ;
expn[5][0] = jn-1 ;
expn[5][1] = in-2 ;
expn[6][0] = jn-2 ;
expn[6][1] = in+1 ;
expn[7][0] = jn-2 ;
expn[7][1] = in-1 ;
for ( int a = 0 ; a<=7 ; a++)
{
for ( int b=0 ; b<=7 ; b++)
{
if ( ( expn[a][0] == threatk[b][0] && expn[a][1] == threatk[b][1] ) )
{ flag1 = true ; col1 = expn[a][0] ; row1 = expn[a][1] ; }
}
}
for ( int a = 0 ; a<=7 ; a++)
{
for ( int b=0 ; b<=7 ; b++)
{
if ( ( expn[a][0] == threatq[b][0] && expn[a][1] == threatq[b][1] ) )
{ flag2 = true ; col2 = expn[a][0] ; row2 = expn[a][1] ; }
}
}
if ( ( flag1 && flag2 ) && ( col1 >= 1 && col1 <= 8 && row1 >= 1 && row1 <= 8)
&& ( col2 >= 1 && col2 <= 8 && row2 >= 1 && row2 <= 8)
&& ( col1 = col2 && row1 = row2) )
{ string out = "" ;
if ( col1 == 1)out = "A" ;
else if ( col1 == 2) out = "B" ;
else if ( col1 == 3) out = "C" ;
else if ( col1 == 4) out = "D" ;
else if ( col1 == 5) out = "E" ;
else if ( col1 == 6) out = "F" ;
else if ( col1 == 7) out = "G" ;
else if ( col1 == 8) out = "H" ;
cout<<"YES"<<" "<<row1<<out ;
}
else cout<<"NO" ;} '
my approach is to get the threat positions for the king and the queen from a knight , and compare with it with the next possible move for the knight
it's working fine but it fails at some tests that am not aware of i just get to know if it passed all the tests or not .
what do you think is wrong ?

When you are designing code, make sure that all parts are easily testable. Design functions that do one clear thing and can be reused easily. Afterwards test them well so you can figure out what part of your code is wrong.
It is very hard to review your code and figure out what could potentially be wrong. I wrote a solution in Python that should pass all possible edge cases and I will share it here. Parsing input and output is not part of it.
N = 8
def generateThreat(y, x):
threats = []
candidate = (y+2, x+1)
if (candidate[0] < N-1 and candidate[1] < N-1):
threats.append(candidate)
candidate = (y+2, x-1)
if (candidate[0] < N-1 and candidate[1] >= 0):
threats.append(candidate)
candidate = (y-2, x+1)
if (candidate[0] >= 0 and candidate[1] < N-1):
threats.append(candidate)
candidate = (y-2, x-1)
if (candidate[0] >= 0 and candidate[1] >= 0):
threats.append(candidate)
candidate = (y+1, x+2)
if (candidate[0] < N-1 and candidate[1] < N-1):
threats.append(candidate)
candidate = (y+1, x-2)
if (candidate[0] < N-1 and candidate[1] >= 0):
threats.append(candidate)
candidate = (y-1, x+2)
if (candidate[0] >= 0 and candidate[1] < N-1):
threats.append(candidate)
candidate = (y-1, x-2)
if (candidate[0] >= 0 and candidate[1] >= 0):
threats.append(candidate)
return threats
def generateAllThreatsFromCurrent(y, x):
all_threats = set()
for next_step in generateThreat(y, x):
all_threats.update(generateThreat(next_step[0], next_step[1]))
return all_threats
def isMatePossible(king, queen, knight):
y, x = knight
all_threats = generateAllThreatsFromCurrent(y, x)
if king in all_threats and queen in all_threads:
return True
return False

Related

How to assign alternative values to a variable relative to another variable in Ox (a bit similar to C++)

I was simulating some data with Ox (syntax similar to C, C++ and Java) and I was stuck in my assignation part. Let's say, I have this function simulating my data, g_mY:
decl g_mX, g_mY;
simuldata(const ct) // ct : number of observations
{
decl mx = ranbinomial(ct, 1, 1, 0.40)~ 100*ranu(ct, 1);
decl veps = rann(ct, 1);
decl vp = < .0485434;-.006764 ; -.0187657; -1.106632 ; .3647326 ; 1.11204 >;
g_mX = mx[][0:1] ; // regressors: Gender, Age.
decl cut1 = vp[2], cut2 = vp[3], cut3 = vp[4], cut4 = vp[5] ;
decl Yt = g_mX*vp[:1] + veps ; // latent variable
What I want to do is to create g_mY by using the cutpoints (cut...) and latent variable (Yt) defined above, and to compute alternative values to g_mY. More like this :
g_mY = new matrix[rows(g_mX)][1] ; // dependent variable
for(decl i = 0; i < rows(g_mX); ++i)
{
if(Yt[i] < cut1)
{
g_mY[i] = < a number between 1 and 100, but != to a multiple of 5 >
}
else if(Yt[i]> cut1 .&& Yt[i]<= cut2)
{
g_mY[i] = 5 || g_mY[i] = 15 || g_mY[i] = 35 || g_mY[i] = 45 || g_mY[i] = 55 ||
g_mY[i] = 65 || g_mY[i] = 85 || g_mY[i] = 95 ;
// one of these multiples of 5 that are not multiples of 10
}
else if(Yt[i]> cut2 .&& Yt[i] <= cut3)
{
g_mY[i] = 10 || g_mY[i] = 20 || g_mY[i] = 30 || g_mY[i] = 40 ||
g_mY[i] = 60 || g_mY[i] = 70 || g_mY[i] = 80 || g_mY[i] = 90 ;
// one of these multiples of 10
}
else if(Yt[i] > cut3 .&& Yt[i] <= cut4)
{
g_mY[i] = 25 || g_mY[i] = 75 ; //either 25 or 75
}
else if(Yt[i] > cut4)
{
g_mY[i] = 50 || g_mY[i] = 100; //either 50 or 100
}
}
return 1
}
When I print g_mY, I only have zeros. How can I achieve this successfully?
Many thanks.
If I understood correctly your question, the following code should answer it. It shows several ways to randomly pick a variable : with a loop (#1), with the function ranindex (#2) or with the ternary operator (#3).
#include <oxstd.oxh>
#include <oxprob.h>
decl g_mX, g_mY;
simuldata(const ct) { // ct : number of observations
decl mx = ranbinomial(ct, 1, 1, 0.40)~ 100 * ranu(ct, 1);
decl veps = rann(ct, 1);
decl vp = < .0485434; -.006764 ; -.0187657; -1.106632 ; .3647326 ; 1.11204 >;
g_mX = mx[][0:1] ; // regressors: Gender, Age.
decl cut1 = vp[2], cut2 = vp[3], cut3 = vp[4], cut4 = vp[5] ;
decl Yt = g_mX * vp[:1] + veps ; // latent variable
g_mY = new matrix[rows(g_mX)][1] ; // dependent variable
for (decl i = 0; i < rows(g_mX); ++i) {
if (Yt[i] < cut1) {
decl temp ;
do { //#1
temp = 1 + ranindex(1, 100);
} while (imod(temp, 5) == 0); // a number between 1 and 100, but != to a multiple of 5
g_mY[i] = temp ;
} else if (Yt[i] > cut1 .&& Yt[i] <= cut2) {
decl ar = < 5; 15; 35; 45; 55; 65; 85; 95 >;
g_mY[i] = ar[ranindex(1, rows(ar))] ;//#2
} else if (Yt[i] > cut2 .&& Yt[i] <= cut3) {
decl ar = range(10,90,10)'; // == < 10; 20; 30; 40; 60; 70; 80; 90 >;
g_mY[i] = ar[ranindex(1, rows(ar))] ;//#2
} else if (Yt[i] > cut3 .&& Yt[i] <= cut4) {
g_mY[i] = ranu(1, 1) > 0.5 ? 25 : 75 ;//#3
} else if (Yt[i] > cut4) {
g_mY[i] = ranu(1, 1) > 0.5 ? 50 : 100 ;//#3
}
}
return 1;
}
main() {
simuldata(100);
println(g_mY);
}

Problem 19 project Euler Counting Sundays

This is my code for Project Euler #19. The answer for the problem is 171 but my code is producing 172. Please can anyone figure out the problem in the code below.
#include <bits/stdc++.h>
using namespace std ;
typedef long long LL ;
int ordYear[12] = {31,28,31,30,31,30,31,31,30,31,30,31} ;
int leapYear[12] = {31,29,31,30,31,30,31,31,30,31,30,31} ;
int main(){
int leapFlag = 0 ;
LL ans = 0 ;
int dayonfirst = 2 ; // since it was tuesday on 1 Jan 1901
for (int i=1901 ; i<=2000 ; i++){
if ( (i%4==0 && i%100!=0) || (i%100==0 && i%400==0) )
leapFlag = 1 ;
for (int i=0 ; i<12 ; i++){
int oddDays ;
if (leapFlag == 1)
oddDays = leapYear[i]%7 ;
else
oddDays = ordYear[i]%7 ;
dayonfirst += oddDays ;
if(dayonfirst == 7)
ans++ ;
else if (dayonfirst > 7)
dayonfirst = dayonfirst%7 ;
}
}
cout << ans << endl ;
return 0 ;
}
You need else statement to assign leapFlag = 0 when it not a leap year:
if ( (i%4==0 && i%100!=0) || (i%100==0 && i%400==0) )
leapFlag = 1;
else
leapFlag = 0;

bool function taking array as argument

I have a bool function used in a test to see whether or not two objects are neighbours. If they are, a previous function InitFaceCheck() will write either 0 or 1 into a global array N[16] (16 cases to check for).
for (n = 0; n < count; n++ )
{
int l = 0;
for (m = 0; m < count; m++ )
{ InitFaceCheck(tet[n], tet_copy[m]); //
if( (tet[n].ID != tet_copy[m].ID) && (isNeighbour(N) == 1) ) // if T's
{
for(j = 0; j < 16; j++){
printf("N[%i] = %i ",j, N[j]);
}
printf("\n");
tet[n].next[l] = tet_copy[m].ID; // mark them as neighbours
l++; // neighbour counter
};
}
}
The InitFaceCheck() function evaluates if any the two tetrahedra share any of their faces (i.e. they share a face if the share the x,y,z coords of the three vertices that constitute that face) in total there are 16 tests, only 2 are included here:
void InitFaceCheck (TETRA a, TETRA b)
{
/*... Setup of bool variables to be used in CheckFace () ....
a bit tedious due to having .x .y .z components but it is solid for our purposes ... */
bool f11 = ( (a.vert[0].x == b.vert[0].x) && (a.vert[0].y == b.vert[0].y) && (a.vert[0].z == b.vert[0].z) &&
(a.vert[1].x == b.vert[1].x) && (a.vert[1].y == b.vert[1].y) && (a.vert[1].z == b.vert[1].z) &&
(a.vert[2].x == b.vert[2].x) && (a.vert[2].y == b.vert[2].y) && (a.vert[2].z == b.vert[2].z) );
bool f12 = ( (a.vert[0].x == b.vert[0].x) && (a.vert[0].y == b.vert[0].y) && (a.vert[0].z == b.vert[0].z) &&
(a.vert[1].x == b.vert[3].x) && (a.vert[1].y == b.vert[3].y) && (a.vert[1].z == b.vert[3].z) &&
(a.vert[2].x == b.vert[2].x) && (a.vert[2].y == b.vert[2].y) && (a.vert[2].z == b.vert[2].z) );
.......
// write output of tests to global array N, so as to make them accessible to all functions
N[0] = f11;
N[1] = f12;
N[2] = f13;
N[3] = f14;
N[4] = f21;
N[5] = f22;
N[6] = f23;
N[7] = f24;
N[8] = f31;
N[9] = f32;
N[10] = f33;
N[11] = f34;
N[12] = f41;
N[13] = f42;
N[14] = f43;
N[15] = f44;
The isNeighbour function looks like this:
bool isNeighbour (int a[16])
{
return (a[0] || a[1] || a[2] || a[3] || a[4] || a[5] || a[6] || a[7] || a[8]
|| a[9] || a[10] || a[11] || a[12] || a[13] || a[14] || a[15]);
// int i = 0;
//for (i = 0; i < 16; i++)
// {
// if ( a[i] == 1 ) return true;
//
// }
}
The output looks something like this:
T4092
T4100
N[0] = 0 N[1] = 0 N[2] = 0 N[3] = 0 N[4] = 0 N[5] = 0 N[6] = 0 N[7] = 0 N[8] = 1 N[9] = 0 N[10] = 0 N[11] = 0 N[12] = 0 N[13] = 0 N[14] = 0 N[15] = 0
T4101
T4120
N[0] = 0 N[1] = 0 N[2] = 1 N[3] = 0 N[4] = 0 N[5] = 0 N[6] = 0 N[7] = 0 N[8] = 0 N[9] = 0 N[10] = 0 N[11] = 0 N[12] = 0 N[13] = 0 N[14] = 0 N[15] = 0
T4169
N[0] = 0 N[1] = 0 N[2] = 0 N[3] = 0 N[4] = 0 N[5] = 0 N[6] = 0 N[7] = 0 N[8] = 0 N[9] = 0 N[10] = 0 N[11] = 0 N[12] = 1 N[13] = 0 N[14] = 0 N[15] = 0
N[0] = 0 N[1] = 1 N[2] = 0 N[3] = 0 N[4] = 0 N[5] = 0 N[6] = 0 N[7] = 0 N[8] = 0 N[9] = 0 N[10] = 0 N[11] = 0 N[12] = 0 N[13] = 0 N[14] = 0 N[15] = 0
My questions are the following:
why won't the commented out part of isNeighbour() work (it crashes)
? is the condition in the if loop correct ? (is it doing what I
think it is doing?)
why is N[] being rewritten as 0 when a tetrahedron has more than 1
neighbour (see T4169 with two lines of N[], in the second line,
N[12] was previously evaluated to be true (=1),
why is it when evaluating for the second time and it finds N[1]=1;
N[12] is reset to 0.
-and for the love of god is there anyway I could achieve a similar result but in a more elegant manner ? Also I am aware that I might
be violating basic rules of coding so please do not hesitate to
point them out!
Thank you
EDIT: this indeed C. I asked around and was told to include and bool should work just fine.

Why did I get a Memory-related error here?

I had a problem from a website. Given a string s and st, I have to found all possible combination of st in s. For example,
s = "doomdogged"
st = "dg"
answer = 4
I can choose the d from 0 or 4, and g from 6 or 7. Which gives me 4 possible combinations.
Here's my code:
#include <iostream>
#include <vector>
using namespace std;
string s, st;
bool target[26];
vector<int> positions[26];
vector<vector<int>> possibleCombinations;
void DFS_Enumeration(int, vector<int>*);
int DFS_index_max = 0;
int main(int argc, char *argv[])
{
int answer = 0;
cin >> s; //Given a string s
cin >> st; //Given a string st
//Find all possible combination of st in s
for ( int i = 0 ; i < 26 ; ++ i )
target[i] = 0;
for ( int i = 0 ; i < st.length() ; ++ i )
target[st[i] - 97] = 1;
for ( int i = 0 ; i < 26 ; ++ i )
{
if ( target[i] == 0 ) continue;
for ( int j = 0 ; j < s.length() ; ++ j )
{
if ( s[j] == i + 97 ) positions[i].push_back(j);
}
}
DFS_index_max = st.length();
vector<int> trail(0);
DFS_Enumeration(0, &trail); //Here I got an runtime error
for ( vector<int> vi : possibleCombinations )
{
int currentMax = 0;
for ( int i = 0 ; i < vi.size() ; ++ i )
{
if ( vi[i] > currentMax )
{
if ( i == vi.size() - 1 ) ++ answer;
currentMax = vi[i];
continue;
}
else
break;
}
}
cout << answer;
}
void DFS_Enumeration(int index, vector<int>* trail)
{
if ( index == DFS_index_max )
{
possibleCombinations.push_back(*trail);
return;
}
for ( int i = 0 ; i < positions[st[index] - 97].size() ; ++ i )
{
trail -> push_back(positions[st[index] - 97][i]);
DFS_Enumeration(++index, trail);
trail -> pop_back();
}
return;
}
First I look for characters in st, and mark them as needed to found in my boolean array target.
Then, I use DFS to enumerate all possible combinations. For the above example of "doomdogged" and "dg", d exists in 0, 4, 9. And g exist in 6, 7. I will get 06, 07, 46, 47, 96, 97.
Lastly, I count those which make sense, and output the answer. For some reason, my code doesn't work and generate an runtime error concerning memory at the line I've marked.
DFS_Enumeration might increment index any number of times, so st[index] could likely be past the end of the string st.

Floating point exception( core dump

Program: So I made a program that take two numbers, N and L. N is the size of a 2D array and L is a number from 3 - 16. The program builds the array and starts at the center and works its way out in a counter clockwise spiral. I is the value of the center and its as you go through the array( in the spiral ) the value will increase by one. It it is prime, that number will be assigned to that spot and if not it * will take its place instead.
Error: I'm getting a "Floating point exception " error, how would I solve this?
Code:
void Array_Loop( int *Array, int n, int L ) ;
int Is_Prime( int Number ) ;
int main( int argc, char *argv[] ){
int **Array ;
int n, L ;
n = atoi( argv[1] ) ;
L = atoi( argv[2] ) ;
Matrix_Build( &Array, n, n ) ;
Array_Loop( Array, n, L ) ;
return 0 ;
}
void Array_Loop( int *Array, int n, int L ){
int i, j, k, h ;
int lctn, move;
lctn = n / 2 + 1 ;
i = lctn ;
j = lctn ;
move = 1
while( i != 0 && j != n ){
for( j = lctn ; j < lctn + move ; j++ ){
if( L % 2 == 2) Array[i][j] = -1 ;
else Array[i][j] = Is_Prime( L ) ;
L++ ;
}
move = move * -1 ;
for( i = i ; i > lctn - move ; i-- ){
if( L % 2 == 2) Array[i][j] = -1 ;
else Array[i][j] = Is_Prime( L ) ;
L++ ;
}
move-- ;
for( j = j ; j > lctn - move ; j-- ){
if( L % 2 == 2) Array[i][j] = -1 ;
else Array[i][j] = Is_Prime( L ) ;
L++ ;
}
move = move * -1 ;
for( i = i ; i < lctn - move ; i-- ){
if( L % 2 == 2) Array[i][j] = -1 ;
else Array[i][j] = Is_Prime( L ) ;
L++ ;
}
move++ ;
}
}
int Is_Prime( int Number ){
int i ;
for( i = 0 ; i < Number / 2 ; i++ ){
if( Number % i != 0 ) return -1 ;
}
return Number ;
}
You are getting Floating point exception because Number % i, when i is 0:
int Is_Prime( int Number ){
int i ;
for( i = 0 ; i < Number / 2 ; i++ ){
if( Number % i != 0 ) return -1 ;
}
return Number ;
}
Just start the loop at i = 2. Since i = 1 in Number % i it always be equal to zero, since Number is a int.
Floating Point Exception happens because of an unexpected infinity or NaN.
You can track that using gdb, which allows you to see what is going on inside your C program while it runs. For more details:
https://www.cs.swarthmore.edu/~newhall/unixhelp/howto_gdb.php
In a nutshell, these commands might be useful...
gcc -g myprog.c
gdb a.out
gdb core a.out
ddd a.out