Advertisement
Jan-Langevad

SUDOKU.TXT

Oct 4th, 2024
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.84 KB | Software | 0 0
  1. \ SUDOKU.TXT
  2. \ From: https://see.stanford.edu/materials/icspacs106b/H19-RecBacktrackExamples.pdf
  3. \
  4. \ A straightforward port from the original C++ to Forth
  5.  
  6. \ Some useful constants
  7.  
  8. 0 constant unassigned
  9. 3 constant box-size
  10. 9 constant board-size
  11. board-size dup * constant cell-count
  12. board-size 1+ constant puzzle-base
  13.  
  14. board-size cells constant column-jump
  15. board-size box-size - 1+ cells constant box-jump
  16.  
  17. 0 value MAXDepth \ ADDED code JL
  18. 0 value TimesAround \ ADDED code JL
  19.  
  20. : puzzle-base!
  21. puzzle-base base ! ;
  22.  
  23. puzzle-base!
  24.  
  25.  
  26. \ http://www.telegraph.co.uk/news/science/science-news/9359579/Worlds-hardest-sudoku-can-you-crack-it.html
  27.  
  28. create puzzle
  29. 8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
  30. 0 , 0 , 3 , 6 , 0 , 0 , 0 , 0 , 0 ,
  31. 0 , 7 , 0 , 0 , 9 , 0 , 2 , 0 , 0 ,
  32. 0 , 5 , 0 , 0 , 0 , 7 , 0 , 0 , 0 ,
  33. 0 , 0 , 0 , 0 , 4 , 5 , 7 , 0 , 0 ,
  34. 0 , 0 , 0 , 1 , 0 , 0 , 0 , 3 , 0 ,
  35. 0 , 0 , 1 , 0 , 0 , 0 , 0 , 6 , 8 ,
  36. 0 , 0 , 8 , 5 , 0 , 0 , 0 , 1 , 0 ,
  37. 0 , 9 , 0 , 0 , 0 , 0 , 4 , 0 , 0 ,
  38.  
  39.  
  40. \ Rather than compare against zero, make the code more meaningful to readers.
  41.  
  42. : unassigned? ( -- )
  43. 0= ;
  44.  
  45.  
  46. \ Puzzle access methods
  47.  
  48. : grid>addr ( n - addr )
  49. cells puzzle + ;
  50.  
  51. : grid@ ( n -- number )
  52. grid>addr @ ;
  53.  
  54. : grid! ( number n -- )
  55. grid>addr ! ;
  56.  
  57.  
  58. \ Move and grid position translation methods
  59.  
  60. : move>xy ( n -- x y )
  61. board-size /mod ;
  62.  
  63. : move>x ( n -- x )
  64. board-size mod ;
  65.  
  66. : move>y ( n -- y )
  67. board-size / ;
  68.  
  69. : xy>move ( x y -- n )
  70. board-size * + ;
  71.  
  72.  
  73. \ Row, column and box start positions
  74.  
  75. : move>row-start ( n -- n )
  76. move>y board-size * ;
  77.  
  78. : move>column-start ( n -- n )
  79. move>x ;
  80.  
  81. : box-side-start ( n -- n )
  82. dup box-size mod - ;
  83.  
  84. : move>box-start ( n -- n )
  85. move>xy
  86. box-side-start swap
  87. box-side-start swap
  88. xy>move ;
  89.  
  90.  
  91. \ Used macro helper
  92.  
  93. : cell-check
  94. 2dup @ = if drop r> drop exit then ;
  95.  
  96.  
  97. \ Function: used-in-row?
  98. \ ----------------------
  99. \ Returns a boolean which indicates whether any assigned entry
  100. \ in the specified row matches the given number.
  101.  
  102. \ simplified in Forth by row cells being contiguious in the grid.
  103.  
  104. : used-in-row? ( number n -- f )
  105. move>row-start grid>addr
  106. cell-check
  107. cell+ cell-check
  108. cell+ cell-check
  109. cell+ cell-check
  110. cell+ cell-check
  111. cell+ cell-check
  112. cell+ cell-check
  113. cell+ cell-check
  114. cell+ cell-check
  115. 2drop 0 ;
  116.  
  117.  
  118. \ Function: used-in-column?
  119. \ -------------------------
  120. \ Returns a boolean which indicates whether any assigned entry
  121. \ in the specified column matches the given number.
  122.  
  123. \ Very similar to used-in-row?, with the offset incrementing by the board-size
  124.  
  125. : used-in-column? ( number n -- f )
  126. move>column-start grid>addr
  127. cell-check
  128. column-jump + cell-check
  129. column-jump + cell-check
  130. column-jump + cell-check
  131. column-jump + cell-check
  132. column-jump + cell-check
  133. column-jump + cell-check
  134. column-jump + cell-check
  135. column-jump + cell-check
  136. 2drop 0 ;
  137.  
  138.  
  139. \ Function: used-in-box?
  140. \ ----------------------
  141. \ Returns a boolean which indicates whether any assigned entry
  142. \ within the specified 3x3 box matches the given number.
  143.  
  144. \ Convert the loop into a box xy, then calculate an offset to obtain cell value.
  145.  
  146. : used-in-box? ( number n - f )
  147. move>box-start grid>addr
  148. cell-check
  149. cell+ cell-check
  150. cell+ cell-check
  151. box-jump + cell-check
  152. cell+ cell-check
  153. cell+ cell-check
  154. box-jump + cell-check
  155. cell+ cell-check
  156. cell+ cell-check
  157. 2drop 0 ;
  158.  
  159.  
  160. \ Function: available?
  161. \ --------------------
  162. \ Returns a boolean which indicates whether it will be legal to assign
  163. \ number to the given row,column location. As assignment is legal if it that
  164. \ number is not already used in the row, column, or box.
  165.  
  166. \ Because Forth doesn't seem to shortcut logical operations, we must explicitly leave early
  167. \ if possible.
  168.  
  169. : available? ( number n -- f )
  170. 2dup used-in-row? if 2drop 0 exit then
  171. 2dup used-in-column? if 2drop 0 exit then
  172. used-in-box? 0= ;
  173.  
  174.  
  175. \ Function: solve?
  176. \ ----------------
  177. \ Takes a partially filled-in grid and attempts to assign values to all
  178. \ unassigned locations in such a way to meet the requirements for sudoku
  179. \ solution (non-duplication across rows, columns, and boxes). The function
  180. \ operates via recursive backtracking: it finds an unassigned location with
  181. \ the grid and then considers all digits from 1 to "board-size" in a loop. If a digit
  182. \ is found that has no existing conflicts, tentatively assign it and recur
  183. \ to attempt to fill in rest of grid. If this was successful, the puzzle is
  184. \ solved. If not, unmake that decision and try again. If all digits have
  185. \ been examined and none worked out, return false to backtrack to previous
  186. \ decision point.
  187.  
  188. : solve? ( n -- f )
  189.  
  190. DEPTH MAXDepth max is MAXDepth \ ADDED code JL
  191. TimesAround 1+ is TimesAround \ ADDED code JL
  192.  
  193. dup cell-count =
  194. if drop -1 exit
  195. then \ success!
  196.  
  197. dup grid@
  198. if 1+ recurse exit
  199. then \ if it's already assigned, skip
  200.  
  201. 10 1
  202. ?do \ consider all digits
  203. i over available?
  204. if \ if looks promising
  205. i over grid! \ make tentative assignment
  206. dup 1+ recurse
  207. if unloop drop -1 exit \ recur, if success, yay!
  208. then
  209. then
  210. loop
  211. unassigned over grid! \ failure, unmake & try again
  212. drop 0 \ this triggers backtracking
  213. ;
  214.  
  215. \ Board display
  216.  
  217. : .board-element ( n -- )
  218. ." "
  219. grid@ dup unassigned? if drop ." - " else . then
  220. ." " ;
  221.  
  222. : .box-break-vertical ( -- )
  223. ." |" ;
  224.  
  225. : .box-break-horizontal ( -- )
  226. ." ------------+------------+-----------" ;
  227.  
  228. : .board ( -- )
  229. cell-count 0 do
  230. i move>x unassigned? if
  231. i move>y box-size mod 0= if
  232. cr cr
  233. .box-break-horizontal
  234. then
  235. cr cr
  236. else
  237. i move>x box-size mod 0= if
  238. .box-break-vertical
  239. then
  240. then
  241. i .board-element
  242. loop
  243. cr cr .box-break-horizontal cr ;
  244.  
  245. : game ( -- )
  246.  
  247. MS-TICKS \ ADDED code JL
  248. 0 is TimesAround \ ADDED code JL
  249. 0 is MAXDepth \ ADDED code JL
  250.  
  251. 0 solve? if
  252. .board
  253. else
  254. cr cr ." No solution exists"
  255. then
  256.  
  257. MS-TICKS swap - \ ADDED code JL
  258. cr ." Time used in milliseconds: " . ." Max DEPTH: " MAXDepth . ." xAround: " TimesAround . cr \ ADDED code JL
  259. ;
  260.  
  261. \ game
  262. \ EOF "Test-area":
  263.  
  264. decimal
  265.  
  266. : 81>board ( n...81......n --- )
  267. 81 0
  268. do 80 I - \ 80.......0
  269. cells \ n --- 4n
  270. puzzle + !
  271. loop
  272. ;
  273.  
  274. decimal
  275.  
  276. \ "World's hardest SUDOKU":
  277. 8 0 0 0 0 0 0 0 0
  278. 0 0 3 6 0 0 0 0 0
  279. 0 7 0 0 9 0 2 0 0
  280. 0 5 0 0 0 7 0 0 0
  281. 0 0 0 0 4 5 7 0 0
  282. 0 0 0 1 0 0 0 3 0
  283. 0 0 1 0 0 0 0 6 8
  284. 0 0 8 5 0 0 0 1 0
  285. 0 9 0 0 0 0 4 0 0
  286.  
  287. 81>board
  288.  
  289. cr depth cr
Tags: FORTH SUDOKU
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement