Sudoku logikai játék

Próbáljuk meg megoldani a feladatot csak a következő segédanyagok felhasználásával: Haskell könyvtárainak dokumentációja, Hoogle, a tárgy honlapja és a BE-AD rendszerbe feltöltött beadandók.

A feladatok egymásra épülnek, ezért érdemes ezeket a megadásuk sorrendjében megoldani, de legalább megérteni az aktuális feladatot megelőző feladatokat! A függvények definíciójában lehet, sőt javasolt is alkalmazni a korábban definiált függvényeket (függetlenül attól, hogy sikerült-e azokat megadni). Beadni viszont a teljes megoldást kell, vagyis az összes függvény definícióját egyszerre!

Tekintve, hogy a tesztesetek, bár odafigyelés mellett íródnak, nem fedik le minden esetben a függvény teljes működését, határozottan javasolt még külön próbálgatni a megoldásokat beadás előtt!

A feladat összefoglaló leírása

A feladat a Sudoku logikai játékról, szabályainak megfogalmazásáról és végül a megoldásáról szól. A Sudoku játékot egy 9x9-es négyzetrácson játsszák, amelynek az üresen hagyott mezőit kell kitölteni az [1-9] intervallumból vett értékek valamelyikével. A kitöltés szabálya, hogy egy tetszőleges sorban, oszlopban vagy blokkban sem szerepeljen ugyanaz a szám egynél többször.

Egy rejtvényt 9 sorral, oszloppal és blokkal adunk meg és mindegyikét 0-tól 8-ig indexeljük. Egy Sudoku alapvető elemei az alábbi ábrán láthatóak:

012345678012345678012345678

A rejtvény kezdőállapota egy részlegesen kitöltött tábla, amelynek a teljes kitöltésére törekszünk.

Egy lehetséges kezdeti állapot, amelynek egy megoldása van:

367125189247132845292746538983676943

És ennek a megoldása:

852142472759161351987618347569635814632954897367125189247132845292746538983676943

Egy másik feladvány, amelynek szintén egy kitöltése létezik:

537619598686348317266284195879

És a megoldása:

162543236784175958274291438431295147531862437976925537619598686348317266284195879

A rejtvényt táblázatát egy listával ábrázoljuk (Sudoku), amelyekben az egyes mezőket (Cell) egy rendezett párossal azonosítunk. A mezőket a táblázatban elfoglalt pozíciójukkal (Pos) és a mezőbe beírt egész értékkel ábrázoljuk. A pozíció (Pos) egy rendezett pár, amely a sor és oszlop indexeit tartalmazza. A 3x3 mezőket pedig blokkoknak (Block) nevezzük, és egy egész értékkel azonosítjuk.

type Pos = (Int, Int)
type Cell = (Pos, Int)
type Sudoku = [Cell]
type Block = Int

A fenti két példának megfelelően bevezetünk két konstanst, amely a kezdeti állapotokat írja le:

sudoku :: Sudoku
sudoku = [((0,0),3),((0,1),6),((0,4),7),((0,5),1),((0,6),2),
          ((1,1),5),((1,6),1),((1,7),8),
          ((2,2),9),((2,3),2),((2,5),4),((2,6),7),
          ((3,4),1),((3,5),3),((3,7),2),((3,8),8),
          ((4,0),4),((4,3),5),((4,5),2),((4,8),9),
          ((5,0),2),((5,1),7),((5,3),4),((5,4),6),
          ((6,2),5),((6,3),3),((6,5),8),((6,6),9),
          ((7,1),8),((7,2),3),((7,7),6),
          ((8,2),7),((8,3),6),((8,4),9),((8,7),4),((8,8),3)]
sudoku2 :: Sudoku
sudoku2 = [((0,0),5),((0,1),3),((0,4),7),
           ((1,0),6),((1,3),1),((1,4),9),((1,5),5),
           ((2,1),9),((2,2),8),((2,7),6),
           ((3,0),8),((3,4),6),((3,8),3),
           ((4,0),4),((4,3),8),((4,5),3),((4,8),1),
           ((5,0),7),((5,4),2),((5,8),6),
           ((6,1),6),((6,6),2),((6,7),8),
           ((7,3),4),((7,4),1),((7,5),9),((7,8),5),
           ((8,4),8),((8,7),7),((8,8),9)]

A megoldást kellő általánossággal igyekszünk megadni, hogy a nem egyértelműen kitölthető rejtvények esetén is találjunk megoldást.

