spoj samer08e getting wrong answer - c++

Here is my solution for the spoj problem:
http://www.spoj.com/problems/SAMER08E/
This is my logic:
I check if the given dates are adjacent to each other. If they are, then add the difference of the cost. Else skip.
//header files omitted
#define REP(i,n) for(int i=0; i<n; i++)
#define FOR(i,st,end) for(int i=st;i<end;i++)
int monthDates[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
bool isLeap( int y ){//check if year is leap
if(y%4 == 0 && y%100 != 0 || y%400 == 0)
return true;
return false;
}
bool checkAdjacent( int prev[], int curr[] ){//check if the dates are adjacent to each other
if( prev[0] == 31 && prev[1] == 12 && curr[0] == 1 && curr[1] == 1 && (curr[2] - prev[2]) == 1 )//last and first days of the year
return true;
if( prev[2] == curr[2]){//same year
if( prev[1] == curr[1]){//same month
if((curr[0]-prev[0]) == 1)//same adjacent dates
return true;
}else if( curr[1] - prev[1] == 1){//adjacent months
if( isLeap(prev[2]) && prev[1] == 2 && curr[1] == 3 && prev[0] == 29 && curr[0] == 1)//for leap year february
return true;
else if( !isLeap(prev[2]) && monthDates[prev[1]] == prev[0] && curr[0] == 1)
return true;
}
}
return false;
}
int main(){
int n;
while( scanf("%d", &n) && n){
int prev[4], curr[4], count = 0;
ll totalCost = 0;
REP(i,4)
scanf("%d", &prev[i]);
FOR( i, 1, n){
REP(j,4)
scanf("%d", &curr[j]);
if( checkAdjacent( prev, curr) ){
totalCost += curr[3] - prev[3];
count++;
}
prev[0] = curr[0];
prev[1] = curr[1];
prev[2] = curr[2];
prev[3] = curr[3];
}
printf("%d %lld\n", count, totalCost);
}
return 0;
}
The program works for the test cases, but i keep getting wrong answer. What is the error?

Since there are two people recording the measurements, it might be possible for the same day to be recorded twice, which could throw off your consumption computation.

Your program does not check the condition when the year is leap and the month is not February. Add this condition and you will get AC. I hope this helps.

Related

C++ Month, day, and year validation

I'm currently working on a project for my intro to C++ programming class. The project asks a user to enter a date using mm/dd/yyyy format. Based on the information given, the program then has to determine if the date is valid or invalid, then displays a response to that. I'm facing the problem currently where everything is coming out reading "Good date!" I'm not sure where the problem is. Any help is appreciated. If you could help point me in the right direction, that would be awesome.
#include <iostream>
#include <conio.h>
using namespace std;
void getDate(int *month, int *day, int *year);
int checkDate(int month, int day, int year);
void displayMessage(int status);
int main()
{
int month, day, year;
int s = 0;
getDate(&month, &day, &year);
do
{
checkDate(month, day, year);
displayMessage(s);
getDate(&month, &day, &year);
}
while (_getch() != EOF);
}
void getDate(int *month, int *day, int *year)
{
char fill;
fill = '/';
cout << "Enter a date in mm/dd/yyyy form: ";
cin >> *month;
if (cin.get() != '/')
{
cout << "expected /" << endl;
}
cin >> *day;
if (cin.get() != '/')
{
cout << "expected /" << endl;
}
cin >> *year;
cout << *month << fill << *day << fill << *year << endl;
};
int checkDate(int month, int day, int year)
{
if ((month = 1) || (month = 3) || (month = 5) || (month = 7) ||
(month = 8) || (month = 10) || (month = 12))
{
day <= 31;
}
else if ((month = 4) || (month = 6) || (month = 9) || (month = 11))
{
day <= 30;
}
else if ((month = 2) && (year % 4 == 0))
{
day <= 29;
}
else if ((month = 2) && (year % 4 != 0))
{
day <= 28;
};
int status = 0;
if ((year < 999) || (year > 10000))
{
status == 1;
}
if ((month < 1) || (month > 12))
{
status == 2;
}
else if ((day < 1) || (day > 31))
{
status == 3;
}
else if ((day < 1) || (day > 30))
{
status == 4;
}
else if ((day < 1) || (day > 29))
{
status == 5;
}
else if ((day < 1) || (day > 28))
{
status == 6;
}
return status;
};
void displayMessage(int status)
{
if (status == 0)
{
cout << "Good date!" << endl;
}
if (status == 1)
{
cout << "Bad year" << endl;
}
if (status == 2)
{
cout << "Bad month" << endl;
}
if (status == 3)
{
cout << "Bad day. Not 1-31" << endl;
}
if (status == 4)
{
cout << "Bad day, not 1-30" << endl;
}
if (status == 5)
{
cout << "Bad day, not 1-29" << endl;
}
if (status == 6)
{
cout << "Bad day, not 1-28" << endl;
}
_getch();
}
1) There are a couple of issues here, but the most obvious one is in main():
int s=0;
...
checkDate(month, day, year); // you don't store the status
displayMessage(s); // so s will always be 0 ! So good date !
You have to correct this:
s=checkDate(month, day, year); // store the result of the check
displayMessage(s); // and take it to display the message
2) Then in checkDate(), you mixup = and ==. = changes the value of the variable to its left. == just makes a comparison but store nothing. When correcting/adjusting, without any optimisation, your code should look like:
int checkDate(int month, int day, int year)
{
int status=0;
if ((month == 1 || month == 3 || month == 5 || month == 7 ||
month == 8 || month == 10 || month == 12) && ( day>31 || day<1) )
{
status = 3;
}
else if ((month == 4 || month == 6 || month == 9 || month == 11) && (day>30 || day<1) )
{
status = 4;
}
else if ((month == 2) && (year % 4 == 0) && (day>29 || day<1))
{
status = 5;
}
else if ((month == 2) && (year % 4 != 0) && (day>28 || day<1) )
{
status = 6;
}
else if ((year < 999) || (year > 10000))
{
status = 1;
}
if ((month < 1) || (month > 12))
{
status = 2;
}
return status;
};
3) After this, you should improve the input function, because:
it doesn't cope with invalid separators. If '/' are missing, an error message is displayed, but you continue the input as if everything was fine.
it doesn't cope with invalid (i.e.non numeric) input. If user enters XI/1/2016 for example, your input will fail.
So keep in mind that (cin>>xxx) is an expression that you could use in an if and is true if everything was read correctly. Also be aware that cin.clear() clears error flags that blocks input after a failure.
You also could make use of the function mktime().
It tries to convert a given tm struct into a correct date. If the comparison of the individual members of the struct subsequently shows equality for all members, the given tm struct contained a valid date.
bool CBorrow::validateDate(tm * timestruct)
{
struct tm copy;
copy.tm_sec = timestruct->tm_sec;
copy.tm_min = timestruct->tm_min;
copy.tm_hour = timestruct->tm_hour;
copy.tm_mday = timestruct->tm_mday;
copy.tm_mon = timestruct->tm_mon;
copy.tm_year = timestruct->tm_year;
copy.tm_wday = timestruct->tm_wday;
copy.tm_yday = timestruct->tm_yday;
copy.tm_isdst = timestruct->tm_isdst;
time_t res = mktime(&copy);
if (res < 0)
{
return false;
}
if (copy.tm_mday != timestruct->tm_mday
|| copy.tm_mon != timestruct->tm_mon
|| copy.tm_year != timestruct->tm_year)
{
return false;
}
return true;
}
Updated answer for C++20:
#include <chrono>
#include <iostream>
void
displayMessage(std::chrono::year_month_day ymd)
{
using namespace std;
using namespace std::chrono;
if (!ymd.year().ok())
{
cout << "Bad year\n";
return;
}
if (!ymd.month().ok())
{
cout << "Bad month\n";
return;
}
if (!ymd.ok())
{
cout << "Bad day, not 1-" << (ymd.year()/ymd.month()/last).day() << '\n';
return;
}
cout << "Good date!\n";
}
int
main()
{
using namespace std::literals;
displayMessage(29d/2/1900);
}
Output:
Bad day, not 1-28
(1900 was not a leap year)
Can this also be achieved by a regular expression?
I know there are many drawbacks in this approach, but still may be considered:
#include <regex>
#include <string>
using std::regex;
using std::regex_match;
using std::string;
// for ddmmyy
regex ddmmyy("^([0-2][0-9]|(3)[0-1])(((0)[0-9])|((1)[0-2]))\\d{2}$");
/*
for dd/mm/yy https://regex101.com/r/IqPLBJ/1
for dd/mm/yyyy - could start from \\d{4}$ instead of \\d{2}$ bearing 0000-case in mind
*/
regex slashed_ddmmyy("^([0-2][0-9]|(3)[0-1])\/(((0)[0-9])|((1)[0-2]))\/\\d{2}$");
string f1 = "111223";
bool res = regex_match(f1,ddmmyy); // true
f1 = "112223";
res = regex_match(f1,ddmmyy); // false
res = regex_match(f1, slashed_ddmmyy); // false, no slashes
A more compact and stripped checkDate (replace uppercase return by value)
int checkDate(int day, int month, int year) {
if(day < 1 || day > 31) {
return BADVALUE;
} else if(month < 1 || month > 12) {
return BADVALUE;
} else if (year < MINYEAR || year > MAXYEAR) {
return YEAROUTRANGE;
}
if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 31) {
return BADMONTHDAY;
} else if ((month == 2) && (year % 4 == 0) && day > 29) {
return BADMONTHYEAR;
} else if ((month == 2) && (year % 4 != 0) && day > 28) {
return BADMONTHYEAR;
}
return GOOD;
}

