How to make atmega 128 electronic watch and stopwatch? - c++

`#include <mega128.h>
unsigned int KEYs_NUMs = 0, FLAG_RUNs = 0, TIME_DAYs = 1, TIME_HOUR = 0, TIME_MINs = 0, TIME_SECs = 0, TIME_10ms = 0, TIME_CNTs = 0 ;
unsigned int TIME_TMR0 = 0, TIME_IMSI, SEGs_NUMs = 0 ;
unsigned int TIME_S0, TIME_S1, TIME_M0, TIME_M1, TIME_H0, TIME_H1 ;
unsigned int IMSI = 0, DAT5 = 0, DAT4 = 0, DAT3 = 0, DAT2 = 0, DAT1 = 0, DAT0 = 0 ;
unsigned int mode = 0 ;
unsigned char SEG7[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7C, 0x07, 0x7F, 0x67} ;
unsigned char FNDs[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7C, 0x07, 0x7F, 0x67} ;
interrupt [EXT_INT4] void ext_int4_isr(void)
{
KEYs_NUMs += 1 ;
if(KEYs_NUMs == 1) { mode = 1 ; }
else { mode = 0 ; KEYs_NUMs = 0 ; }
}
interrupt [EXT_INT5] void ext_int5_isr(void)
{
if(mode == 1)
{
KEYs_NUMs += 1 ;
if(KEYs_NUMs == 1) { FLAG_RUNs = 1 ; }
else if(KEYs_NUMs == 2) { FLAG_RUNs = 0 ; }
else { FLAG_RUNs = 1 ; KEYs_NUMs = 1 ; }
}
}
interrupt [EXT_INT6] void ext_int6_isr(void)
{
if(mode == 1)
{
KEYs_NUMs -= 1 ;
if(KEYs_NUMs == 1) { TIME_MINs = 0, TIME_SECs = 0, TIME_10ms = 0, TIME_CNTs = 0 ; }
}
}
interrupt [EXT_INT7] void ext_int7_isr(void)
{
}
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0 = 0x06 ;
// Place your code here
TIME_TMR0 += 1 ; // 1ms
if(TIME_TMR0 >= 1000)
{ TIME_TMR0 = 0 ; TIME_SECs += 1 ; }
if(TIME_SECs > 59)
{ TIME_SECs = 0 ; TIME_MINs += 1 ; }
if(TIME_MINs > 59)
{ TIME_MINs = 0 ; TIME_HOUR += 1 ; }
if(TIME_HOUR > 23)
{ TIME_HOUR = 0 ; TIME_DAYs += 1 ; }
if(TIME_DAYs > 31)
{ TIME_DAYs = 1 ; }
TIME_IMSI = TIME_HOUR ;
TIME_H1 = TIME_IMSI/10 ;
TIME_H0 = TIME_IMSI - TIME_H1*10 ;
TIME_IMSI = TIME_MINs ;
TIME_M1 = TIME_IMSI/10 ;
TIME_M0 = TIME_IMSI - TIME_M1*10 ;
TIME_IMSI = TIME_SECs ;
TIME_S1 = TIME_IMSI/10 ;
TIME_S0 = TIME_IMSI - TIME_S1*10 ;
if(SEGs_NUMs > 6) { SEGs_NUMs = 0 ; }
SEGs_NUMs += 1 ;
if(SEGs_NUMs == 1)
{
PORTA.5 = 1 ; PORTA.4 = 1 ; PORTA.3 = 1 ; PORTA.2 = 1 ; PORTA.1 = 1 ;
PORTD = SEG7[TIME_S0] ;
PORTA.0 = 0 ;
}
else if(SEGs_NUMs == 2)
{
PORTA.5 = 1 ; PORTA.4 = 1 ; PORTA.3 = 1 ; PORTA.2 = 1 ; PORTA.0 = 1 ;
PORTD = SEG7[TIME_S1] ;
PORTA.1 = 0 ;
}
else if(SEGs_NUMs == 3)
{
PORTA.5 = 1 ; PORTA.4 = 1 ; PORTA.3 = 1 ; PORTA.1 = 1 ; PORTA.0 = 1 ;
PORTD = SEG7[TIME_M0] ;
PORTA.2 = 0 ;
}
else if(SEGs_NUMs == 4)
{
PORTA.5 = 1 ; PORTA.4 = 1 ; PORTA.2 = 1 ; PORTA.1 = 1 ; PORTA.0 = 1 ;
PORTD = SEG7[TIME_M1] ;
PORTA.3 = 0 ;
}
else if(SEGs_NUMs == 5)
{
PORTA.5 = 1 ; PORTA.3 = 1 ; PORTA.2 = 1 ; PORTA.1 = 1 ; PORTA.0 = 1 ;
PORTD = SEG7[TIME_H0] ;
PORTA.4 = 0 ;
}
else
{
PORTA.4 = 1 ; PORTA.3 = 1 ; PORTA.2 = 1 ; PORTA.1 = 1 ; PORTA.0 = 1 ;
PORTD = SEG7[TIME_H1] ;
PORTA.5 = 0 ;
}
if(TIME_TMR0 < 500) { PORTA.7 = 1 ; } // LED off
else { PORTA.7 = 0 ; } // LED on
}
void main(void)
{
DDRA=(1<<DDA7) | (0<<DDA6) | (1<<DDA5) | (1<<DDA4) | (1<<DDA3) | (1<<DDA2) | (1<<DDA1) | (1<<DDA0);
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);
DDRD=(1<<DDD7) | (1<<DDD6) | (1<<DDD5) | (1<<DDD4) | (1<<DDD3) | (1<<DDD2) | (1<<DDD1) | (1<<DDD0);
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
// Timer/Counter 0 initialization
ASSR=0<<AS0;
TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (1<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x06; OCR0=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);
ETIMSK=(0<<TICIE3) | (0<<OCIE3A) | (0<<OCIE3B) | (0<<TOIE3) | (0<<OCIE3C) | (0<<OCIE1C);
// External Interrupt(s) initialization
EICRA=(0<<ISC31) | (0<<ISC30) | (0<<ISC21) | (0<<ISC20) | (0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EICRB=(1<<ISC71) | (0<<ISC70) | (1<<ISC61) | (0<<ISC60) | (1<<ISC51) | (0<<ISC50) | (1<<ISC41) | (0<<ISC40);
EIMSK=(1<<INT7) | (1<<INT6) | (1<<INT5) | (1<<INT4) | (0<<INT3) | (0<<INT2) | (0<<INT1) | (0<<INT0);
EIFR=(1<<INTF7) | (1<<INTF6) | (1<<INTF5) | (1<<INTF4) | (0<<INTF3) | (0<<INTF2) | (0<<INTF1) | (0<<INTF0);
// Globally enable interrupts
#asm("sei")
while (1)
{
if(mode == 1)
{
if(FLAG_RUNs) { TIME_CNTs += 1 ; } // 1ms
if(TIME_CNTs > 99 ) { TIME_CNTs = 0 ; TIME_SECs += 1 ; }
if(TIME_SECs > 59 ) { TIME_SECs = 0 ; TIME_MINs += 1 ; }
if(TIME_MINs > 59 ) { TIME_MINs = 0 ; }
TIME_10ms = TIME_CNTs/10 ;
SEGs_NUMs ++ ;
if(SEGs_NUMs > 5) { SEGs_NUMs = 0 ; }
switch(SEGs_NUMs)
{
case 0 : PORTA.0 = 0 ; PORTA.1 = 1 ; PORTA.2 = 1 ; PORTA.3 = 1 ; PORTA.4 = 1 ;
PORTA.5 = 1 ;
PORTD = FNDs[DAT0] ; break;
case 1 : PORTA.0 = 1 ; PORTA.1 = 0 ; PORTA.2 = 1 ; PORTA.3 = 1 ; PORTA.4 = 1 ;
PORTA.5 = 1 ;
PORTD = FNDs[DAT1] ; break;
case 2 : PORTA.0 = 1 ; PORTA.1 = 1 ; PORTA.2 = 0 ; PORTA.3 = 1 ; PORTA.4 = 1 ;
PORTA.5 = 1 ;
PORTD = FNDs[DAT2] ; break;
case 3 : PORTA.0 = 1 ; PORTA.1 = 1 ; PORTA.2 = 1 ; PORTA.3 = 0 ; PORTA.4 = 1 ;
PORTA.5 = 1 ;
PORTD = FNDs[DAT3] ; break;
case 4 : PORTA.0 = 1 ; PORTA.1 = 1 ; PORTA.2 = 1 ; PORTA.3 = 1 ; PORTA.4 = 0 ;
PORTA.5 = 1 ;
PORTD = FNDs[DAT4] ; break;
case 5 : PORTA.0 = 1 ; PORTA.1 = 1 ; PORTA.2 = 1 ; PORTA.3 = 1 ; PORTA.4 = 1 ;
PORTA.5 = 0 ;
PORTD = FNDs[DAT5] ; break;
}
IMSI = TIME_MINs ;
DAT5 = IMSI/10 ;
DAT4 = IMSI - DAT5*10 ;
IMSI = TIME_SECs ;
DAT3 = IMSI/10 ;
DAT2 = IMSI - DAT3*10 ;
IMSI = TIME_10ms ;
DAT1 = IMSI/10 ;
DAT0 = IMSI - DAT1*10 ;
}
}
}
` I wrote a code to change the mode by pressing the mode button by putting the clock code in the timer interrupt and the stopwatch code in 'while'. If you change the mode, it moves to the stopwatch as much as the elapsed time, and if you start the stopwatch, the counter starts at the minute digit. And when you reset and return to the clock, the clock counts from the beginning. How can I keep the timer running even if I change the mode? And how do I prevent the timer's time from being transferred to the stopwatch?

