Reputation: 69
I am working on making a step-by-step exercise in making a Sudoku solver from http://www.cse.chalmers.se/edu/year/2013/course/TDA555/lab3.html. Here I'm trying to express the row, column and box constraints for the Sudok
data Sudoku = Sudoku { getSudoku :: [[Maybe Int]] } deriving (Show, Eq)
rows :: Sudoku -> [[Maybe Int]]
rows (Sudoku rs) = rs
columns :: Sudoku -> [[Maybe Int]]
columns = transpose . rows
boxes :: Sudoku -> [[Maybe Int]]
boxes s = a ++ b ++ c
where a = map (concat . take 3) s1
b = map (concat . take 3 . drop 3) s1
c = map (concat . drop 6) s1
s1 = transpose . map (\xs -> [take 3 xs,take 3 (drop 3 xs), drop 6 xs]) $ rows s
I managed to get it to work but I want to refactor the 3 functions applied on s1 to get a,b,c into a list. I tried with <*> but somehow can't get it to work. Thanks
Upvotes: 0
Views: 135
Reputation: 14578
You can write it using Applicative
if you really want
boxes2 s = concat $ [a,b,c] <*> [s1]
This is just the same as
concatMap ($s1) [a,b,c]
Alternatively, you can do this:
boxes3 :: Sudoku -> [[Maybe Int]]
boxes3 = map concat . concat . map (f . transpose) . f . getSudoku
where f = unfoldr (\x -> if null x then Nothing else Just $ splitAt 3 x)
Upvotes: 3