I wanted to give a Christmas present to the user group, to thank everyone for all the information that I have gathered over the years. So here is a program to solve Sudoku puzzles. Just like most of my programs, the user interface is the pits. And of course, it's not complete either. It handles the "Easy" and "Medium" difficulty puzzles, but is pretty spotty on "Difficult" puzzles.
Copy and paste, compile, I hope it works ok. Enjoy, Merry Christmas, Happy Hanukkah, Kwanzaa, Eid al-Fitr, etc. ********************************************** BIG.ARRAY = '' EMPTY.ARRAY = '' POSSIBLE.ARRAY = '' STARTING.ARRAY = '' * * Print the opening screen * PRINT @(-1) FOR I = 1 TO 9 PRINT ' ':STR('-',37) PRINT ' | | | | | | | | | |' NEXT I PRINT ' ':STR('-',37) * * Input the starting numbers * PROMPT '' FOR I = 1 TO 9 FOR J = 1 TO 9 PRINT @(J * 4,I * 2):;INPUT NUMBER STARTING.ARRAY<I,J> = NUMBER EMPTY.ARRAY<I,J> = '' NEXT J NEXT I PRINT;PRINT 'Starting Puzzle' PRINT FOR I = 1 TO 9 FOR J = 1 TO 9 PRINT STARTING.ARRAY<I,J> 'R#1 ': NEXT J PRINT NEXT I PRINT;PRINT BIG.ARRAY = STARTING.ARRAY LOOP POSSIBLE.ARRAY = EMPTY.ARRAY * * Find the easy ones. Start with 123456789, remove any hits. If only one number remains, it must belong * to the cell. * FOR ROW = 1 TO 9 FOR COLUMN = 1 TO 9 GOSUB FIRST.CHECK NEXT J NEXT I * * Check each 3x3 square, by eliminating numbers that are outside the square * FOR SQ.ROW = 1 TO 7 STEP 3 FOR SQ.COLUMN = 1 TO 7 STEP 3 GOSUB SECOND.CHECK NEXT SQ.COLUMN NEXT SQ.ROW GOSUB CHECK.ARRAY IF ERROR.FLAG THEN PRINT;PRINT 'Try again?':;INPUT TI IF TI = 'D' THEN FOR I = 1 TO 9 FOR J = 1 TO 9 PRINT BIG.ARRAY<I,J> 'R#1 ': NEXT J PRINT NEXT I PRINT FOR I = 1 TO 9 FOR J = 1 TO 9 PRINT POSSIBLE.ARRAY<I,J> 'R#':'-': NEXT J PRINT NEXT I END END ELSE TI = 'N' END UNTIL TI = 'N' DO REPEAT PRINT;PRINT 'Ending puzzle' PRINT FOR I = 1 TO 9 FOR J = 1 TO 9 PRINT BIG.ARRAY<I,J> 'R#1 ': NEXT J PRINT NEXT I PRINT STOP ************ FIRST.CHECK: ************ * * First, do not check any cells from the starting array * IF STARTING.ARRAY<ROW,COLUMN> # '' THEN RETURN * * Do not check any cells already in big array? * IF BIG.ARRAY<ROW,COLUMN> # '' THEN RETURN * * Check row/column * FULL.STRING = '123456789' FOR I = 1 TO 9 CHARACTER = BIG.ARRAY<ROW,I> IF CHARACTER # '' THEN LOC = INDEX(FULL.STRING,CHARACTER,1) IF LOC THEN FULL.STRING = FULL.STRING[1,LOC - 1]:FULL.STRING[LOC + 1,9] END END NEXT I FOR I = 1 TO 9 CHARACTER = BIG.ARRAY<I,COLUMN> IF CHARACTER # '' THEN LOC = INDEX(FULL.STRING,CHARACTER,1) IF LOC THEN FULL.STRING = FULL.STRING[1,LOC - 1]:FULL.STRING[LOC + 1,9] END END NEXT I IF LEN(FULL.STRING) = 1 THEN BIG.ARRAY<ROW,COLUMN> = FULL.STRING RETURN END * * Check the 3x3 square * FULL.STRING = '123456789' I = 3 * INT((ROW - 1)/3) J = 3 * INT((COLUMN - 1)/3) FOR K = 1 TO 3 FOR L = 1 TO 3 CHARACTER = BIG.ARRAY<I + K,J + L> IF CHARACTER # '' THEN LOC = INDEX(FULL.STRING,CHARACTER,1) IF LOC THEN FULL.STRING = FULL.STRING[1,LOC - 1]:FULL.STRING[LOC + 1,9] END END NEXT L NEXT K IF LEN(FULL.STRING) = 1 THEN BIG.ARRAY<ROW,COLUMN> = FULL.STRING END RETURN ************* SECOND.CHECK: ************* TEMP.ARRAY = EMPTY.ARRAY FULL.STRING = '123456789' FOR I = SQ.ROW TO SQ.ROW + 2 FOR J = SQ.COLUMN TO SQ.COLUMN + 2 * * If this cell is not blank, remove the number from full.string, If this cell * is blank, then get all of the other numbers from the row/column * IF BIG.ARRAY<I,J> # '' THEN NUMBER = BIG.ARRAY<I,J> LOC = INDEX(FULL.STRING,NUMBER,1) IF LOC THEN FULL.STRING = FULL.STRING[1,LOC - 1]:FULL.STRING[LOC + 1,99] END TEMP.ARRAY<I,J> = '123456789' END ELSE USED.NUMBERS = '' FOR L = 1 TO 9 NUMBER = BIG.ARRAY<I,L> IF NUMBER # '' THEN IF NOT(INDEX(USED.NUMBERS,NUMBER,1)) THEN USED.NUMBERS := NUMBER END NEXT L FOR K = 1 TO 9 NUMBER = BIG.ARRAY<K,J> IF NUMBER # '' THEN IF NOT(INDEX(USED.NUMBERS,NUMBER,1)) THEN USED.NUMBERS := NUMBER END NEXT K TEMP.ARRAY<I,J> = USED.NUMBERS END NEXT J NEXT I * * If full.string is empty, then this square has already been filled in. Otherwise, try and find * a row or column that has not used any of the remaining numbers * NUM.REMAINING.NUMBERS = LEN(FULL.STRING) FOR POSITION = 1 TO NUM.REMAINING.NUMBERS NUMBER = FULL.STRING[POSITION,1] HITS = 0 FOR I = SQ.ROW TO SQ.ROW + 2 FOR J = SQ.COLUMN TO SQ.COLUMN + 2 LOC = INDEX(TEMP.ARRAY<I,J>,NUMBER,1) IF NOT(LOC) THEN HITS<1> += 1 ; HITS<2,-1> = NUMBER ; HITS<3,-1> = I ; HITS<4,-1> = J END NEXT J NEXT I * * If you only had one hit, then store the number in that cell. * IF HITS<1> = 1 THEN IF BIG.ARRAY<HITS<3>,HITS<4>> = '' THEN BIG.ARRAY<HITS<3>,HITS<4>> = NUMBER END ELSE PRINT 'Good work, Loser!' INPUT TI END END * * If there were multiple hits, then store the 'possible' hits in the possible array * IF HITS<1> > 1 THEN FOR I = 1 TO HITS<1> POSSIBLE.ARRAY<HITS<3,I>,HITS<4,I>> := HITS<2,I> NEXT I END NEXT POSITION RETURN ************ CHECK.ARRAY: ************ ERROR.FLAG = 0 FOR I = 1 TO 9 * * Check row I * STRING = '' FOR J = 1 TO 9 STRING := BIG.ARRAY<I,J> NEXT J GOSUB CHECK.STRING * * Check column I * STRING = '' FOR J = 1 TO 9 STRING := BIG.ARRAY<J,I> NEXT J GOSUB CHECK.STRING NEXT I FOR I = 0 TO 2 FOR J = 0 TO 2 STRING = '' FOR K = 1 TO 3 FOR L = 1 TO 3 STRING := BIG.ARRAY<I * 3 + K,J * 3 + L> NEXT L NEXT K GOSUB CHECK.STRING NEXT J NEXT I IF NOT(ERROR.FLAG) THEN PRINT 'You made it!' END RETURN ************* CHECK.STRING: ************* * * Must be numeric, must have nine characters * IF LEN(STRING) # 9 OR NOT(NUM(STRING)) THEN ERROR.FLAG = 1 END * * The sum must be 45, cannot have a number repeat * CHECK.SUM = 0 FOR POSITION = 1 TO 9 CHECK.SUM += STRING[POSITION,1] IF COUNT(STRING,POSITION) # 1 THEN ERROR.FLAG = 2 END NEXT POSITION IF CHECK.SUM # 45 THEN ERROR.FLAG = 3 END RETURN ------- u2-users mailing list u2-users@listserver.u2ug.org To unsubscribe please visit http://listserver.u2ug.org/