Felhasznált számok egy adott sorban

Definiáljuk azt a függvényt, amely meghatározza, hogy mely számok kerültek már felhasználásra a megadott sorban!

numsInRow :: Sudoku -> Int -> [Int]

Test>
[5, 1, 8] :: [Int]
Test>
[4, 5, 2, 9] :: [Int]
Test>
[5, 3, 8, 9] :: [Int]
Test>
[[3, 6, 7, 1, 2], [5, 1, 8], [9, 2, 4, 7], [1, 3, 2, 8], [4, 5, 2, 9], [2, 7, 4, 6], [5, 3, 8, 9], [8, 3, 6], [7, 6, 9, 4, 3]] :: [[Int]]

Az alábbi példa a sudoku példa első sorát jeleníti meg:

Test>
367125189247132845292746538983676943518

Felhasznált számok egy adott oszlopban

Definiáljuk azt a függvényt, amely meghatározza, hogy mely számok kerültek már felhasználásra a megadott oszlopban!

numsInCol :: Sudoku -> Int -> [Int]

Test>
[7, 1, 6, 9] :: [Int]
Test>
[2, 5, 4, 3, 6] :: [Int]
Test>
[8, 2, 6, 4] :: [Int]
Test>
[[3, 4, 2], [6, 5, 7, 8], [9, 5, 3, 7], [2, 5, 4, 3, 6], [7, 1, 6, 9], [1, 4, 3, 2, 8], [2, 1, 7, 9], [8, 2, 6, 4], [8, 9, 3]] :: [[Int]]

Az alábbi példa a sudoku példa negyedik oszlopát jeleníti meg:

Test>
3671251892471328452927465389836769437169

Felhasznált számok egy blokkon belül

A feladat megoldása során szükségünk lesz az egyes blokkokban található értékekre is.

Test>
367125189247132845292746538983676943289

Ennek meghatározásához három függvényt definiálunk:

  1. Definiáljuk azt a leképező műveletet, amely egy pozíció segítségével megadja a befoglaló blokk sorszámát (0 és 8 közötti érték).

  2. Megadjuk azt a műveletet, amely egy blokk összes mezőjének pozícióját megadja.

  3. Megadjuk azt a műveletet, amely egy tetszőleges blokkban található összes értéket megad.

Blokk meghatározása

Definiáljuk azt a műveletet, amely megadja a blokk sorszámát, amelyben az adott pozíció található! A blokkok sorszámozása 0-val kezdődik és sorfolytonosan haladva 8-ig terjed.

Matematikai megfelelője a függvénynek a következő képlettel adható meg:

Sudoku196507e541f8686861039334c8d22232.png


Test>
3 :: Block
Test>
1 :: Block
Test>
8 :: Block

Szemléltetésként, az alábbi példa az (5,2) pozícióhoz tartozó blokk sorszámát adja meg:

Test>
0123456780123456783

Egy blokk pozíciói

Adjuk meg azt a függvényt, amely meghatározza egy tetszőleges blokk összes pozícióját! A definícióban ellenőrizzük, hogy a blokk sorszáma megfelelő-e, és amennyiben ez teljesül, úgy az error függvény segítségével jelezzük ezt! Az ilyenkor küldendő hibaüzenetre mintát a tesztesetek között láthatunk. A paramétert a show függvény segítségével lehet szöveggé alakítani.


Test>
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] :: [Pos]
Test>
[(3, 0), (3, 1), (3, 2), (4, 0), (4, 1), (4, 2), (5, 0), (5, 1), (5, 2)] :: [Pos]
Test>
[(6, 3), (6, 4), (6, 5), (7, 3), (7, 4), (7, 5), (8, 3), (8, 4), (8, 5)] :: [Pos]
Test>
⊥₁ :: [Pos]
⊥₁: blockToPositions: bad block number 9
CallStack (from HasCallStack):
  error, called at ./Sudoku.lhs:277:25 in main:Sudoku
Test>
⊥₁ :: [Pos]
⊥₁: blockToPositions: bad block number -1
CallStack (from HasCallStack):
  error, called at ./Sudoku.lhs:277:25 in main:Sudoku

Adott blokkban használt számok

Az előző függvény felhasználásával adjuk meg a blokkban felhasznált számok listáját!


