2012-11-26 30 views
1

所以我一直在研究打印出Sudoku板過去幾個小時這個問題,而且我差不多完成了,但是我被困在最後一步。因此,我所擁有的是一個數獨板,表示爲「列表清單」(即board = [[1,3,5,7,0,2,0,0,0],[3,4,5,...] ],...]Haskell do關鍵字

我已經能夠打印出了一條符合用下面的函數格式:通過使像「行0板」呼叫

line i s_board = intercalate " | " . map unwords . chunksOf 3 $ map show a 
      where 
       a = s_board!!i 

,所以我會得到「 1 3 5 | 7 0 2 | 0 0 0" ,這是部分地我所需要接下來,我試圖用‘做塊’,以輸出板,我需要這看起來是這樣的:

print = do line 0 board 
     line 1 board 
     ... 

這甚至不會編譯,當我做了這樣的事情:

print = do 
     line 0 board 
     line 1 board 

適當的列表打印多次,這是相當混亂。我想按照自己的方式來加入額外的格式,例如在每三行後打印一個字符串(如「----------」)來完成該板,但我甚至無法讓其他東西工作正確的。我會很感激對這些問題提供的任何幫助。

+0

顯示演示此問題的最小但完整的代碼。 – melpomene

+0

@melpomene我還應該包括什麼?我唯一遺漏的是我的文件頂部的董事會定義。我定義了「行」功能,然後其他事情都是失敗的嘗試。 – Ockham

+5

*完整*代表我可以運行和測試的代碼。 – melpomene

回答

7

這將是更容易和更優雅,產生一個函數,你 板,使得一個大的字符串,最後打印它,而不是擔心 打印通過do塊每一行。

所以,如果我們簡化您的行顯示功能,走板的一行:

showLine :: [Int] -> String 
showLine = intercalate " | " 
     . map unwords 
     . chunksOf 3 
     . map show 

然後,我們需要得到各行的字符串表示,並把它們放在一起 。這看起來非常像showLine代碼:

showBoard :: [[Int]] -> String 
showBoard = intercalate "---------------------\n" 
      . map unlines 
      . chunksOf 3 
      . map showLine 

使用示例板

-- Obviously not a valid sudoku board... 
example :: [[Int]] 
example = replicate 9 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] 

*Main> putStrLn $ showBoard example 
1 2 3 | 4 5 6 | 7 8 9 
1 2 3 | 4 5 6 | 7 8 9 
1 2 3 | 4 5 6 | 7 8 9 
--------------------- 
1 2 3 | 4 5 6 | 7 8 9 
1 2 3 | 4 5 6 | 7 8 9 
1 2 3 | 4 5 6 | 7 8 9 
--------------------- 
1 2 3 | 4 5 6 | 7 8 9 
1 2 3 | 4 5 6 | 7 8 9 
1 2 3 | 4 5 6 | 7 8 9 
+0

非常感謝,這工作!我現在終於可以睡了,謝謝 – Ockham

3

你原來的企圖沒有編譯,因爲它違反了Haskell的佈局規則。

第二個沒有做你期望的,因爲line n board是一個列表,所以do -notation意味着不確定性,而不是IO操作的排序。如果你試圖把一種像

print :: IO() 

你的函數以上(順便說一句,print在標準的前奏定義,你應該得到一個警告約陰影吧),類型檢查器會通知您的錯誤。如果你真的想打印出來的板這樣的(儘管對方的回答表明,建立一個字符串,然後打印這整個事情出來要好得多),你可以嘗試

printBoard :: IO() 
printBoard = do print $ line 0 board 
       print $ line 1 board 

或打印整個板,

printBoard = mapM_ (print . showLine) board 

其中showLine是喜歡你的print但剝離出來的索引。