3

I am a complete beginner to Haskell but I'm being asked to create a sudoku solver. I've been making some steady progress with it but one of the things it is asking me to do is print a valid representation of a sudoku puzzle s. The Puzzle data type is defined as a list of lists, so [[Maybe Int]] and this is composed of Block values ([Maybe Int], representing a row).

Function signature is this:

printPuzzle :: Puzzle -> IO ()

How do I output this? I know this may be a simple question and I'm missing the point but I'm still not at the stage where I've got my ahead around the syntax yet. Any help would be much appreciated!

sea1997
  • 43
  • 6
  • 1
    If `Puzzle` is an alias of `[[Maybe Int]]`, it should already have a `Show` instance, which means that you can use [`print`](http://hackage.haskell.org/package/base-4.10.1.0/docs/Prelude.html#v:print) with it. – Mark Seemann Jan 08 '18 at 13:16
  • 2
    This may, however, not give you the desired formatting. Perhaps [`unlines`](http://hackage.haskell.org/package/base-4.10.1.0/docs/Prelude.html#v:unlines) or [`intercalate`](http://hackage.haskell.org/package/base-4.10.1.0/docs/Data-List.html#v:intercalate) could be helpful to you... – Mark Seemann Jan 08 '18 at 13:19
  • 2
    This question could benefit from a [mcve]. Exactly **how** are you wanting to format the output? – hnefatl Jan 08 '18 at 17:36

1 Answers1

6

Simple pretty-printing of this can be done really succinctly with something like the following:

import Data.Char (intToDigit)

showRow :: [Maybe Int] -> String
showRow = map (maybe ' ' intToDigit)

showPuzzle :: [[Maybe Int]] -> [String]
showPuzzle = map showRow

printPuzzle :: [[Maybe Int]] -> IO ()
printPuzzle = mapM_ putStrLn . showPuzzle
  • showRow takes a single row from your grid and prints it - using the maybe function from Data.Maybe, we can write this as a quick map from each Maybe Int value to either a default "blank space" value or the character representing the number (using intToDigit).

  • showPuzzle simply maps showRow over the outer list.

  • printPuzzle just uses the previous pure definitions to give the impure action which prints a grid, by putStrLn'ing the pretty-print of each row.


A quick demo:

> printPuzzle [[Just 1, Nothing, Just 3],
               [Nothing, Just 3, Just 6],
               [Just 2, Just 4, Just 5]]
1 3
 36
245

Though you can easily modify the above code to print something more explicit, like:

1X3
X36
245
hnefatl
  • 5,860
  • 2
  • 27
  • 49