Test>
[2, 8, 9] :: [Int]
Test>
[4, 2, 7] :: [Int]
Test>
[2, 1, 8, 7] :: [Int]
Test>
[[3, 6, 5, 9], [7, 1, 2, 4], [2, 1, 8, 7], [4, 2, 7], [1, 3, 5, 2, 4, 6], [2, 8, 9], [5, 8, 3, 7], [3, 8, 6, 9], [9, 6, 4, 3]] :: [[Int]]

Megfelelő-e a tábla?

Mielőtt rátérünk a feladvány formai követelmények vizsgálatára, egy segédfüggvényt definiálunk.

Tartalmaz-e ismétlést a lista?

Adjuk meg azt a műveletet, amely eldönti egy tetszőleges véges listáról, hogy az tartalmaz-e ismétlődéseket!


Test>
True :: Bool
Test>
False :: Bool
Test>
False :: Bool
Test>
False :: Bool

Tábla helyessége

Adjuk meg azt az ellenőrző függvényt, amely eldönti az adott feladvány helyességét!

Egy feladványt akkor tekintünk helyesnek, ha:

Megjegyzés: Korábban definiáltuk azokat a műveleteket, amely segítségével kiszámolható egy sorban, oszlopban és blokkban felhasznált értékek listája. Használjuk ezeket a műveleteket!


Test>
True :: Bool
Test>
False :: Bool
Test>
False :: Bool
Test>
False :: Bool
Test>
False :: Bool

Kitöltött-e a tábla?

Adjuk meg azt a függvényt, amely ellenőrzi, hogy az adott feladvány összes mezője ki van-e töltve, és minden mezője pontosan egyszer szerepel!

Megjegyzés: A függvénynél nem kell ellenőrizni, hogy milyen számok találhatóak a táblán!

isFilled :: Sudoku -> Bool

Test>
False :: Bool
Test>
True :: Bool
Test>
False :: Bool
Test>
False :: Bool
Test>
True :: Bool
Test>
False :: Bool
Test>
False :: Bool

Meg van-e oldva?

Adjuk meg azt a függvényt, amely eldönti, hogy az adott feladvány meg van-e oldva!

Egy feladványt akkor tekintünk megoldottnak, ha teljesen kitöltött és helyes.

isSolved :: Sudoku -> Bool

Test>
False :: Bool
Test>
True :: Bool

Üres mezők pozíciói

A kitöltés során szükségünk lesz azokra a mezőkre a rejtvényből, amelyek még üresek. Az alábbi két függvény segítségével ezt fogjuk meghatározni.

Üres-e a rejtvény mezője?

Definiáljuk azt a függvényt, amely eldönti, hogy egy mező üres-e!

Megjegyzés: A megoldásban nem használható fel a következő feladat függvénye (blankPositions)!


Test>
False :: Bool
Test>
True :: Bool

Szabad pozíciók

Az előző függvény segítségével adjuk meg azt a függvényt, amely meghatározza a szabad mezők pozícióját!

Megjegyzés: A szabad pozíciókat sor index szerint növekvő sorrendben adjuk meg!


Test>
[(0, 2), (0, 3), (0, 7), (0, 8), (1, 0), (1, 2), (1, 3), (1, 4), (1, 5), (1, 8), (2, 0), (2, 1), (2, 4), (2, 7), (2, 8), (3, 0), (3, 1), (3, 2), (3, 3), (3, 6), (4, 1), (4, 2), (4, 4), (4, 6), (4, 7), (5, 2), (5, 5), (5, 6), (5, 7), (5, 8), (6, 0), (6, 1), (6, 4), (6, 7), (6, 8), (7, 0), (7, 3), (7, 4), (7, 5), (7, 6), (7, 8), (8, 0), (8, 1), (8, 5), (8, 6)] :: [Pos]
Test>
[(0, 2), (0, 3), (0, 5), (0, 6), (0, 7), (0, 8), (1, 1), (1, 2), (1, 6), (1, 7), (1, 8), (2, 0), (2, 3), (2, 4), (2, 5), (2, 6), (2, 8), (3, 1), (3, 2), (3, 3), (3, 5), (3, 6), (3, 7), (4, 1), (4, 2), (4, 4), (4, 6), (4, 7), (5, 1), (5, 2), (5, 3), (5, 5), (5, 6), (5, 7), (6, 0), (6, 2), (6, 3), (6, 4), (6, 5), (6, 8), (7, 0), (7, 1), (7, 2), (7, 6), (7, 7), (8, 0), (8, 1), (8, 2), (8, 3), (8, 5), (8, 6)] :: [Pos]

