bool BoardGenerator::handleNakedPairs(int round){ for (int position=0; position<BOARD_SIZE; position++){ int possibilities = countPossibilities(position); if (possibilities == 2){ int row = cellToRow(position); int column = cellToColumn(position); int section = cellToSectionStartCell(position); for (int position2=position; position2<BOARD_SIZE; position2++){ if (position != position2){ int possibilities2 = countPossibilities(position2); if (possibilities2 == 2 && arePossibilitiesSame(position, position2)){ if (row == cellToRow(position2)){ bool doneSomething = false; for (int column2=0; column2<9; column2++){ int position3 = rowColumnToCell(row,column2); if (position3 != position && position3 != position2 && removePossibilitiesInOneFromTwo(position, position3, round)){ doneSomething = true; } } if (doneSomething){ if (recordHistory) addHistoryItem(new LogItem(round, LogItem::NAKED_PAIR_ROW, 0, position)); return true; } } if (column == cellToColumn(position2)){ bool doneSomething = false; for (int row2=0; row2<9; row2++){ int position3 = rowColumnToCell(row2,column); if (position3 != position && position3 != position2 && removePossibilitiesInOneFromTwo(position, position3, round)){ doneSomething = true; } } if (doneSomething){ if (recordHistory) addHistoryItem(new LogItem(round, LogItem::NAKED_PAIR_COLUMN, 0, position)); return true; } } if (section == cellToSectionStartCell(position2)){ bool doneSomething = false; int secStart = cellToSectionStartCell(position); {for (int i=0; i<3; i++){ for (int j=0; j<3; j++){ int position3=secStart+i+(9*j); if (position3 != position && position3 != position2 && removePossibilitiesInOneFromTwo(position, position3, round)){ doneSomething = true; } } }} if (doneSomething){ if (recordHistory) addHistoryItem(new LogItem(round, LogItem::NAKED_PAIR_SECTION, 0, position)); return true; } } } } } } } return false; }
/** * Reset the board to its initial state with * only the givens. * This method clears any solution, resets statistics, * and clears any history messages. */ bool BoardGenerator::reset(){ {for (int i=0; i<BOARD_SIZE; i++){ solution[i] = 0; }} {for (int i=0; i<BOARD_SIZE; i++){ solutionRound[i] = 0; }} {for (int i=0; i<POSSIBILITY_SIZE; i++){ possibilities[i] = 0; }} {for (vector<LogItem*>::size_type i=0;i<solveHistory->size();i++){ delete solveHistory->at(i); }} solveHistory->clear(); solveInstructions->clear(); int round = 1; for (int position=0; position<BOARD_SIZE; position++){ if (puzzle[position] > 0){ int valIndex = puzzle[position]-1; int valPos = getPossibilityIndex(valIndex,position); int value = puzzle[position]; if (possibilities[valPos] != 0) return false; mark(position,round,value); if (recordHistory) addHistoryItem(new LogItem(round, LogItem::GIVEN, value, position)); } } return true; }
/** * Mark exactly one cell which is the only possible value for some section, if * such a cell exists. * This method will look in a section for a possibility that is only listed * for one cell. This type of cell is often called a "hidden single" */ bool BoardGenerator::onlyValueInSection(int round){ for (int sec=0; sec<SEC_COUNT; sec++){ int secPos = sectionToFirstCell(sec); for (int valIndex=0; valIndex<NUM_POSS; valIndex++){ int count = 0; int lastPosition = 0; {for (int i=0; i<3; i++){ for (int j=0; j<3; j++){ int position = secPos + i + 9*j; int valPos = getPossibilityIndex(valIndex,position); if (possibilities[valPos] == 0){ count++; lastPosition = position; } } }} if (count == 1){ int value = valIndex+1; if (recordHistory) addHistoryItem(new LogItem(round, LogItem::HIDDEN_SINGLE_SECTION, value, lastPosition)); mark(lastPosition, round, value); return true; } } } return false; }
int main(int argc, char *argv[]) { int i, *a; historyItem *h; setHistoryLimit(15); for (i=0;i < 6; i++) { a = (int *)malloc(sizeof(int)); *a = i; h = newHistoryItem(a); addHistoryItem(h); } /* Start at the beginning */ setHistoryIndex(numHistoryItems()); while ((h = nextHistoryItem(0)) != NULL) { printf("h[%d]->a is %d\n", getHistoryIndex(), *(int *)h->data); } printf("Doing the reverse now...\n"); setHistoryIndex(3); for (i=0;i<6;i++) { h = prevHistoryItem(1); if (h) printf("h[%d]->a is %d\n", getHistoryIndex(), *(int *)h->data); } return 0; }
void HistoryManager::addHistoryEntry(const QString &url) { QUrl cleanUrl(url); cleanUrl.setPassword(QString()); cleanUrl.setHost(cleanUrl.host().toLower()); HistoryItem item(cleanUrl.toString(), QDateTime::currentDateTime()); addHistoryItem(item); }
bool BoardGenerator::rowBoxReduction(int round){ for (int valIndex=0; valIndex<NUM_POSS; valIndex++){ for (int row=0; row<9; row++){ int rowStart = rowToFirstCell(row); bool inOneBox = true; int rowBox = -1; {for (int i=0; i<3; i++){ for (int j=0; j<3; j++){ int column = i*3+j; int position = rowColumnToCell(row, column); int valPos = getPossibilityIndex(valIndex,position); if(possibilities[valPos] == 0){ if (rowBox == -1 || rowBox == i){ rowBox = i; } else { inOneBox = false; } } } }} if (inOneBox && rowBox != -1){ bool doneSomething = false; int column = 3*rowBox; int secStart = cellToSectionStartCell(rowColumnToCell(row, column)); int secStartRow = cellToRow(secStart); int secStartCol = cellToColumn(secStart); {for (int i=0; i<3; i++){ for (int j=0; j<3; j++){ int row2 = secStartRow+i; int col2 = secStartCol+j; int position = rowColumnToCell(row2, col2); int valPos = getPossibilityIndex(valIndex,position); if (row != row2 && possibilities[valPos] == 0){ possibilities[valPos] = round; doneSomething = true; } } }} if (doneSomething){ if (recordHistory) addHistoryItem(new LogItem(round, LogItem::ROW_BOX, valIndex+1, rowStart)); return true; } } } } return false; }
bool BoardGenerator::guess(int round, int guessNumber){ int localGuessCount = 0; int position = findPositionWithFewestPossibilities(); {for (int i=0; i<NUM_POSS; i++){ int valIndex = randomPossibilityArray[i]; int valPos = getPossibilityIndex(valIndex,position); if (possibilities[valPos] == 0){ if (localGuessCount == guessNumber){ int value = valIndex+1; if (recordHistory) addHistoryItem(new LogItem(round, LogItem::GUESS, value, position)); mark(position, round, value); return true; } localGuessCount++; } }} return false; }
void BoardGenerator::rollbackRound(int round){ if (recordHistory) addHistoryItem(new LogItem(round, LogItem::ROLLBACK)); {for (int i=0; i<BOARD_SIZE; i++){ if (solutionRound[i] == round){ solutionRound[i] = 0; solution[i] = 0; } }} {for (int i=0; i<POSSIBILITY_SIZE; i++){ if (possibilities[i] == round){ possibilities[i] = 0; } }} while(solveInstructions->size() > 0 && solveInstructions->back()->getRound() == round){ solveInstructions->pop_back(); } }
bool BoardGenerator::pointingColumnReduction(int round){ for (int valIndex=0; valIndex<NUM_POSS; valIndex++){ for (int section=0; section<9; section++){ int secStart = sectionToFirstCell(section); bool inOneCol = true; int boxCol = -1; {for (int i=0; i<3; i++){ for (int j=0; j<3; j++){ int secVal=secStart+i+(9*j); int valPos = getPossibilityIndex(valIndex,secVal); if(possibilities[valPos] == 0){ if (boxCol == -1 || boxCol == i){ boxCol = i; } else { inOneCol = false; } } } }} if (inOneCol && boxCol != -1){ bool doneSomething = false; int col = cellToColumn(secStart) + boxCol; int colStart = columnToFirstCell(col); {for (int i=0; i<9; i++){ int position = colStart+(9*i); int section2 = cellToSection(position); int valPos = getPossibilityIndex(valIndex,position); if (section != section2 && possibilities[valPos] == 0){ possibilities[valPos] = round; doneSomething = true; } }} if (doneSomething){ if (recordHistory) addHistoryItem(new LogItem(round, LogItem::POINTING_PAIR_TRIPLE_COLUMN, valIndex+1, colStart)); return true; } } } } return false; }
bool BoardGenerator::pointingRowReduction(int round){ for (int valIndex=0; valIndex<NUM_POSS; valIndex++){ for (int section=0; section<9; section++){ int secStart = sectionToFirstCell(section); bool inOneRow = true; int boxRow = -1; for (int j=0; j<3; j++){ {for (int i=0; i<3; i++){ int secVal=secStart+i+(9*j); int valPos = getPossibilityIndex(valIndex,secVal); if(possibilities[valPos] == 0){ if (boxRow == -1 || boxRow == j){ boxRow = j; } else { inOneRow = false; } } }} } if (inOneRow && boxRow != -1){ bool doneSomething = false; int row = cellToRow(secStart) + boxRow; int rowStart = rowToFirstCell(row); {for (int i=0; i<9; i++){ int position = rowStart+i; int section2 = cellToSection(position); int valPos = getPossibilityIndex(valIndex,position); if (section != section2 && possibilities[valPos] == 0){ possibilities[valPos] = round; doneSomething = true; } }} if (doneSomething){ if (recordHistory) addHistoryItem(new LogItem(round, LogItem::POINTING_PAIR_TRIPLE_ROW, valIndex+1, rowStart)); return true; } } } } return false; }
/** * Mark exactly one cell that has a single possibility, if such a cell exists. * This method will look for a cell that has only one possibility. This type * of cell is often called a "single" */ bool BoardGenerator::onlyPossibilityForCell(int round){ for (int position=0; position<BOARD_SIZE; position++){ if (solution[position] == 0){ int count = 0; int lastValue = 0; for (int valIndex=0; valIndex<NUM_POSS; valIndex++){ int valPos = getPossibilityIndex(valIndex,position); if (possibilities[valPos] == 0){ count++; lastValue=valIndex+1; } } if (count == 1){ mark(position, round, lastValue); if (recordHistory) addHistoryItem(new LogItem(round, LogItem::SINGLE, lastValue, position)); return true; } } } return false; }
/** * Mark exactly one cell which is the only possible value for some column, if * such a cell exists. * This method will look in a column for a possibility that is only listed * for one cell. This type of cell is often called a "hidden single" */ bool BoardGenerator::onlyValueInColumn(int round){ for (int col=0; col<COL_HEIGHT; col++){ for (int valIndex=0; valIndex<NUM_POSS; valIndex++){ int count = 0; int lastPosition = 0; for (int row=0; row<ROW_LENGTH; row++){ int position = rowColumnToCell(row,col); int valPos = getPossibilityIndex(valIndex,position); if (possibilities[valPos] == 0){ count++; lastPosition = position; } } if (count == 1){ int value = valIndex+1; if (recordHistory) addHistoryItem(new LogItem(round, LogItem::HIDDEN_SINGLE_COLUMN, value, lastPosition)); mark(lastPosition, round, value); return true; } } } return false; }
bool BoardGenerator::hiddenPairInRow(int round){ for (int row=0; row<9; row++){ for (int valIndex=0; valIndex<9; valIndex++){ int c1 = -1; int c2 = -1; int valCount = 0; for (int column=0; column<9; column++){ int position = rowColumnToCell(row,column); int valPos = getPossibilityIndex(valIndex,position); if (possibilities[valPos] == 0){ if (c1 == -1 || c1 == column){ c1 = column; } else if (c2 == -1 || c2 == column){ c2 = column; } valCount++; } } if (valCount==2){ for (int valIndex2=valIndex+1; valIndex2<9; valIndex2++){ int c3 = -1; int c4 = -1; int valCount2 = 0; for (int column=0; column<9; column++){ int position = rowColumnToCell(row,column); int valPos = getPossibilityIndex(valIndex2,position); if (possibilities[valPos] == 0){ if (c3 == -1 || c3 == column){ c3 = column; } else if (c4 == -1 || c4 == column){ c4 = column; } valCount2++; } } if (valCount2==2 && c1==c3 && c2==c4){ bool doneSomething = false; for (int valIndex3=0; valIndex3<9; valIndex3++){ if (valIndex3 != valIndex && valIndex3 != valIndex2){ int position1 = rowColumnToCell(row,c1); int position2 = rowColumnToCell(row,c2); int valPos1 = getPossibilityIndex(valIndex3,position1); int valPos2 = getPossibilityIndex(valIndex3,position2); if (possibilities[valPos1] == 0){ possibilities[valPos1] = round; doneSomething = true; } if (possibilities[valPos2] == 0){ possibilities[valPos2] = round; doneSomething = true; } } } if (doneSomething){ if (recordHistory) addHistoryItem(new LogItem(round, LogItem::HIDDEN_PAIR_ROW, valIndex+1, rowColumnToCell(row,c1))); return true; } } } } } } return false; }
bool BoardGenerator::hiddenPairInSection(int round){ for (int section=0; section<9; section++){ for (int valIndex=0; valIndex<9; valIndex++){ int si1 = -1; int si2 = -1; int valCount = 0; for (int secInd=0; secInd<9; secInd++){ int position = sectionToCell(section,secInd); int valPos = getPossibilityIndex(valIndex,position); if (possibilities[valPos] == 0){ if (si1 == -1 || si1 == secInd){ si1 = secInd; } else if (si2 == -1 || si2 == secInd){ si2 = secInd; } valCount++; } } if (valCount==2){ for (int valIndex2=valIndex+1; valIndex2<9; valIndex2++){ int si3 = -1; int si4 = -1; int valCount2 = 0; for (int secInd=0; secInd<9; secInd++){ int position = sectionToCell(section,secInd); int valPos = getPossibilityIndex(valIndex2,position); if (possibilities[valPos] == 0){ if (si3 == -1 || si3 == secInd){ si3 = secInd; } else if (si4 == -1 || si4 == secInd){ si4 = secInd; } valCount2++; } } if (valCount2==2 && si1==si3 && si2==si4){ bool doneSomething = false; for (int valIndex3=0; valIndex3<9; valIndex3++){ if (valIndex3 != valIndex && valIndex3 != valIndex2){ int position1 = sectionToCell(section,si1); int position2 = sectionToCell(section,si2); int valPos1 = getPossibilityIndex(valIndex3,position1); int valPos2 = getPossibilityIndex(valIndex3,position2); if (possibilities[valPos1] == 0){ possibilities[valPos1] = round; doneSomething = true; } if (possibilities[valPos2] == 0){ possibilities[valPos2] = round; doneSomething = true; } } } if (doneSomething){ if (recordHistory) addHistoryItem(new LogItem(round, LogItem::HIDDEN_PAIR_SECTION, valIndex+1, sectionToCell(section,si1))); return true; } } } } } } return false; }
bool BoardGenerator::hiddenPairInColumn(int round){ for (int column=0; column<9; column++){ for (int valIndex=0; valIndex<9; valIndex++){ int r1 = -1; int r2 = -1; int valCount = 0; for (int row=0; row<9; row++){ int position = rowColumnToCell(row,column); int valPos = getPossibilityIndex(valIndex,position); if (possibilities[valPos] == 0){ if (r1 == -1 || r1 == row){ r1 = row; } else if (r2 == -1 || r2 == row){ r2 = row; } valCount++; } } if (valCount==2){ for (int valIndex2=valIndex+1; valIndex2<9; valIndex2++){ int r3 = -1; int r4 = -1; int valCount2 = 0; for (int row=0; row<9; row++){ int position = rowColumnToCell(row,column); int valPos = getPossibilityIndex(valIndex2,position); if (possibilities[valPos] == 0){ if (r3 == -1 || r3 == row){ r3 = row; } else if (r4 == -1 || r4 == row){ r4 = row; } valCount2++; } } if (valCount2==2 && r1==r3 && r2==r4){ bool doneSomething = false; for (int valIndex3=0; valIndex3<9; valIndex3++){ if (valIndex3 != valIndex && valIndex3 != valIndex2){ int position1 = rowColumnToCell(r1,column); int position2 = rowColumnToCell(r2,column); int valPos1 = getPossibilityIndex(valIndex3,position1); int valPos2 = getPossibilityIndex(valIndex3,position2); if (possibilities[valPos1] == 0){ possibilities[valPos1] = round; doneSomething = true; } if (possibilities[valPos2] == 0){ possibilities[valPos2] = round; doneSomething = true; } } } if (doneSomething){ if (recordHistory) addHistoryItem(new LogItem(round, LogItem::HIDDEN_PAIR_COLUMN, valIndex+1, rowColumnToCell(r1,column))); return true; } } } } } } return false; }
/** * The Xinu shell. Provides an interface to execute commands. * @param descrp descriptor of device on which the shell is open * @return OK for successful exit, SYSERR for unrecoverable error */ thread shell(int indescrp, int outdescrp, int errdescrp) { char buf[SHELL_BUFLEN]; /* line input buffer */ short buflen; /* length of line input */ char tokbuf[SHELL_BUFLEN + SHELL_MAXTOK]; /* token value buffer */ short ntok; /* number of tokens */ char *tok[SHELL_MAXTOK]; /* pointers to token values */ char *outname; /* name of output file */ char *inname; /* name of input file */ bool background; /* is background proccess? */ syscall child; /* pid of child thread */ ushort i, j; /* temp variables */ irqmask im; /* interrupt mask state */ /* hostname variables */ char hostnm[NET_HOSTNM_MAXLEN + 1]; /* hostname of backend */ char *hostptr; /* pointer to hostname */ int hostname_strsz; /* nvram hostname name size */ device *devptr; /* device pointer */ printf( "Welcome to the shell!\n" ); /* Enable interrupts */ enable(); hostptr = NULL; devptr = NULL; hostname_strsz = 0; bzero(hostnm, NET_HOSTNM_MAXLEN + 1); /* Setup buffer for string for nvramGet call for hostname */ #ifdef ETH0 if (!isbaddev(ETH0)) { /* Determine the hostname of the main network device */ devptr = (device *)&devtab[ETH0]; hostname_strsz = strnlen(NET_HOSTNAME, NVRAM_STRMAX) + 1; hostname_strsz += DEVMAXNAME; char nvramget_hostname_str[hostname_strsz]; sprintf(nvramget_hostname_str, "%s_%s", devptr->name, NET_HOSTNAME); /* Acquire the backend's hostname */ #if NVRAM hostptr = nvramGet(nvramget_hostname_str); #endif /* NVRAM */ if (hostptr != NULL) { memcpy(hostnm, hostptr, NET_HOSTNM_MAXLEN); hostptr = hostnm; } } #endif /* Set command devices for input, output, and error */ stdin = indescrp; stdout = outdescrp; stderr = errdescrp; /* Print shell banner */ printf(SHELL_BANNER); /* Print shell welcome message */ printf(SHELL_START); /* Continually receive and handle commands */ while (TRUE) { /* Display prompt */ printf(SHELL_PROMPT); if (NULL != hostptr) { printf("@%s$ ", hostptr); } else { printf("$ "); } /* Setup proper tty modes for input and output */ control(stdin, TTY_CTRL_CLR_IFLAG, TTY_IRAW, NULL); control(stdin, TTY_CTRL_SET_IFLAG, TTY_ECHO, NULL); /* Null out the buf and read command */ memset(buf, '\0', SHELL_BUFLEN); buflen = shellRead(stdin, buf, SHELL_BUFLEN); if(buf[0] != '!') { addHistoryItem(buf, buflen); } /* Check for EOF and exit gracefully if seen */ if (EOF == buflen) { break; } // Check for indicator of history command if (buf[0] == '!') { int index; // handler for !! (just execute most recent command) if(buf[1] == '!') { index = 0; } else { // extract the number string char indexString[buflen]; strncpy(indexString, &buf[1], buflen - 1); indexString[buflen] = '\0'; // convert number string into a valid index // calculation is done because the index numbers // are reverse of their numbers printed using 'history' index = numHistoryItems - atoi(indexString); } //replace buf and buflen with the last command strncpy(buf, history[index].command, SHELL_BUFLEN); buflen = history[index].commandLength + 1; } /* Parse line input into tokens */ if (SYSERR == (ntok = lexan(buf, buflen, &tokbuf[0], &tok[0]))) { fprintf(stderr, SHELL_SYNTAXERR); continue; } /* Ensure parse generated tokens */ if (0 == ntok) { continue; } /* Initialize command options */ inname = NULL; outname = NULL; background = FALSE; /* Mark as background thread, if last token is '&' */ if ('&' == *tok[ntok - 1]) { ntok--; background = TRUE; } /* Check each token and perform special handling of '>' and '<' */ for (i = 0; i < ntok; i++) { /* Background '&' should have already been handled; Syntax error */ if ('&' == *tok[i]) { ntok = -1; break; } /* Setup for output redirection if token is '>' */ if ('>' == *tok[i]) { /* Syntax error */ if (outname != NULL || i >= ntok - 1) { ntok = -1; break; } outname = tok[i + 1]; ntok -= 2; /* shift tokens (not to be passed to command */ for (j = i; j < ntok; j++) { tok[j] = tok[j + 2]; } continue; } /* Setup for input redirection if token is '<' */ if ('<' == *tok[i]) { /* Syntax error */ if (inname != NULL || i >= ntok - 1) { ntok = -1; break; } inname = tok[i + 1]; ntok -= 2; /* shift tokens (not to be passed to command */ for (j = i; j < ntok; j++) { tok[j] = tok[j + 2]; } continue; } } /* Handle syntax error */ if (ntok <= 0) { fprintf(stderr, SHELL_SYNTAXERR); continue; } /* Lookup first token in the command table */ for (i = 0; i < ncommand; i++) { if (0 == strncmp(commandtab[i].name, tok[0], SHELL_BUFLEN)) { break; } } /* Handle command not found */ if (i >= ncommand) { fprintf(stderr, "%s: command not found\n", tok[0]); continue; } /* Handle command if it is built-in */ if (commandtab[i].builtin) { if (inname != NULL || outname != NULL || background) { fprintf(stderr, SHELL_SYNTAXERR); } else { (*commandtab[i].procedure) (ntok, tok); } continue; } /* Spawn child thread for non-built-in commands */ child = create(commandtab[i].procedure, SHELL_CMDSTK, SHELL_CMDPRIO, commandtab[i].name, 2, ntok, tok); /* Ensure child command thread was created successfully */ if (SYSERR == child) { fprintf(stderr, SHELL_CHILDERR); continue; } /* Set file descriptors for newly created thread */ if (NULL == inname) { thrtab[child].fdesc[0] = stdin; } else { thrtab[child].fdesc[0] = getdev(inname); } if (NULL == outname) { thrtab[child].fdesc[1] = stdout; } else { thrtab[child].fdesc[1] = getdev(outname); } thrtab[child].fdesc[2] = stderr; if (background) { /* Make background thread ready, but don't reschedule */ im = disable(); ready(child, RESCHED_NO); restore(im); } else { /* Clear waiting message; Reschedule; */ while (recvclr() != NOMSG); im = disable(); ready(child, RESCHED_YES); restore(im); /* Wait for command thread to finish */ while (receive() != child); sleep(10); } } /* Close shell */ fprintf(stdout, SHELL_EXIT); sleep(10); return OK; }