yingpotter

[99p]SudokuSolver

Aug 21st, 2011
305
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- This sudoku solver is based on the fuctional pearls from Richard Bird
  2. -- Available at ttp://www.cs.tufts.edu/~nr/comp150fp/archive/richard-bird/sudoku.pdf
  3.  
  4. import Data.List
  5. import Data.List.Split
  6.  
  7. ----- predefined consts and inputs
  8. type Matrix a = [[a]]
  9. type Board = Matrix Integer
  10. blktest = [ [1,2,3,4],
  11.             [5,6,7,8],
  12.             [1,3,5,7],
  13.             [2,4,6,8] ]
  14. sudokuq1 = [ [2, 0, 0, 0, 0, 1, 0, 3, 8],
  15.              [0, 0, 0, 0, 0, 0, 0, 0, 5],
  16.              [0, 7, 0, 0, 0, 6, 0, 0, 0],
  17.              [0, 0, 0, 0, 0, 0, 0, 1, 3],
  18.              [0, 9, 8, 1, 0, 0, 2, 5, 7],
  19.              [3, 1, 0, 0, 0, 0, 8, 0, 0],
  20.              [9, 0, 0, 8, 0, 0, 0, 2, 0],
  21.              [0, 5, 0, 0, 6, 9, 7, 8, 4],
  22.              [4, 0, 0, 2, 5, 0, 0, 0, 0] ]
  23. sudokuq2 = [ [0, 1, 0, 4, 2, 0, 0, 0, 5],
  24.              [0, 0, 2, 0, 7, 1, 0, 3, 9],
  25.              [0, 0, 0, 0, 0, 0, 0, 4, 0],
  26.              [2, 0, 7, 1, 0, 0, 0, 0, 6],
  27.              [0, 0, 0, 0, 4, 0, 0, 0, 0],
  28.              [6, 0, 0, 0, 0, 7, 4, 0, 3],
  29.              [0, 7, 0, 0, 0, 0, 0, 0, 0],
  30.              [1, 2, 0, 7, 3, 0, 5, 0, 0],
  31.              [3, 0, 0, 0, 8, 2, 0, 7, 0] ]
  32. sudokuq3 = [ [0, 9, 0, 7, 0, 0, 8, 6, 0],
  33.              [0, 3, 1, 0, 0, 5, 0, 2, 0],
  34.              [8, 0, 6, 0, 0, 0, 0, 0, 0],
  35.              [0, 0, 7, 0, 5, 0, 0, 0, 6],
  36.              [0, 0, 0, 3, 0, 7, 0, 0, 0],
  37.              [5, 0, 0, 0, 1, 0, 7, 0, 0],
  38.              [0, 0, 0, 0, 0, 0, 1, 0, 9],
  39.              [0, 2, 0, 6, 0, 0, 3, 5, 0],
  40.              [0, 5, 4, 0, 0, 8, 0, 7, 0] ]
  41. sudokuq4 = [ [1, 0, 0, 9, 0, 7, 0, 3, 0],
  42.              [0, 8, 0, 0, 0, 0, 0, 7, 0],
  43.              [0, 0, 9, 0, 0, 0, 6, 0, 0],
  44.              [0, 0, 7, 2, 0, 9, 4, 0, 0],
  45.              [4, 1, 0, 0, 0, 0, 0, 9, 5],
  46.              [0, 0, 8, 5, 0, 4, 3, 0, 0],
  47.              [0, 0, 3, 0, 0, 0, 7, 0, 0],
  48.              [0, 5, 0, 0, 0, 0, 0, 4, 0],
  49.              [2, 0, 0, 8, 0, 6, 0, 0, 9] ]
  50. sudokuq5 = [ [0, 9, 8, 0, 0, 0, 0, 0, 0],
  51.              [0, 0, 0, 0, 7, 0, 0, 0, 0],
  52.              [0, 0, 0, 0, 1, 5, 0, 0, 0],
  53.              [1, 0, 0, 0, 0, 0, 0, 0, 0],
  54.              [0, 0, 0, 2, 0, 0, 0, 0, 9],
  55.              [0, 0, 0, 9, 0, 6, 0, 8, 2],
  56.              [0, 0, 0, 0, 0, 0, 0, 3, 0],
  57.              [5, 0, 1, 0, 0, 0, 0, 0, 0],
  58.              [0, 0, 0, 4, 0, 0, 0, 2, 0] ]
  59.  
  60. ----- solution verification
  61. brdtoBlk :: Matrix a -> Matrix a
  62. brdtoBlk [] = []
  63. brdtoBlk brd = map concat $ concat $ map transpose $ splitEvery 3 $ map (splitEvery 3) brd
  64. noDup :: Eq a => [a] -> Bool
  65. noDup [] = True
  66. noDup (x:xs) = (x `notElem` xs) && (noDup xs)
  67. veriSol :: Board -> Bool
  68. veriSol sol = and (map noDup sol) &&
  69.               and (map noDup $ transpose sol) &&
  70.               and (map noDup $ brdtoBlk sol)
  71.  
  72. ----- solution permutation
  73. choices :: Board -> Matrix [Integer]
  74. choices brd = map (map choice) brd
  75.               where choice e = if (e == 0) then [1..9] else [e]
  76. matCart :: Matrix [a] -> [Matrix a]
  77. matCart = cartProd . (map cartProd)
  78.           where cartProd :: [[a]] -> [[a]]
  79.                 cartProd [] = [[]]
  80.                 cartProd (ls:lss) = [ x:xs | x <- ls, xs <- cartProd lss ]
  81.  
  82. ----- prune solutions
  83. single :: [a] -> Bool
  84. single [_] = True
  85. single _ = False
  86. reduce :: [[Integer]] -> [[Integer]]
  87. reduce chomat = [ if (single chorow) then chorow else (chorow \\ (concat (filter single chomat))) | chorow <- chomat ]
  88. pruSol :: Matrix [Integer] -> Matrix [Integer]
  89. pruSol = pruneBy brdtoBlk . pruneBy transpose . pruneBy id
  90.          where pruneBy f = f . map reduce . f
  91.  
  92. ----- solution properties
  93. compSol :: Matrix [Integer] -> Bool
  94. compSol chomat = and (map (all single) chomat)
  95. voidSol :: Matrix [Integer] -> Bool
  96. voidSol chomat = or (map (any null) chomat)
  97. safeSol :: Matrix [Integer] -> Bool
  98. safeSol chomat = and (map (noDup . concat . filter single)  chomat) &&
  99.                  and (map (noDup . concat . filter single) $ transpose chomat) &&
  100.                  and (map (noDup . concat . filter single) $ brdtoBlk chomat)
  101. ridSol :: Matrix [Integer] -> Bool
  102. ridSol chomat = voidSol chomat || not (safeSol chomat)
  103.  
  104. ----- solver algorithm
  105. expand :: Matrix [Integer] -> [Matrix [Integer]]
  106. expand chomat = [chorows1 ++ [chorow1 ++ [c]:chorow2] ++ chorows2 | c <- cs]
  107.                 where
  108.                   (chorows1, chorow:chorows2) = break (any best) chomat
  109.                   (chorow1, cs:chorow2) = break best chorow
  110.                   best cs = (length cs == n)
  111.                   n = minchoice chomat
  112. minchoice = minimum . filter (>1) . concat . map (map length)
  113. search :: Matrix [Integer] -> [Board]
  114. search chomat
  115.        | ridSol chomat     = []
  116.        | compSol chomat    = matCart chomat
  117.        | otherwise         = [ sol | chom <- expand chomat, sol <- search (pruSol chom) ]
  118. sudoku :: Board -> [Board]
  119. sudoku = search . pruSol . choices
Advertisement
Add Comment
Please, Sign In to add comment