Szabad mezők lehetséges értékei

A továbbiakban tudnunk kell, hogy az egyes mezőkbe milyen érték(ek)et írhatunk be. Az alábbi két függvényt erre fogjuk felhasználni.

Mezőbe beírható értékek

Adjuk meg azt a függvényt, amely meghatározza, mely értékek írhatóak egy adott mezőbe!

A függvény eredménye:

Megjegyzések:


Test>
[] :: [Int]
Test>
[4, 8] :: [Int]

Felhasználható számok a szabad pozíciókon

Az előző függvény felhasználásával adjuk meg a szabad pozíciók és az ezekbe beírható számok párosait!


Test>
[((0, 2), [4, 8]), ((0, 3), [8, 9]), ((0, 7), [5, 9]), ((0, 8), [4, 5]), ((1, 0), [7]), ((1, 2), [2, 4]), ((1, 3), [9]), ((1, 4), [3]), ((1, 5), [6, 9]), ((1, 8), [4, 6]), ((2, 0), [1, 8]), ((2, 1), [1]), ((2, 4), [3, 5, 8]), ((2, 7), [3, 5]), ((2, 8), [5, 6]), ((3, 0), [5, 6, 9]), ((3, 1), [9]), ((3, 2), [6]), ((3, 3), [7, 9]), ((3, 6), [4, 5, 6]), ((4, 1), [1, 3]), ((4, 2), [1, 6, 8]), ((4, 4), [8]), ((4, 6), [3, 6]), ((4, 7), [1, 3, 7]), ((5, 2), [1, 8]), ((5, 5), [9]), ((5, 6), [3, …, ……]), ((…, …), […, ……]), (…, …), …, ……] :: [(Pos, [Int])]
Test>
[((0, 2), [1, 2, 4]), ((0, 3), [2, 6]), ((0, 5), [2, 4, 6, 8]), ((0, 6), [1, 4, 8, 9]), ((0, 7), [1, 2, 4, 9]), ((0, 8), [2, 4, 8]), ((1, 1), [2, 4, 7]), ((1, 2), [2, 4, 7]), ((1, 6), [3, 4, 7, 8]), ((1, 7), [2, 3, 4]), ((1, 8), [2, 4, 7, 8]), ((2, 0), [1, 2]), ((2, 3), [2, 3]), ((2, 4), [3, 4]), ((2, 5), [2, 4]), ((2, 6), [1, 3, 4, 5, 7]), ((2, 8), [2, 4, 7]), ((3, 1), [1, 2, 5]), ((3, 2), [1, 2, 5, 9]), ((3, 3), [5, 7, 9]), ((3, 5), [1, 4, 7]), ((3, 6), [4, 5, 7, …, ……]), ((3, 7), [2, 4, …, ……]), ((4, 1), [2, …, ……]), ((…, …), […, ……]), (…, …), …, ……] :: [(Pos, [Int])]

Megoldható-e?

Adjuk meg azt a függvényt, amely eldönti, hogy a feladvány megoldható-e az adott állapotból!

A megoldhatóságot csak egy lépés erejéig vizsgáljuk, és a feladványt akkor tekintjük megoldhatónak, ha létezik még szabad pozíció és mindegyik szabad pozíció esetén van legalább egy beírható érték!

hasSolution :: [(Pos, [Int])] -> Bool

Test>
False :: Bool
Test>
False :: Bool
Test>
True :: Bool

Egyértelműen kitölthető mezők

Adjuk meg azt a függvényt, amely megadja az egyértelműen kitölthető mezők listáját!

Megjegyzés: Egy mező akkor egyértelműen kitölthető, ha pontosan egy érték írható bele.

uniqueNumForBlankPos :: [(Pos, [Int])] -> [(Pos, Int)]

Test>
[((1, 0), 7), ((1, 3), 9), ((1, 4), 3), ((2, 1), 1), ((3, 1), 9), ((3, 2), 6), ((4, 4), 8), ((5, 5), 9), ((7, 6), 5), ((8, 0), 1), ((8, 5), 5)] :: [(Pos, Int)]
Test>
[((4, 4), 5), ((6, 5), 7), ((6, 8), 4), ((7, 7), 3)] :: [(Pos, Int)]

Néhány szemléltető példa:

Test>
36712518924713284529274653898367694379319689515
Test>
5376195986863483172662841958795743

