%! % POSTSCRIPT NUMERIC PUZZLE SOLVER % ============================================ % Copyright c 1999, 2011 by Don Lancaster and Syenrgetics, Box 809, Thatcher, AZ, 85552 % (928) 428-4073 don@tinaja.com < http://www.tinaja.com > % Consulting services available per < http://www.tinaja.com/info01.html > % Additional PostScript resources at < http://www.tinaja.com/pssamp1.asp > % All commercial rights and all electronic media rights fully reserved. % Personal use permitted provided header and entire file remains intact. % Linking welcome. Reposting expressly forbidden. % version 5.1 % Instantly solves most (and possibly all) 3x3 Suduku puzzles. % Change gotmapin to match present problem, thon send to acrobat distiller. % more assistance at < http://www.tinaja.com/pssamp1.asp > % ========================================================================== % redefine and uncomment to include gonzo Utilities % (C:\\Documents and Settings\\don\\Desktop\\gonzo\\gonzo.ps) run % use external gonzo %%%%%%%%%%%%%%%%%%%% gonzo inports %%%%%%%%%%%%%% % mergestr merges the two top stack strings into one top stack string /mergestr {2 copy length exch length add string dup dup 4 3 roll 4 index length exch putinterval 3 1 roll exch 0 exch putinterval} def /stopwatchoff {stoptimer reporttimer} def % for single shots /stopwatchon {resettimer starttimer} def % for single shots /reporttimer {mytime 1000 div (\rElapsed time: ) print 20 string cvs print ( seconds.\r) print flush} def % to host /resettimer {/mytime 0 def} def % reset timer /starttimer {usertime /mytimenow exch def} def % add to time so far /stoptimer {usertime mytimenow sub /mytime exch mytime add def} def % for multiple timing intervals %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% stopwatchon % Solves the 3x3 Soduko numeric puzzles by simplifying the checkoff procedure. /locmap % locmap shows how the numbers are numbered [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 ] store /r0 [ 0 1 2 3 4 5 6 7 8 ] store % these are the row mappings /r1 [ 9 10 11 12 13 14 15 16 17 ] store /r2 [ 18 19 20 21 22 23 24 25 26 ] store /r3 [ 27 28 29 30 31 32 33 34 35 ] store /r4 [ 36 37 38 39 40 41 42 43 44 ] store /r5 [ 45 46 47 48 49 50 51 52 53 ] store /r6 [ 54 55 56 57 58 59 60 61 62 ] store /r7 [ 63 64 65 66 67 68 69 70 71 ] store /r8 [ 72 73 74 75 76 77 78 79 80 ] store /c0 [ 0 9 18 27 36 45 54 63 72 ] store % these are the column mappings /c1 [ 1 10 19 28 37 46 55 64 73 ] store /c2 [ 2 11 20 29 38 47 56 65 74 ] store /c3 [ 3 12 21 30 39 48 57 66 75 ] store /c4 [ 4 13 22 31 40 49 58 67 76 ] store /c5 [ 5 14 23 32 41 50 59 68 77 ] store /c6 [ 6 15 24 33 42 51 60 69 78 ] store /c7 [ 7 16 25 34 43 52 61 70 79 ] store /c8 [ 8 17 26 35 44 53 62 71 80 ] store /g0 [ 0 1 2 9 10 11 18 19 20 ] store % these are the group mappings /g1 [ 3 4 5 12 13 14 21 22 23 ] store /g2 [ 6 7 8 15 16 17 24 25 26 ] store /g3 [ 27 28 29 36 37 38 45 46 47 ] store /g4 [ 30 31 32 39 40 41 48 49 50 ] store /g5 [ 33 34 35 42 43 44 51 52 53 ] store /g6 [ 54 55 56 63 64 65 72 73 74 ] store /g7 [ 57 58 59 66 67 68 75 76 77 ] store /g8 [ 60 61 62 69 70 71 78 79 80 ] store /posmap % posmap is the relationship between the groups, rows, and columns [ { /r0 /c0 /g0 } {/r0 /c1 /g0 } {/r0 /c2 /g0 } {/r0 /c3 /g1} {/r0 /c4 /g1} {/r0 /c5 /g1 } {/r0 /c6 /g2} {/r0 /c7 /g2} {/r0 /c8 /g2} { /r1 /c0 /g0 } {/r1 /c1 /g0 } {/r1 /c2 /g0 } {/r1 /c3 /g1} {/r1 /c4 /g1} {/r1 /c5 /g1 } {/r1 /c6 /g2} {/r1 /c7 /g2} {/r1 /c8 /g2} { /r2 /c0 /g0 } {/r2 /c1 /g0 } {/r2 /c2 /g0 } {/r2 /c3 /g1} {/r2 /c4 /g1} {/r2 /c5 /g1 } {/r2 /c6 /g2} {/r2 /c7 /g2} {/r2 /c8 /g2} { /r3 /c0 /g3 } {/r3 /c1 /g3 } {/r3 /c2 /g3 } {/r3 /c3 /g4} {/r3 /c4 /g4} {/r3 /c5 /g4 } {/r3 /c6 /g5} {/r3 /c7 /g5} {/r3 /c8 /g5} { /r4 /c0 /g3 } {/r4 /c1 /g3 } {/r4 /c2 /g3 } {/r4 /c3 /g4} {/r4 /c4 /g4} {/r4 /c5 /g4 } {/r4 /c6 /g5} {/r4 /c7 /g5} {/r4 /c8 /g5} { /r5 /c0 /g3 } {/r5 /c1 /g3 } {/r5 /c2 /g3 } {/r5 /c3 /g4} {/r5 /c4 /g4} {/r5 /c5 /g4 } {/r5 /c6 /g5} {/r5 /c7 /g5} {/r5 /c8 /g5} { /r6 /c0 /g6 } {/r6 /c1 /g6 } {/r6 /c2 /g6 } {/r6 /c3 /g7} {/r6 /c4 /g7} {/r6 /c5 /g7 } {/r6 /c6 /g8} {/r6 /c7 /g8} {/r6 /c8 /g8} { /r7 /c0 /g6 } {/r7 /c1 /g6 } {/r7 /c2 /g6 } {/r7 /c3 /g7} {/r7 /c4 /g7} {/r7 /c5 /g7 } {/r7 /c6 /g8} {/r7 /c7 /g8} {/r7 /c8 /g8} { /r8 /c0 /g6 } {/r8 /c1 /g6 } {/r8 /c2 /g6 } {/r8 /c3 /g7} {/r8 /c4 /g7} {/r8 /c5 /g7 } {/r8 /c6 /g8} {/r8 /c7 /g8} {/r8 /c8 /g8} ] store /gotmapin % gotmapin is the pinput known numbers in the array 0 = presently undefined [ % 31 live 0 5 3 0 8 9 0 0 0 7 0 0 0 0 0 0 9 0 9 8 0 0 0 0 5 0 0 3 0 0 0 0 1 0 8 7 0 0 7 9 0 3 2 0 0 2 9 0 5 0 0 0 0 4 0 0 8 0 0 0 0 3 2 0 7 0 0 0 0 0 0 9 0 0 0 2 5 0 8 7 0 ] store /gotmap gotmapin store % gotmap is the running result present known valid numbers /maymapx % mapmap is the potential remaining numerical candidates [ (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) (123456789) ] store /maymap maymapx store % running result. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% this completes file definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% fancy reporters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /mergestri {( ) cvs mergestr} store % simplify below /showfancygotmap { % formats gotmap in easy to read form (\ngotmap is now\n\n [) print flush (\n ) gotmap 0 get mergestri ( ) mergestr gotmap 1 get mergestri ( ) mergestr gotmap 2 get mergestri ( ) mergestr gotmap 3 get mergestri ( ) mergestr gotmap 4 get mergestri ( ) mergestr gotmap 5 get mergestri ( ) mergestr gotmap 6 get mergestri ( ) mergestr gotmap 7 get mergestri ( ) mergestr gotmap 8 get mergestri ( ) mergestr print flush (\n ) gotmap 9 get mergestri ( ) mergestr gotmap 10 get mergestri ( ) mergestr gotmap 11 get mergestri ( ) mergestr gotmap 12 get mergestri ( ) mergestr gotmap 13 get mergestri ( ) mergestr gotmap 14 get mergestri ( ) mergestr gotmap 15 get mergestri ( ) mergestr gotmap 16 get mergestri ( ) mergestr gotmap 17 get mergestri ( ) mergestr print flush (\n ) gotmap 18 get mergestri ( ) mergestr gotmap 19 get mergestri ( ) mergestr gotmap 20 get mergestri ( ) mergestr gotmap 21 get mergestri ( ) mergestr gotmap 22 get mergestri ( ) mergestr gotmap 23 get mergestri ( ) mergestr gotmap 24 get mergestri ( ) mergestr gotmap 25 get mergestri ( ) mergestr gotmap 26 get mergestri ( \n) mergestr print flush (\n ) gotmap 27 get mergestri ( ) mergestr gotmap 28 get mergestri ( ) mergestr gotmap 29 get mergestri ( ) mergestr gotmap 30 get mergestri ( ) mergestr gotmap 31 get mergestri ( ) mergestr gotmap 32 get mergestri ( ) mergestr gotmap 33 get mergestri ( ) mergestr gotmap 34 get mergestri ( ) mergestr gotmap 35 get mergestri ( ) mergestr print flush (\n ) gotmap 36 get mergestri ( ) mergestr gotmap 37 get mergestri ( ) mergestr gotmap 38 get mergestri ( ) mergestr gotmap 39 get mergestri ( ) mergestr gotmap 40 get mergestri ( ) mergestr gotmap 41 get mergestri ( ) mergestr gotmap 42 get mergestri ( ) mergestr gotmap 43 get mergestri ( ) mergestr gotmap 44 get mergestri ( ) mergestr print flush (\n ) gotmap 45 get mergestri ( ) mergestr gotmap 46 get mergestri ( ) mergestr gotmap 47 get mergestri ( ) mergestr gotmap 48 get mergestri ( ) mergestr gotmap 49 get mergestri ( ) mergestr gotmap 50 get mergestri ( ) mergestr gotmap 51 get mergestri ( ) mergestr gotmap 52 get mergestri ( ) mergestr gotmap 53 get mergestri ( \n) mergestr print flush (\n ) gotmap 54 get mergestri ( ) mergestr gotmap 55 get mergestri ( ) mergestr gotmap 56 get mergestri ( ) mergestr gotmap 57 get mergestri ( ) mergestr gotmap 58 get mergestri ( ) mergestr gotmap 59 get mergestri ( ) mergestr gotmap 60 get mergestri ( ) mergestr gotmap 61 get mergestri ( ) mergestr gotmap 62 get mergestri ( ) mergestr print flush (\n ) gotmap 63 get mergestri ( ) mergestr gotmap 64 get mergestri ( ) mergestr gotmap 65 get mergestri ( ) mergestr gotmap 66 get mergestri ( ) mergestr gotmap 67 get mergestri ( ) mergestr gotmap 68 get mergestri ( ) mergestr gotmap 69 get mergestri ( ) mergestr gotmap 70 get mergestri ( ) mergestr gotmap 71 get mergestri ( ) mergestr print flush (\n ) gotmap 72 get mergestri ( ) mergestr gotmap 73 get mergestri ( ) mergestr gotmap 74 get mergestri ( ) mergestr gotmap 75 get mergestri ( ) mergestr gotmap 76 get mergestri ( ) mergestr gotmap 77 get mergestri ( ) mergestr gotmap 78 get mergestri ( ) mergestr gotmap 79 get mergestri ( ) mergestr gotmap 80 get mergestri ( \n) mergestr print flush ( ]\n\n) print flush } store /showfancymaymap { % formats gotmap in easy to read form (\nmaymap is now\n\n [) print flush (\n \() maymap 0 get mergestr (\) \() mergestr maymap 1 get mergestr (\) \() mergestr maymap 2 get mergestr (\) \() mergestr maymap 3 get mergestr (\) \() mergestr maymap 4 get mergestr (\) \() mergestr maymap 5 get mergestr (\) \() mergestr maymap 6 get mergestr (\) \() mergestr maymap 7 get mergestr (\) \() mergestr maymap 8 get mergestr (\) )mergestr print flush (\n \() maymap 9 get mergestr (\) \() mergestr maymap 10 get mergestr (\) \() mergestr maymap 11 get mergestr (\) \() mergestr maymap 12 get mergestr (\) \() mergestr maymap 13 get mergestr (\) \() mergestr maymap 14 get mergestr (\) \() mergestr maymap 15 get mergestr (\) \() mergestr maymap 16 get mergestr (\) \() mergestr maymap 17 get mergestr (\) ) mergestr print flush (\n \() maymap 18 get mergestr (\) \() mergestr maymap 19 get mergestr (\) \() mergestr maymap 20 get mergestr (\) \() mergestr maymap 21 get mergestr (\) \() mergestr maymap 22 get mergestr (\) \() mergestr maymap 23 get mergestr (\) \() mergestr maymap 24 get mergestr (\) \() mergestr maymap 25 get mergestr (\) \() mergestr maymap 26 get mergestr (\) \n) mergestr print flush (\n \() maymap 27 get mergestr (\) \() mergestr maymap 28 get mergestr (\) \() mergestr maymap 29 get mergestr (\) \() mergestr maymap 30 get mergestr (\) \() mergestr maymap 31 get mergestr (\) \() mergestr maymap 32 get mergestr (\) \() mergestr maymap 33 get mergestr (\) \() mergestr maymap 34 get mergestr (\) \() mergestr maymap 35 get mergestr (\) )mergestr print flush (\n \() maymap 36 get mergestr (\) \() mergestr maymap 37 get mergestr (\) \() mergestr maymap 38 get mergestr (\) \() mergestr maymap 39 get mergestr (\) \() mergestr maymap 40 get mergestr (\) \() mergestr maymap 41 get mergestr (\) \() mergestr maymap 42 get mergestr (\) \() mergestr maymap 43 get mergestr (\) \() mergestr maymap 44 get mergestr (\) ) mergestr print flush (\n \() maymap 45 get mergestr (\) \() mergestr maymap 46 get mergestr (\) \() mergestr maymap 47 get mergestr (\) \() mergestr maymap 48 get mergestr (\) \() mergestr maymap 49 get mergestr (\) \() mergestr maymap 50 get mergestr (\) \() mergestr maymap 51 get mergestr (\) \() mergestr maymap 52 get mergestr (\) \() mergestr maymap 53 get mergestr (\) \n) mergestr print flush (\n \() maymap 54 get mergestr (\) \() mergestr maymap 55 get mergestr (\) \() mergestr maymap 56 get mergestr (\) \() mergestr maymap 57 get mergestr (\) \() mergestr maymap 58 get mergestr (\) \() mergestr maymap 59 get mergestr (\) \() mergestr maymap 60 get mergestr (\) \() mergestr maymap 61 get mergestr (\) \() mergestr maymap 62 get mergestr (\) )mergestr print flush (\n \() maymap 63 get mergestr (\) \() mergestr maymap 64 get mergestr (\) \() mergestr maymap 65 get mergestr (\) \() mergestr maymap 66 get mergestr (\) \() mergestr maymap 67 get mergestr (\) \() mergestr maymap 68 get mergestr (\) \() mergestr maymap 69 get mergestr (\) \() mergestr maymap 70 get mergestr (\) \() mergestr maymap 71 get mergestr (\) ) mergestr print flush (\n \() maymap 72 get mergestr (\) \() mergestr maymap 73 get mergestr (\) \() mergestr maymap 74 get mergestr (\) \() mergestr maymap 75 get mergestr (\) \() mergestr maymap 76 get mergestr (\) \() mergestr maymap 77 get mergestr (\) \() mergestr maymap 78 get mergestr (\) \() mergestr maymap 79 get mergestr (\) \() mergestr maymap 80 get mergestr (\) \n) mergestr print flush ( ]\n\n) print flush } store % temptest true { showfancygotmap showfancymaymap } if %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% maymap updater %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /update { 0 1 80 {/curpos exch store gotmap curpos get /curnum exch store posmap curpos get exec /curgroup exch store /curcol exch store /currow exch store curnum 0 ne { curgroup cvx exec nullsome % updates present group curcol cvx exec nullsome % updates present column currow cvx exec nullsome % updates present row maymap curpos (---------) put % zeros out self maymap from further activity } if } for } store /nullsome { { /curfix exch store maymap curfix get /workstring exch store workstring curnum 1 sub (-) 0 get put maymap curfix workstring put } forall } store update % revises maymap for current gotmap true { showfancymaymap } if /findsingles { { /candidates exch store % (\ncandidates are now ) print flush candidates == 1 1 9 { /curnumtest exch store % numerals 1 through 9 to be tested in string positions 0 through 8 /curasciitest curnumtest 48 add store % ascii equivalent of numeral for test /hits 0 store % zero hit counter false { (\n\n curnumtest is now ) curnumtest ( ) cvs mergestr print flush (\n curasciitest is now ) curasciitest ( ) cvs mergestr print flush (\n) print flush } if /hits 0 store /lasthit -2 store 0 1 8 {/indcanpointer exch store /indcan candidates cvx exec indcanpointer get cvx exec store false { (\n indcan is now ) print flush indcan == } if maymap indcan get /curstring exch store false { (\n curstring is now ) curstring mergestr print flush } if curstring curnumtest 1 sub get /curtest exch store false { (\n indcanpointer is now ) indcanpointer ( ) cvs mergestr print (\n curtest is now ) curtest ( ) cvs mergestr print flush } if curtest curasciitest eq { /hits hits 1 add store /lasthit indcanpointer store /curhold curnumtest store /indcanhold indcan store } if } for % for each individual candidate hits 1 eq { % (\n hits are now ) hits ( ) cvs mergestr print flush % (\n lasthit was ) lasthit ( ) cvs mergestr print flush % (\n curhold was ) curhold ( ) cvs mergestr print flush % (\n indcanhold was ) indcanhold ( ) cvs mergestr print flush (\n putting a ) curhold ( ) cvs mergestr ( into gotmap location ) mergestr indcanhold ( ) cvs mergestr (.) mergestr print flush gotmap indcanhold curhold put % this does it % maymap indcanhold (---------) put % clears related maymap % too early?!!! } if } for % for numerals 1-9 } forall % for each column set, group set, or row set } store /singlecycle { [/c0 /c1 /c2 /c3 /c4 /c5 /c6 /c7 /c8 ] findsingles [/g0 /g1 /g2 /g3 /g4 /g5 /g6 /g7 /g8 ] findsingles [/r0 /r1 /r2 /r3 /r4 /r5 /r6 /r7 /r8 ] findsingles } store singlecycle % need an update here instead? update true { showfancygotmap showfancymaymap } if singlecycle update true { showfancygotmap showfancymaymap } if singlecycle update true { showfancygotmap showfancymaymap } if singlecycle update true { showfancygotmap showfancymaymap } if 6 { singlecycle update true { showfancygotmap showfancymaymap } if } repeat %% end of new code stopwatchoff %% EOF