Algorithm to calculate sum of LUCKY FACTOR in given range

Problem Statement :-
A number is given, N, which is given in binary notation, and it
contains atmost 1000000 bits. You have to calculate the sum of LUCKY
FACTOR in range from 1 to N (decimal notation).
Here, LUCKY FACTOR means, (after converting into binary representation) if
rightmost or leftmost 1's neighbour is either 0 or nothing(for
boundary bit).
EDITED :-
Means if rightmost one's left neighbour is 0, means it count as a
LUCKY FACTOR, simlarly in the left side also
Example,
5 == 101, LUCKY FACTOR = 2.
7 == 111, LUCKY FACTOR = 0.
13 == 1101, LUCKY FACTOR = 1.
16 == 1110, LUCKY FACTOR = 0.
0 == 0, LUCKY FACTOR = 0.
Answer must be in binary form
I am totally stuck, give me a hint.
My code
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
//#include<iostream>
using namespace std;
vector<string> pp(10000001);
string add(string a, string b) {
if(b == "") return a;
string answer = "";
int c = 0;
int szeA = a.size() - 1;
int szeB = b.size() - 1;
while(szeA >= 0 || szeB >= 0) {
answer = (char)( ( ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) ^ ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) ) ^ (c) ) + 48 ) + answer;
c = ( ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) & ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) ) | ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) & (c) ) | ( ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) & (c) ) );
szeA--;
szeB--;
}
if(c) answer = '1' + answer;
return answer;
}
string subtract(string a, string b) {
int sze = a.size() - b.size();
while(sze--) b = '0' + b;
sze = a.size();
for(int i = 0; i < sze; i++) {
if(b[i] == '1') b[i] = '0';
else b[i] = '1';
}
if(b[sze-1] == '0') {
b[sze-1] = '1';
}
else {
int i = sze-1;
while(i >= 0 && b[i] == '1') {
b[i] = '0';
i--;
}
if(i >= 0) b[i] = '1';
else b = '1' + b;
}
b = add(a, b);
b.erase(b.begin() + 0);
//b[0] = '0';
while(b[0] == '0') b.erase(b.begin() + 0);
return b;
}
string power(int index) {
if(index < 0) return "";
string answer = "";
while(index--) {
answer = '0' + answer;
}
answer = '1' + answer;
return answer;
}
string convert(long long int val) {
int divisionStore=0;
int modStore=0;
string mainVector = "";
do {
modStore=val%2;
val=val/2;
mainVector = (char)(modStore+48) + mainVector;
}while(val!=0);
return mainVector;
}
string increment(string s) {
int sze = s.size()-1;
if(s[sze] == '0') {
s[sze] = '1';
return s;
}
while(sze >= 0 && s[sze] == '1') {
s[sze] = '0';
sze--;
}
if(sze >= 0) s[sze] = '1';
else s = '1' + s;
return s;
}
main() {
int T;
char s[1000001];
string answer;
scanf("%d", &T);
for(int t = 1; t <= T; t++) {
int num;
answer = "1";
int bitComeEver = 0;
int lastBit = 0;
scanf("%s", s);
int sze = strlen(s);
// I used below block because to avoid TLE.
if(sze > 3300) {
printf( "Case #%d\n", t);
for(int i = 0; i < sze; i++) printf("%c", '1');
printf("\n");
//continue;
}
else {
if(pp[sze-1] != "") answer = pp[sze-1];
else {
pp[sze-1] = power(sze-1);
answer = pp[sze-1];
}
answer = subtract(answer, convert(sze-1));
////////////////////////////
//cout << answer << endl;
for(int i = 1; i < sze; i++) {
if(s[i] == '1') {
if(s[1] == '0') {
num = sze-i-1;
if(num > 0) {
if( pp[num-1] == "") {
pp[num-1] = power(num-1);
}
if(pp[num+1] == "") {
pp[num+1] = power(num+1);
}
answer = add(answer, subtract(pp[num+1], pp[num-1]));
if(lastBit) answer = add(answer, "1");
//else answer = increment(answer);
//cout << "\t\t" << answer << endl;
}
else{
int inc;
if(lastBit) inc = 2; //answer = add(answer, "10");
else inc = 1; //answer = increment(answer);
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
if(lastBit) inc += 2;
else inc += 1;
if(inc == 2) answer = add(answer, "10");
else if(inc == 3) answer = add(answer, "11");
else answer = add(answer, "100");
}
}
else {
if(num > 0) {
if(pp[num-1] != "") pp[num-1] = power(num-1);
answer = add(answer, pp[num-1]);
}
else {
int inc = 0;
if(lastBit) inc = 1; //answer = increment(answer);
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
if(lastBit) inc += 1;
answer = add(answer, convert(inc));
}
}
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
}
}
if(s[sze-1] == '0') {
if(lastBit) {
if(s[1] == '0') {
answer = add(answer, "10");
}
else answer = increment(answer);
}
else if(s[1] == '0'){
answer = increment(answer);
}
}
printf( "Case #%d\n", t);
for(int i = 0; i < sze; i++) printf("%c", answer[i]);
printf("\n");
}
}
return 0;
}
If a number has k bits, then calculate the number of such numbers having a LUCKY FACTOR of 2:
10.............01
Hence in this the 1st two and last two digits are fixed, the remaining k-4 digits can have any value. The number of such numbers = 2^(k-4).
So you can easily calculate the sum of lucky factors of such numbers = lucky_factor x 2^(k-4)
(ofcourse this is assuming k >= 4)
What's more, you do not need to calculate this number since it will be of the form 10000000.
If the number n is 11010010. Then 8 bit numbers less than n shall be of form:
10........ or 1100...... or 1101000_. If you see a pattern, then we have divided the calculation in terms of the number of 1s in the number n
.
I leave the rest for you.