Megoldás beszúrása

Adjuk meg az egy mezőt kitöltő műveletet!

Megyjegyzés: A mezők sorrendje tetszőleges, a kitöltött mezőt elég a lista elejére beszúrni. Mielőtt azonban kitöltenénk egy mezőt, ellenőrizzük, hogy az a pozíció valóban szabad-e! Amennyiben nem, úgy az error segítségével jelezzünk hibát! (A konkrét üzenetre példát ld. a tesztesetekben. Itt ismét alkalmazhatjuk a show függvényt.)

insertElem :: Sudoku -> Pos -> Int -> Sudoku

Test>
[((4, 4), 5), ((0, 0), 5), ((0, 1), 3), ((0, 4), 7), ((1, 0), 6), ((1, 3), 1), ((1, 4), 9), ((1, 5), 5), ((2, 1), 9), ((2, 2), 8), ((2, 7), 6), ((3, 0), 8), ((3, 4), 6), ((3, 8), 3), ((4, 0), 4), ((4, 3), 8), ((4, 5), 3), ((4, 8), 1), ((5, 0), 7), ((5, 4), 2), ((5, 8), 6), ((6, 1), 6), ((6, 6), 2), ((6, 7), 8), ((7, 3), 4), ((7, 4), 1), ((7, 5), 9), ((7, 8), 5), ((8, 4), 8), ((8, 7), 7), ((8, 8), 9)] :: Sudoku
Test>
⊥₁ :: Sudoku
⊥₁: insertElem: position (0,0) is not blank
CallStack (from HasCallStack):
  error, called at ./Sudoku.lhs:551:21 in main:Sudoku
Test>
⊥₁ :: Sudoku
⊥₁: insertElem: position (0,0) is not blank
CallStack (from HasCallStack):
  error, called at ./Sudoku.lhs:551:21 in main:Sudoku

Egy lépés végrehajtása

Adjuk meg azt a függvényt, amely elvégez egy lépést, azaz kitölti a feladvány egy szabad mezőjét!

A kitöltést az alábbiak szerint végezzük:

step :: Sudoku -> [Sudoku]

Test>
[[((1, 0), 7), ((0, 0), 3), ((0, 1), 6), ((0, 4), 7), ((0, 5), 1), ((0, 6), 2), ((1, 1), 5), ((1, 6), 1), ((1, 7), 8), ((2, 2), 9), ((2, 3), 2), ((2, 5), 4), ((2, 6), 7), ((3, 4), 1), ((3, 5), 3), ((3, 7), 2), ((3, 8), 8), ((4, 0), 4), ((4, 3), 5), ((4, 5), 2), ((4, 8), 9), ((5, 0), 2), ((5, 1), 7), ((5, 3), 4), ((5, 4), 6), ((6, 2), 5), ((6, 3), 3), ((6, 5), 8), ((6, 6), 9), ((7, 1), 8), ((7, 2), 3), ((7, 7), 6), ((8, 2), 7), ((8, 3), 6), ((8, 4), 9), ((8, 7), 4), ((8, 8), 3)]] :: [Sudoku]
Test>
[[((1, 3), 9), ((1, 0), 7), ((0, 0), 3), ((0, 1), 6), ((0, 4), 7), ((0, 5), 1), ((0, 6), 2), ((1, 1), 5), ((1, 6), 1), ((1, 7), 8), ((2, 2), 9), ((2, 3), 2), ((2, 5), 4), ((2, 6), 7), ((3, 4), 1), ((3, 5), 3), ((3, 7), 2), ((3, 8), 8), ((4, 0), 4), ((4, 3), 5), ((4, 5), 2), ((4, 8), 9), ((5, 0), 2), ((5, 1), 7), ((5, 3), 4), ((5, 4), 6), ((6, 2), 5), ((6, 3), 3), ((6, 5), 8), ((6, 6), 9), ((7, 1), 8), ((7, 2), 3), ((7, 7), 6), ((8, 2), 7), ((8, 3), 6), ((8, 4), 9), ((8, 7), 4), ((8, 8), 3)]] :: [Sudoku]
Test>
[[((4, 4), 5), ((0, 0), 5), ((0, 1), 3), ((0, 4), 7), ((1, 0), 6), ((1, 3), 1), ((1, 4), 9), ((1, 5), 5), ((2, 1), 9), ((2, 2), 8), ((2, 7), 6), ((3, 0), 8), ((3, 4), 6), ((3, 8), 3), ((4, 0), 4), ((4, 3), 8), ((4, 5), 3), ((4, 8), 1), ((5, 0), 7), ((5, 4), 2), ((5, 8), 6), ((6, 1), 6), ((6, 6), 2), ((6, 7), 8), ((7, 3), 4), ((7, 4), 1), ((7, 5), 9), ((7, 8), 5), ((8, 4), 8), ((8, 7), 7), ((8, 8), 9)]] :: [Sudoku]
Test>
8 :: Int
Test>
[] :: [Sudoku]

