Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add given cells option and generate seed for random without using time value #15

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/configure.ac
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
AC_PREREQ(2.59)
AC_INIT(qqwing, 1.3.4, http://qqwing.com/)
AC_INIT(qqwing, 1.3.6, http://qqwing.com/)
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADER([config.h])
Expand Down
2 changes: 1 addition & 1 deletion build/src_neaten.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ then
touch --date 1980-01-01 $neaten_time_file
fi

find build/ doc/ src/ test/ Makefile -type f -newer $neaten_time_file | grep -vEi 'changelog|copyright|COPYING|README|\.gif|\.png|\.jpg$' | xargs ./build/src_neaten.pl
find build/ doc/ src/ test/ Makefile -type f -newer $neaten_time_file | grep -vEi 'changelog|copyright|COPYING|README|\.gif|\.png|\.jpg|\.gch$' | xargs ./build/src_neaten.pl

touch $neaten_time_file
31 changes: 30 additions & 1 deletion src/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ bool readPuzzleFromStdIn(int* puzzle);
void printHelp();
void printVersion();
void printAbout();
unsigned long generateSeed(unsigned long a, unsigned long b, unsigned long c);

/**
* Main method -- the entry point into the program.
Expand Down Expand Up @@ -69,6 +70,7 @@ int main(int argc, char *argv[]){
SudokuBoard::PrintStyle printStyle = SudokuBoard::READABLE;
int numberToGenerate = 1;
bool printStats = false;
int givenCells = 0;
SudokuBoard::Difficulty difficulty = SudokuBoard::UNKNOWN;
SudokuBoard::Symmetry symmetry = SudokuBoard::NONE;

Expand Down Expand Up @@ -155,6 +157,17 @@ int main(int argc, char *argv[]){
return 1;
}
i++;
} else if (!strcmp(argv[i],"--given-cells")){
if (argc <= i+1){
cout << "Please specify a number of given cells between 0 and " << BOARD_SIZE << "." << endl;
return 1;
}
givenCells = atoi(argv[i+1]);
if (givenCells < 0 || givenCells > BOARD_SIZE){
cout << "number of given cells expected to be in range [0-" << BOARD_SIZE << "]. receive: " << givenCells << endl;
return 1;
}
i++;
} else if (!strcmp(argv[i],"--solve")){
action = SOLVE;
printSolution = true;
Expand Down Expand Up @@ -201,7 +214,7 @@ int main(int argc, char *argv[]){
}

// Initialize the random number generator
srand ( unsigned ( time(0) ) );
srand (generateSeed(clock(), time(NULL), getpid()));

// If printing out CSV, print a header
if (printStyle == SudokuBoard::CSV){
Expand All @@ -221,6 +234,7 @@ int main(int argc, char *argv[]){
ss->setRecordHistory(printHistory || printInstructions || printStats || difficulty!=SudokuBoard::UNKNOWN);
ss->setLogHistory(logHistory);
ss->setPrintStyle(printStyle);
ss->setNbGivenCells(givenCells);

// Solve puzzle or generate puzzles
// until end of input for solving, or
Expand Down Expand Up @@ -451,6 +465,7 @@ void printHelp(){
cout << " --solve Solve all the puzzles from standard input" << endl;
cout << " --difficulty <diff> Generate only simple, easy, intermediate, expert, or any" << endl;
cout << " --symmetry <sym> Symmetry: none, rotate90, rotate180, mirror, flip, or random" << endl;
cout << " --given-cells <num> Number of given cells according to sudoku games." << endl;
cout << " --puzzle Print the puzzle (default when generating)" << endl;
cout << " --nopuzzle Do not print the puzzle (default when solving)" << endl;
cout << " --solution Print the solution (default when solving)" << endl;
Expand Down Expand Up @@ -514,3 +529,17 @@ long getMicroseconds(){
return 0;
#endif
}

// http://burtleburtle.net/bob/hash/doobs.html
unsigned long generateSeed(unsigned long a, unsigned long b, unsigned long c){
a=a-b; a=a-c; a=a^(c >> 13);
b=b-c; b=b-a; b=b^(a << 8);
c=c-a; c=c-b; c=c^(b >> 13);
a=a-b; a=a-c; a=a^(c >> 12);
b=b-c; b=b-a; b=b^(a << 16);
c=c-a; c=c-b; c=c^(b >> 5);
a=a-b; a=a-c; a=a^(c >> 3);
b=b-c; b=b-a; b=b^(a << 10);
c=c-a; c=c-b; c=c^(b >> 15);
return c;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does not appear to be licensed in a way that is compatible with the GPLv2. This patch cannot be accepted with this function included.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"You may use this code any way you wish, private, educational, or commercial. It's free." - this code is public domain and compatible with GPLv2. Not sure you need that complex seed generator though

12 changes: 10 additions & 2 deletions src/cpp/qqwing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ namespace qqwing {
solveHistory ( new vector<LogItem*>() ),
solveInstructions ( new vector<LogItem*>() ),
printStyle ( READABLE ),
lastSolveRound (0)
lastSolveRound (0),
nbGivenCells (0)
{
{for (int i=0; i<BOARD_SIZE; i++){
randomBoardArray[i] = i;
Expand All @@ -143,6 +144,10 @@ namespace qqwing {
return count;
}

void SudokuBoard::setNbGivenCells(int givenCells){
nbGivenCells = givenCells;
};

/**
* Set the board to the given puzzle.
* The given puzzle must be an array of 81 integers.
Expand Down Expand Up @@ -344,7 +349,7 @@ namespace qqwing {
// Even when starting from an empty grid
solve();

if (symmetry == SudokuBoard::NONE){
if (symmetry == SudokuBoard::NONE && nbGivenCells < (BOARD_SIZE / 2)){
// Rollback any square for which it is obvious that
// the square doesn't contribute to a unique solution
// (ie, squares that were filled by logic rather
Expand All @@ -367,6 +372,9 @@ namespace qqwing {
// If it does, leave it out the point because
// it is not needed.
{for (int i=0; i<BOARD_SIZE; i++){
if (getGivenCount() <= nbGivenCells) {
break;
}
// check all the positions, but in shuffled order
int position = randomBoardArray[i];
if (puzzle[position] > 0){
Expand Down
7 changes: 7 additions & 0 deletions src/cpp/qqwing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
void setRecordHistory(bool recHistory);
void setLogHistory(bool logHist);
void setPrintStyle(PrintStyle ps);
void setNbGivenCells(int nbGivenCells);
bool generatePuzzle();
bool generatePuzzleSymmetry(SudokuBoard::Symmetry symmetry);
int getGivenCount();
Expand Down Expand Up @@ -204,6 +205,12 @@
* The last round of solving
*/
int lastSolveRound;

/**
* expected number of given cells
*/
int nbGivenCells;

bool reset();
bool singleSolveMove(int round);
bool onlyPossibilityForCell(int round);
Expand Down
1 change: 1 addition & 0 deletions test/app/help.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Sudoku solver and generator.
--solve Solve all the puzzles from standard input
--difficulty <diff> Generate only simple, easy, intermediate, expert, or any
--symmetry <sym> Symmetry: none, rotate90, rotate180, mirror, flip, or random
--given-cells <num> Number of given cells according to sudoku games.
--puzzle Print the puzzle (default when generating)
--nopuzzle Do not print the puzzle (default when solving)
--solution Print the solution (default when solving)
Expand Down