Sudoku solving algorithm C++

I'm trying to make a Sudoku Solving program for a couple of days but I'm stuck with the methods. I found this algorithm here but I don't really understand it:
start at the first empty cell, and put 1 in it.
Check the entire board, and see if there are any conflicts
If there are coflicts on the board, increase the number in the current cell by 1 (so change 1 to 2, 2 to 3, etc)
If the board is clean move, start at step one again.
If all nine possible numbers on a given cell cause a conflict in the board, then you set this cell back to empty, go back to the previous cell, and start again from step 3 (this is where the 'backtracking' comes in).
Here is my code. I think something is wrong with my Help_Solve(...) function. Can you help me to identify the problem, please?
#include <iostream>
#include <iomanip>
#include <time.h>
#include <cstdlib>
#include <windows.h>
using namespace std;
class Sudoku
{
private:
int board[9][9];
int change[9][9];
public:
Sudoku();
void Print_Board();
void Add_First_Cord();
void Solve();
void Help_Solve(int i, int j);
bool Check_Conflicts(int p, int i, int j);
};
Sudoku Game;
void setcolor(unsigned short color) //The function that you'll use to
{ //set the colour
HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hcon,color);
}
Sudoku::Sudoku()
{
for(int i = 1; i <= 9; i++)
for(int j = 1; j <= 9; j++)
board[i][j] = 0;
}
void Sudoku::Print_Board()
{
for(int i = 1; i <= 9; i++)
{
for(int j = 1; j <= 9; j++)
{
if(change[i][j] == 1)
{
setcolor(12);
cout << board[i][j] << " ";
setcolor(7);
}
else cout << board[i][j] << " ";
if(j%3 == 0) cout << "| ";
}
cout << endl;
if(i%3 == 0) cout << "------+-------+---------" << endl;
}
}
void Sudoku::Add_First_Cord()
{
board[1][1] = 5; change[1][1] = 1;
board[1][2] = 3; change[1][2] = 1;
board[1][5] = 7; change[1][5] = 1;
board[2][1] = 6; change[2][1] = 1;
board[2][4] = 1; change[2][4] = 1;
board[2][5] = 9; change[2][5] = 1;
board[2][6] = 5; change[2][6] = 1;
board[3][2] = 9; change[3][2] = 1;
board[3][3] = 8; change[3][3] = 1;
board[3][8] = 6; change[3][8] = 1;
board[4][1] = 8; change[4][1] = 1;
board[4][5] = 6; change[4][5] = 1;
board[4][9] = 3; change[4][9] = 1;
board[5][1] = 4; change[5][1] = 1;
board[5][4] = 8; change[5][4] = 1;
board[5][6] = 3; change[5][6] = 1;
board[5][9] = 1; change[5][9] = 1;
board[6][1] = 7; change[6][1] = 1;
board[6][5] = 2; change[6][5] = 1;
board[6][9] = 6; change[6][9] = 1;
board[7][2] = 6; change[7][2] = 1;
board[7][7] = 2; change[7][7] = 1;
board[7][8] = 8; change[7][8] = 1;
board[8][4] = 4; change[8][4] = 1;
board[8][5] = 1; change[8][5] = 1;
board[8][6] = 9; change[8][6] = 1;
board[8][9] = 5; change[8][9] = 1;
board[9][5] = 8; change[9][5] = 1;
board[9][8] = 7; change[9][8] = 1;
board[9][9] = 9; change[9][9] = 1;
}
bool Sudoku::Check_Conflicts(int p, int i, int j)
{
for(int k = 1; k <= 9; k++)
if(board[i][k] == p) return false;
for(int q = 1; q <= 9; q++)
if(board[q][j] == p) return false;
/*
*00
000
000
*/
if((j == 1 || j == 4 || j == 7) && (i == 1 || i == 4 || i == 7))
{
if(board[i][j+1] == p || board[i][j+2] == p || board[i+1][j] == p ||
board[i+2][j] == p || board[i+1][j+1] == p || board[i+1][j+2] == p ||
board[i+2][j+1] == p || board[i+2][j+2] == p)return false;
}
/*
000
000
*00
*/
if((j == 1 || j == 4 || j == 7) && (i == 3 || i == 6 || i == 9))
{
if(board[i-1][j] == p || board[i-2][j] == p || board[i][j+1] == p ||
board[i][j+2] == p || board[i-1][j+1] == p || board[i-1][j+2] == p ||
board[i-2][j+1] == p || board[i-2][j+2] == p)return false;
}
/*
000
*00
000
*/
if((j == 1 || j == 4 || j == 7) && (i == 2 || i == 5 || i == 8))
{
if(board[i-1][j] == p || board[i+1][j] == p || board[i-1][j+1] == p ||
board[i][j+1] == p || board[i+1][j+1] == p || board[i+1][j+2] == p ||
board[i][j+2] == p || board[i+1][j+2] == p)return false;
}
/*
0*0
000
000
*/
if((j == 2 || j == 5 || j == 8) && (i == 1 || i == 5 || i == 7))
{
if(board[i-1][j] == p || board[i+1][j] == p || board[i-1][j+1] == p ||
board[i][j+1] == p || board[i+1][j+1] == p || board[i+1][j+2] == p ||
board[i][j+2] == p || board[i+1][j+2] == p)return false;
}
/*
000
0*0
000
*/
if((j == 2 || j == 5 || j == 8) && (i == 2 || i == 5 || i == 8))
{
if(board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j+1] == p ||
board[i][j+1] == p || board[i][j-1] == p || board[i+1][j+1] == p ||
board[i][j] == p || board[i+1][j-1] == p)return false;
}
/*
000
000
0*0
*/
if((j == 2 || j == 5 || j == 8) && (i == 3 || i == 6 || i == 9))
{
if(board[i][j-1] == p || board[i][j+1] == p || board[i-1][j] == p ||
board[i-1][j+1] == p || board[i-1][j-1] == p || board[i-2][j] == p ||
board[i-1][j+1] == p || board[i-2][j-1] == p) return false;
}
/*
00*
000
000
*/
if((j == 3 || j == 6 || j == 9) && (i == 1 || i == 4 || i == 7))
{
if(board[i][j-1] == p || board[i][j-2] == p || board[i+1][j] == p ||
board[i+1][j-1] == p || board[i+1][j-2] == p || board[i+2][j] == p ||
board[i+2][j-1] == p || board[i+2][j-2] == p) return false;
}
/*
000
00*
000
*/
if((j == 3 || j == 6 || j == 9) && (i == 2 || i == 5 || i == 8))
{
if(board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j-2] == p ||
board[i][j-1] == p || board[i][j-2] == p || board[i+1][j] == p ||
board[i+1][j-1] == p || board[i+1][j-2] == p) return false;
}
/*
000
000
00*
*/
if((j == 3 || j == 6 || j == 9) && (i == 3 || i == 6 || i == 9))
{
if(board[i][j-1] == p || board[i][j-1] == p || board[i-1][j] == p ||
board[i-1][j-1] == p || board[i-1][j-2] == p || board[i-2][j] == p ||
board[i-2][j-1] == p || board[i-2][j-2] == p) return false;
}
return true;
}
void Sudoku::Help_Solve(int i, int j)
{
if(j <= 0)
{
i = i-1;
j = 9;
}
if(change[i][j] == 1) return Game.Help_Solve(i, j-1);
for(int p = 1; p <= 9; p++)
if(Game.Check_Conflicts(p, i, j))
{
board[i][j] = p;
return;
}
return Game.Help_Solve(i, j-1);
}
void Sudoku::Solve()
{
for(int i = 1; i <= 9; i++)
{
for(int j = 1; j <= 9; j++)
{
if(board[i][j] == 0 && change[i][j] == 0)
{
Game.Help_Solve(i, j);
}
}
}
for(int i = 1; i <= 9; i++)
for(int j = 1; j <= 9; j++)
if(board[i][j] == 0) Game.Help_Solve(i, j);
}
int main()
{
Game.Add_First_Cord();
Game.Solve();
Game.Print_Board();
system("pause");
return 0;
}
Edit: I need to use recursion right? But maybe the parameters I give to the function are wrong. I really don't know. In Add_First_Cord() I declare the starting values that every sudoku has in the beginning. Here are the values that I use: http://bg.wikipedia.org/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:Sudoku-by-L2G-20050714.gif. I expect to see the solved sudoku as it is shown in wikipedia. But some solved values are right others are not. Here is what I get in the console
Suggested Approach
Implement a generic graph search algorithm
could use either IDFS or A* graph search
I would prefer the second
do this for a general directed graph
node type TNode
node successor function TNode => vector<TNode>
Define your Sudoku states
a state is a 9x9 array with a number 1, 2, ..., or 9 or a blank in each position
Define what a goal Sudoku state is
all 81 cells filled in
all 9 rows have numbers {1, 2, ..., 9} in them
all 9 columns have numbers {1, 2, ..., 9} in them
all 9 3x3 squares have numbers {1, 2, ..., 9} in them
Define your valid Sudoku state successor function
a state S can have number N added at row I, column J if:
cell (I,J) is empty
there is no other N in row I
there is no other N in column J
there is no other N in the 3x3 square containing (I,J)
the state successor function maps a state S to the vector of states that satisfy these rules
Apply your generic graph search algorithm (1) to the Sudoku state graph (2-4)
(optional) If you do choose to use A* graph search, you can also define a heuristic on your Sudoku state space to potentially drastically increase performance
how to design the heuristic is another whole problem, that's more of an art than a science
Current Approach
Your current approach mixes the specification of the graph to be searched and the implementation of the search algorithm. You're going to have a lot of difficulty if you mix those two. This problem naturally separates into two distinct pieces -- the algorithm and the graph -- so you can and should exploit that in your implementation. It will make it much simpler.
The other benefit you get if you go with this separation is that you will be able to reuse your graph search algorithm on a huge number of problems - very cool!
The following assumes you are trying to solve a given board, not generate a puzzle.
Basic (simple) approach
Create a class whose objects can hold a board (here called board_t). This class may internally use array, but must support copying boards.
Have a function void solve(board_t const& board); which repeats the following for each number n:
Copies your input
Enters n in the first empty cell of the copied board
If the copied board is a solution, print the solution and return.
Else If the board is still viable (e.g. no conflicts):
call solve(copied_board)
Performance
This is a recursive backtracking solution, which performs horribly for hard problems. You can significantly speed it up by proper pruning or deductive steps (e.g. if you end up with 8 numbers in a row after inserting one, you can immediately enter the ninth without any kind of search).
Reasoning
While certainly not an impressive technique, it has a high probability of working correctly, since you will only ever be modifying a copy to add a single value. This prevents corruption of your data structures (one problem your idea has is that it will destroy the numbers it finds when backtracking, are not necessarily the ones you just inserted, but may be part of the initial puzzle).
Improving performance is quite simple, once you start picking more intelligent heuristics (e.g. instead of testing the square in order, you could pick the ones with the fewest remaining moves and try to get them out of the way - or do the reverse...) or start doing a bit of deduction and pruning.
Note: The Algorithm Design Manual uses a Soduko solver to show the impact of these techniques on backtracking.
There is one very important modification to recursive algorithms: Use most constrained first approach. This means first to solve a cell with smallest number of possible candidates (when direct row/column/block conflicts are removed).
Another modification is: Change the board in-place; do not copy it. In each recursive call you modify only one cell on the board, and that cell used to be empty. If that call doesn't end up in a solved board somewhere down the recursive call tree, just clear the cell again before returning - this returns the board into original state.
You can find a very short and fast solution in C# on address: Sudoku Solver. It solves arbitrary sudoku board in about 100 steps only, all thanks to the most constrained first heuristic.
This is a classic Constraint Satisfaction Problem. I recommend doing some research on the topic to figure out the successful strategy. You will need to use AC-3 ( Arc Consistency 3) algorithm along with the backtracking techniques to solve the problem.