Megoldás keresése

Adjuk meg azt a műveletet, amely megold egy feladványt!

A feladványt az előző (step) művelet segítségével tudjuk megoldani, amelyet addig ismételünk, amíg a feladvány teljesen ki nincs töltve! A függvény eredménye egy lista amelyben a helyes megoldások találhatóak! Ügyeljünk arra, hogy csak olyan feladványt kezdjünk el megoldani, amely helyes, azaz megfelel a Sudoku formai követelményeinek (isSudokuPuzzle)! Amennyiben ez nem teljesül, az error segítségével jelezzünk hibát (ld. a teszteseteket)!

Megjegyzés: Ne feledkezzünk meg arról, hogy egy-egy végrehajtott lépés több megoldáshoz is vezethet, ha a feladvány nem egyértelmű! Azaz minden ilyen állapotot meg kell próbálni folytatni és megoldást keresni!

solve :: Sudoku -> [Sudoku]

Test>
[[((8, 6), 8), ((8, 5), 5), ((8, 1), 2), ((8, 0), 1), ((6, 1), 4), ((6, 4), 2), ((7, 4), 4), ((6, 8), 7), ((7, 8), 2), ((7, 5), 7), ((7, 6), 5), ((7, 0), 9), ((7, 3), 1), ((6, 0), 6), ((6, 7), 1), ((5, 6), 3), ((5, 7), 5), ((5, 8), 1), ((5, 5), 9), ((5, 2), 8), ((4, 7), 7), ((4, 6), 6), ((4, 2), 1), ((4, 4), 8), ((4, 1), 3), ((3, 6), 4), ((3, 3), 7), ((3, 0), 5), ((3, 2), 6), ((3, 1), 9), ((2, 8), 6), ((2, 7), 3), ((2, 4), 5), ((2, 0), 8), ((2, 1), 1), ((1, 8), 4), ((1, 5), 6), ((1, 4), 3), ((1, 2), 2), ((0, 7), 9), ((0, 8), 5), ((0, 2), 4), ((0, 3), 8), ((…, …), …), …, ……]] :: [Sudoku]
Test>
[[((8, 6), 1), ((8, 5), 6), ((8, 3), 2), ((8, 2), 5), ((8, 1), 4), ((8, 0), 3), ((7, 0), 2), ((7, 7), 3), ((7, 6), 6), ((7, 2), 7), ((7, 1), 8), ((6, 8), 4), ((6, 2), 1), ((6, 5), 7), ((6, 3), 5), ((6, 0), 9), ((5, 7), 5), ((1, 8), 8), ((1, 2), 2), ((1, 1), 7), ((0, 2), 4), ((0, 8), 2), ((0, 6), 9), ((0, 7), 1), ((1, 7), 4), ((1, 6), 3), ((5, 6), 8), ((5, 5), 4), ((5, 2), 3), ((5, 1), 1), ((3, 7), 2), ((3, 2), 9), ((3, 1), 5), ((3, 5), 1), ((3, 6), 4), ((2, 8), 7), ((2, 6), 5), ((2, 3), 3), ((2, 0), 1), ((0, 5), 8), ((0, 3), 6), ((2, 5), 2), ((2, 4), 4), ((…, …), …), …, ……]] :: [Sudoku]
Test>
2 :: Int
Test>
⊥₁ :: [Sudoku]
⊥₁: solve: improper sudoku
CallStack (from HasCallStack):
  error, called at ./Sudoku.lhs:626:20 in main:Sudoku
Test>
⊥₁ :: [Sudoku]
⊥₁: solve: improper sudoku
CallStack (from HasCallStack):
  error, called at ./Sudoku.lhs:626:20 in main:Sudoku

Néhány szemléltető példa:

Test>
852142472759161351987618347569635814632954897367125189247132845292746538983676943
Test>
162543236784175958274291438431295147531862437976925537619598686348317266284195879