According to the comments to the question:
interrupt [EXT_INT4] void ext_int4_isr(void)
{
// just toggle the mode, no need for counting any occurrences...
mode = !mode; // alternatively mode = 1 - mode
if(mode)
{
// reset the stop watch on having been enabled:
flagRuns = 0;
// reset the counter as well!
// TODO: common function for!
// should work calling ext_int6_isr directly, too
}
}
interrupt [EXT_INT5] void ext_int5_isr(void)
{
// can toggle unconditionally, as the flag is not evaluated if not
// in stop watch mode and is reset upon ENTERING the mode (this changed
// compared to your original version!)
flagRuns = !flagRuns;
}
interrupt [EXT_INT6] void ext_int6_isr(void)
{
if(mode && !flagRuns)
{
// reset, common function, see above
}
}
Most likely you need to declare the variables that are written to and read from across ISR and main routine or across different ISR volatile to avoid caching effects.

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);
}

Is there any way to go through the indexes of a 2D arrangement as if it were a piece on a game board or something like that?

I am trying to develop the code for an exercise that was assigned to me, but I can't find any way to do what I need to accomplish. The exercise in question consists of changing and printing the values of a 10x10 2d array filled with zeroes generating a pattern like this:
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1
1 0 1 0 0 0 0 0 0 0
1 0 1 0 1 1 1 1 1 1
1 0 1 0 1 0 0 0 0 1
1 0 1 0 1 0 1 1 1 1
1 0 1 0 1 0 1 0 0 0
1 0 1 0 1 0 1 0 1 1
1 0 1 1 1 0 1 1 1 0
It is probably not very noticeable, but starting from the index a[9][0] and ending at a[8][9] of the array it starts to go through changing those zeros of the array, forming a snake-like pattern. Thinking about it for a while, I tried to solve it with this code that I made, but I think it has several errors within it even though the compiler doesn't mark any so evident:
#include <iostream>
using namespace std;
int main()
{
int px = 0;
int py = 9;
int a[10][10];
for(int i = 0; i <= 10; i++) {
for(int j = 0; j <= 10; j++) {
a[i][j] = 0;
}
}
if (py == 9 && px == 0) {
while(py >= 0) {
a[py][px] = 1;
py = py - 1;
}
}
if (py == 0 && px == 0) {
while(px <= 9) {
a[py][px] = 1;
px = px + 1;
}
}
if (py == 0 && px == 9) {
while(py <= 2) {
a[py][px] = 1;
py = py + 1;
}
}
if (py == 2 && px == 9) {
while(px >= 2) {
a[py][px] = 1;
px = px - 1;
}
}
if (py == 2 && px == 2) {
while(py <= 9) {
a[py][px] = 1;
py = py + 1;
}
}
if (py == 9 && px == 2) {
while(px <= 4) {
a[px][py] = 1;
px = px + 1;
}
}
if (py == 9 && px == 4) {
while(py >= 4) {
a[px][py] = 1;
py = py - 1;
}
}
if (py == 4 && px == 4) {
while(px <= 9) {
a[py][px] = 1;
px = px + 1;
}
}
if (py == 4 && px == 9) {
while(py <= 6) {
a[py][px] = 1;
py = py + 1;
}
}
if (py == 6 && px == 9) {
while(px >= 6) {
a[py][px] = 1;
px = px - 1;
}
}
if (py == 6 && px == 6) {
while(py <= 9) {
a[py][px] = 1;
py = py + 1;
}
}
if (py == 9 && px == 6) {
while(px <= 8) {
a[py][px] = 1;
px = px + 1;
}
}
if (py == 9 && px == 8) {
while(py >= 8) {
a[py][px] = 1;
py = py - 1;
}
}
if (py == 8 && px == 8) {
while(px <= 9) {
a[py][px] = 1;
px = px + 1;
}
}
for(int k=0; k<=9; k++) {
for(int l=0; l<=9; l++) {
cout << a[k][l] << " ";
}
cout << endl;
}
return 0;
}
I hope you can help me with this, still I continue learning a little the basic thing of C++, probably it has been that it has escaped me some concept that I don't know or something like that. Thanks in advance.
Kindly refer to this
In first conv function I made a general pattern without snake
Then I focused on positions from where the snake connects other rows or column
#include <bits/stdc++.h>
using namespace std;
void conv1(int a[10][10])
{
int temp=0;
for(int i=0; i<10; i++)
{
if(i%2==0)
{
for(int j=temp; j<10; j++)
{
a[i][j]=1;
a[j][i]=1;
}
}
temp=temp+1;
}
}
/*
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0
1 0 1 1 1 1 1 1 1 1
1 0 1 0 0 0 0 0 0 0
1 0 1 0 1 1 1 1 1 1
1 0 1 0 1 0 0 0 0 0
1 0 1 0 1 0 1 1 1 1
1 0 1 0 1 0 1 0 0 0
1 0 1 0 1 0 1 0 1 1
1 0 1 0 1 0 1 0 1 0
*/
void conv2(int a[10][10])
{
int temp=0;
for(int i=0; i<10; i++)
{
if(i%2!=0&&temp==0)
{
a[i][9]=1;
temp=1;
}
else if(i%2!=0)
{
temp=0;
}
}
for(int i=0; i<10; i++)
{
if(i%2!=0&&temp==0)
{
a[9][i]=1;
temp=1;
}
else if(i%2!=0)
{
temp=0;
}
}
a[9][9]=0;
}
int main(){
int a[10][10];
for(int i=0; i<10;i++)
{
for(int j=0; j<10; j++)
{
a[i][j]=0;
}
}
conv1(a);
conv2(a);
for(int i=0; i<10;i++)
{
for(int j=0; j<10; j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}

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;

Check if the next move is check-mate

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

Remove if conditions from simple function

I need to remove as many if conditions as possible from the two functions below:
inline int inc_with_1bit_saturation(int counter)
{
if (counter == 1)
return --counter;
return ++counter;
}
void branch_prediction_1bit_saturation(int* input, int* output, int size)
{
int counter = 0;
for (int i = 0; i < size; ++i)
{
if (input[i] != counter)
{
counter = inc_with_1bit_saturation(counter);
output[i] = 0;
}
else output[i] = 1;
}
}
How can I do that and what if branch is absolutely necessary and cannot be removed and which one can be replaced by simple bitwise operations or something like that?
Update 1
According to User JSF's great tip, the code is now looking like this:
void branch_prediction_1bit_saturation(int* input, int* output, int size)
{
int counter = 0;
for (int i = 0; i < size; ++i)
{
if (input[i] != counter)
{
counter = 1 - counter;
output[i] = 0;
}
else output[i] = 1;
}
}
Update 2
Thanks to Cantfindname, the code became like this:
void branch_prediction_1bit_saturation(int* input, int* output, int size)
{
int counter = 0;
for (int i = 0; i < size; ++i)
{
output[i] = counter == input[i];
counter = output[i] * counter + (1 - output[i])*(1 - counter);
}
}
And this completely solves the question.
For the if statement inside the loop:
output[i] = (int)(input[i]==counter);
counter = output[i]*counter + (1-output[i])*(1-counter) //used JSF's trick
True converts to 1 and false to 0, according to this: bool to int conversion
function inc_with_1bit_saturation is equivalent of modulo 2. So you can replace
counter = inc_with_1bit_saturation(counter);
With
counter = (counter+1) % 2;
void branch_prediction_1bit_saturation(int* input, int* output, int size) {
int counter = 0;
for (int i = 0; i < size; ++i)
{
output[i] = (int)!((!!input[i]) ^ counter);
counter = (int)((!!input[i]) & counter) | ((!!input[i]) & !counter);
}
}
A is logic input[i];
B is logic counter;
The truth table for input[i] != counter is:
A B
0 0 | 0 --> (0 & 0) | (0 & !0) = 0 | 0 = 0
0 1 | 0 --> (0 & 1) | (0 & !1) = 0 | 0 = 0
1 0 | 1 --> (1 & 0) | (1 & !0) = 0 | 1 = 1
1 1 | 1 --> (1 & 1) | (1 & !1) = 1 | 0 = 1
The truth table for output[i]
A B
0 0 | 1 --> !(0 ^ 0) = !(0) = 1
0 1 | 0 --> !(0 ^ 1) = !(1) = 0
1 0 | 0 --> !(1 ^ 0) = !(1) = 0
1 1 | 1 --> !(1 ^ 1) = !(0) = 1
:)