C++ Incomplete Code about dates, what is the better solution?

Im writing a code that, if you input your birthday date and any other date, it returns the total number of years, months and day that you are alive.
Obs.:including (leap) bissextile years.
Obs.2:for invalid dates, the output must be "data invalida" (invalid date in portuguese).
Inputs/Outputs:
Obs.: The date format is in the brazillian standard, the format is Day / Month / Year.
8 //the first input is the number of inputs that you will test.
Input 1: 29/02/2000
Input 2: 01/03/2001
Output: 1 0 1
Input 1: 29/02/2000
Input 2: 28/02/2001
Output: 1 0 0
Input 1: 29/12/2012
Input 2: 13/01/2013
Output: 0 0 15
Input 1: 27/05/2012
Input 2: 27/05/2013
Output: 1 0 0
Input 1: 01/01/2012
Input 2: 05/01/2013
Output: 1 0 4
Input 1: 13/05/1966
Input 2: 05/02/2015
Output: 48 8 23
Input 1: 29/02/2003
Input 2: 4/05/2012
Output: data invalida
Input 1: 14/13/1995
Input 2: 7/8/1996
Output: data invalida
The Code:
#include <iostream>
#include <cstdio>
using namespace std;
int verificar(int ano)
{
if (((ano % 4 == 0) && (ano % 100 != 0)) || (ano % 400 == 0))
return 1;
else
return 0;
}
int checkdia(int dia, int mes, int ano){
if (dia>0)
if (((mes==1)||(mes==3)||(mes==5)||(mes==7)||(mes==8)||(mes==10)||(mes==12)) && (dia<=31))
return 1;
else{
if (((mes==4)||(mes==6)||(mes==9)||(mes==11)) && (dia<=30))
return 1;
else{
if ((mes==2) && (dia<=28))
return 1;
else{
if ((((verificar(ano))==true)&&(dia<=29))&&(mes==2))
return 1;
else
return 0;
}
}
}
else
return 0;
}
int checkmes(int mes)
{
if ((mes>0) && (mes<=12))
return 1;
else
return 0;
}
int checkano(int ano)
{
if ((ano>0) && (ano<11000))
return 1;
else
return 0;
}
int main(){
int numerodetestes, mes1, mes2, dia1, dia2, ano1, ano2, teste11, teste12, teste13, teste21, teste22, teste23;
cin>>numerodetestes;
for(int c=0;c<=numerodetestes;c++){
scanf("%d/%d/%d", &dia1, &mes1, &ano1);
scanf("%d/%d/%d", &dia2, &mes2, &ano2);
teste11=checkano(ano1);
teste12=checkdia(dia1,mes1,ano1);
teste13=checkmes(mes1);
teste21=checkano(ano2);
teste22=checkdia(dia2,mes2,ano2);
teste23=checkmes(mes2);
if ((dia1==29)&&(mes1==02))
dia1=28;
if ((teste11+teste12+teste13+teste21+teste22+teste23)==6){
total=((365*(ano2-ano1))+sexto);
//... incomplete part ...//
}
else
cout<<"data invalida"<<endl;
}
return 0;
}
Glossary:
dia: day
mes: month
ano: year
numerodetestes: number of tests
verificar: function for bissextile
check(...): function to check "X"
teste"XX": int variable that will receive a 0 or 1 of a check function.
THE PROBLEM IS: I cant figure out how to calculate it in an organized way.
You should use bool instead of int for your return values :
bool verificar(int ano)
{
return ((ano % 4 == 0) && (ano % 100 != 0)) || (ano % 400 == 0));
}
Also your check functions could be greatly simplified :
bool checkmes(int mes) {
return ( (mes > 0) && (mes <= 12) );
}
bool checkano(int ano) {
return ( (ano > 0) && (ano < 11000) );
}
bool checkdia(int dia, int mes, int ano) {
if(dia < 1 || dia > 31) return false;
if(mes%2 == 0 && dia >30) return false;
if(mes == 2 && dia >28) return verificar(ano);
return true;
}
Then you could write something like :
bool checkdata(int dia, int mes, int ano) {
return ( checkano(ano) && checkmes(mes) && checkdia(dia, mes, ano) );
}
Which would allow you to write :
if( !checkdata(dia1,mes1,ano1) || !checkdata(dia2,mes2,ano2) ) {
cout<< "data invalida" <<endl;
}
Now for the main problem, you could easily get an estimation of the number of day between two dates, but you can't easily get the real number, because dates are nothing but logical. You would have to take into account all calendar modifications across history.
For an easy estimation, I would first add/subtract the dates offset to the first of January, and then add the year difference :
bool isLeap(int year) {
     return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
int monthLengths[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int monthLength(int month, int year) {
int n = monthLengths[month-1];
if(month == 2 && isLeap(year)) n += 1;
return n;
}
int yearLength(int year) {
return isLeap(year) ? 366 : 365;
}
int nDay = 0; /* day counter */
/* subtract data1 offset to 01/01 */
nDay -= dia1;
for(int i = mes1; i > 1; --i) {
nDay -= monthLength(i - 1, ano1);
}
/* add data2 offset to 01/01 */
nDay += dia2;
for(int i = mes2; i > 1; --i) {
nDay += monthLength(i - 1, ano2);
}
/* add year offset */
for(int i = ano2; i > ano1; --i) {
nDay += yearLength(i);
}
cout << "Difference = " << nDay << " days" << endl;

Sudoku Solving Function Explanation

I have been searching for a Sudoku Solving Algorithm for a while and I found this code. But I have some difficulties. I can't understand it. If there are conflicts with all numbers between 1 and 9 in a single cell, the program should stop, right? But it continues. Can somebody explain me how the code works, please? Here it is:
bool Sudoku::Help_Solve(int i, int j)
{
int nextrow, nextcol;
while(change[i][j] == 1) //We find the first cell in which we can change the number
{
j++;
if(j > 9)
{
j = 1;
i++;
}
if(i > 9) return true;
}
for(int p = 1; p <= 9; p++)
{
if(Game.Check_Conflicts(p, i, j)) //We are checking for conflicts
{
board[i][j] = p;
nextrow = i;
nextcol = j+1;
if(nextcol > 9)
{
nextcol = 1;
nextrow++;
}
if(nextcol == 1 && nextrow == 10) return true;
if(Game.Help_Solve(nextrow, nextcol)) return true;
}
}
board[i][j] = 0;
return false;
}
Not enough code to explain properly, what happens in Game.Check_Conflicts(p, i, j), is this function getting called recursively?
Here is the whole code if you want to see it:
#include <iostream>
#include <iomanip>
#include <time.h>
#include <cstdlib>
#include <windows.h>
using namespace std;
class Sudoku
{
private:
int board[9][9];
int change[9][9];
public:
Sudoku();
void Print_Board();
void Add_First_Cord();
bool Help_Solve(int i, int j);
bool Check_Conflicts(int p, int i, int j);
};
Sudoku Game;
void setcolor(unsigned short color) //The function that you'll use to
{ //set the colour
HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hcon,color);
}
Sudoku::Sudoku()
{
for(int i = 0; i <= 9; i++)
for(int j = 0; j <= 9; j++)
board[i][j] = 0;
}
void Sudoku::Print_Board()
{
for(int i = 1; i <= 9; i++)
{
for(int j = 1; j <= 9; j++)
{
if(change[i][j] == 1)
{
setcolor(12);
cout << board[i][j] << " ";
setcolor(7);
}
else cout << board[i][j] << " ";
if(j%3 == 0) cout << "| ";
}
cout << endl;
if(i%3 == 0) cout << "------+-------+--------" << endl;
}
}
void Sudoku::Add_First_Cord()
{
board[1][1] = 5; change[1][1] = 1;
board[1][2] = 3; change[1][2] = 1;
board[1][5] = 7; change[1][5] = 1;
board[2][1] = 6; change[2][1] = 1;
board[2][4] = 1; change[2][4] = 1;
board[2][5] = 9; change[2][5] = 1;
board[2][6] = 5; change[2][6] = 1;
board[3][2] = 9; change[3][2] = 1;
board[3][3] = 8; change[3][3] = 1;
board[3][8] = 6; change[3][8] = 1;
board[4][1] = 8; change[4][1] = 1;
board[4][5] = 6; change[4][5] = 1;
board[4][9] = 3; change[4][9] = 1;
board[5][1] = 4; change[5][1] = 1;
board[5][4] = 8; change[5][4] = 1;
board[5][6] = 3; change[5][6] = 1;
board[5][9] = 1; change[5][9] = 1;
board[6][1] = 7; change[6][1] = 1;
board[6][5] = 2; change[6][5] = 1;
board[6][9] = 6; change[6][9] = 1;
board[7][2] = 6; change[7][2] = 1;
board[7][7] = 2; change[7][7] = 1;
board[7][8] = 8; change[7][8] = 1;
board[8][4] = 4; change[8][4] = 1;
board[8][5] = 1; change[8][5] = 1;
board[8][6] = 9; change[8][6] = 1;
board[8][9] = 5; change[8][9] = 1;
board[9][5] = 8; change[9][5] = 1;
board[9][8] = 7; change[9][8] = 1;
board[9][9] = 9; change[9][9] = 1;
}
bool Sudoku::Check_Conflicts(int p, int i, int j)
{
for(int k = 1; k <= 9; k++)
if(board[i][k] == p) return false;
for(int q = 1; q <= 9; q++)
if(board[q][j] == p) return false;
/*
*00
000
000
*/
if((j == 1 || j == 4 || j == 7) && (i == 1 || i == 4 || i == 7))
{
if(board[i][j+1] == p || board[i][j+2] == p || board[i+1][j] == p ||
board[i+2][j] == p || board[i+1][j+1] == p || board[i+1][j+2] == p ||
board[i+2][j+1] == p || board[i+2][j+2] == p)return false;
}
/*
000
000
*00
*/
if((j == 1 || j == 4 || j == 7) && (i == 3 || i == 6 || i == 9))
{
if(board[i-1][j] == p || board[i-2][j] == p || board[i][j+1] == p ||
board[i][j+2] == p || board[i-1][j+1] == p || board[i-1][j+2] == p ||
board[i-2][j+1] == p || board[i-2][j+2] == p)return false;
}
/*
000
*00
000
*/
if((j == 1 || j == 4 || j == 7) && (i == 2 || i == 5 || i == 8))
{
if(board[i-1][j] == p || board[i-1][j+1] == p || board[i-1][j+2] == p ||
board[i][j+1] == p || board[i][j+2] == p || board[i+1][j] == p ||
board[i+1][j+1] == p || board[i+1][j+2] == p)return false;
}
/*
0*0
000
000
*/
if((j == 2 || j == 5 || j == 8) && (i == 1 || i == 4 || i == 7))
{
if(board[i][j-1] == p || board[i][j+1] == p || board[i+1][j+1] == p ||
board[i+1][j-1] == p || board[i+1][j] == p || board[i+2][j-1] == p ||
board[i+2][j] == p || board[i+2][j+1] == p)return false;
}
/*
000
0*0
000
*/
if((j == 2 || j == 5 || j == 8) && (i == 2 || i == 5 || i == 8))
{
if(board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j+1] == p ||
board[i][j+1] == p || board[i][j-1] == p || board[i+1][j+1] == p ||
board[i+1][j] == p || board[i+1][j-1] == p)return false;
}
/*
000
000
0*0
*/
if((j == 2 || j == 5 || j == 8) && (i == 3 || i == 6 || i == 9))
{
if(board[i][j-1] == p || board[i][j+1] == p || board[i-1][j] == p ||
board[i-1][j+1] == p || board[i-1][j-1] == p || board[i-2][j] == p ||
board[i-2][j+1] == p || board[i-2][j-1] == p) return false;
}
/*
00*
000
000
*/
if((j == 3 || j == 6 || j == 9) && (i == 1 || i == 4 || i == 7))
{
if(board[i][j-1] == p || board[i][j-2] == p || board[i+1][j] == p ||
board[i+1][j-1] == p || board[i+1][j-2] == p || board[i+2][j] == p ||
board[i+2][j-1] == p || board[i+2][j-2] == p) return false;
}
/*
000
00*
000
*/
if((j == 3 || j == 6 || j == 9) && (i == 2 || i == 5 || i == 8))
{
if(board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j-2] == p ||
board[i][j-1] == p || board[i][j-2] == p || board[i+1][j] == p ||
board[i+1][j-1] == p || board[i+1][j-2] == p) return false;
}
/*
000
000
00*
*/
if((j == 3 || j == 6 || j == 9) && (i == 3 || i == 6 || i == 9))
{
if(board[i][j-1] == p || board[i][j-2] == p || board[i-1][j] == p ||
board[i-1][j-1] == p || board[i-1][j-2] == p || board[i-2][j] == p ||
board[i-2][j-1] == p || board[i-2][j-2] == p) return false;
}
return true;
}
bool Sudoku::Help_Solve(int i, int j)
{
int nextrow, nextcol;
while(change[i][j] == 1)
{
j++;
if(j > 9)
{
j = 1;
i++;
}
if(i > 9) return true;
}
for(int p = 1; p <= 9; p++)
{
if(Game.Check_Conflicts(p, i, j))
{
board[i][j] = p;
nextrow = i;
nextcol = j+1;
if(nextcol > 9)
{
nextcol = 1;
nextrow++;
}
if(nextcol == 1 && nextrow == 10) return true;
if(Game.Help_Solve(nextrow, nextcol)) return true;
}
}
board[i][j] = 0;
return false;
}
int main()
{
Game.Add_First_Cord();
Game.Help_Solve(1, 1);
Game.Print_Board();
system("pause");
return 0;
}
It looks like Sudoku::Check_Conflicts returns true if the number CAN be placed there, or false if it CAN'T be placed there due to a simple conflict. A different function name could maybe better self-document the code.
The thing is rhat I can't understand why it continues if in the end it
returns false :/
It doesn't ALWAYS return at the bottom of the function tho':
bool Sudoku::Help_Solve(int i, int j)
{
int nextrow, nextcol;
while(change[i][j] == 1) //We find the first cell in which we can change the number
{
j++;
if(j > 9)
{
j = 1;
i++;
}
if(i > 9) return true;
-------------------------^^^^
returns true if we have filled all squares.
}
for(int p = 1; p <= 9; p++)
{
if(Game.Check_Conflicts(p, i, j)) //We are checking for conflicts
{
board[i][j] = p;
nextrow = i;
nextcol = j+1;
if(nextcol > 9)
{
nextcol = 1;
nextrow++;
}
if(nextcol == 1 && nextrow == 10) return true;
-----------------------------------------------------^^^^
returns when we have filled everything!
if(Game.Help_Solve(nextrow, nextcol)) return true;
---------------------------------------------------------^^^^
returns if we filled at the next level of solution.
}
}
board[i][j] = 0;
return false;
-----------^^^^^ returns if we failed to fill the whole thing.
}
As someone else mentioned in a comment, there are some trivial things that can be done to improve on the algorithm - such as looking for the "most suitable place to fill first" [which doesn't improve the worst case, but it does improve the typical case].
I have written a Sudoku solver that uses a similar algorithm, but it tries to find the cell with the lowest number of candidates (possible numbers to go in the that cell) and only tries recursively if there are multiple choices.