packages feed

sum-pyramid 0.0 → 0.0.1

raw patch · 9 files changed

+177/−142 lines, 9 filesdep ~basedep ~comfort-arraydep ~containers

Dependency ranges changed: base, comfort-array, containers, lapack, optparse-applicative, random

Files

Makefile view
@@ -1,4 +1,4 @@-CABALOPTS :=+CABALOPTS := --disable-documentation  .PHONY:	all 
puzzle.tex view
@@ -6,10 +6,11 @@ \usepackage{pict2e} \usepackage{color} -\newenvironment{puzzle}{\noindent\mbox{}\vfill}{\newpage}+\newenvironment{puzzle}{\noindent\mbox{}\vfill}{\vfill\newpage}  \newcommand\puzzles{ \fontsize{36}{42}\selectfont+\linethickness{0.1em} \setlength{\unitlength}{2.1em} \input{mixed} %
src/Common.hs view
@@ -1,21 +1,45 @@+{-# LANGUAGE TypeFamilies #-} module Common where  import qualified Data.Array.Comfort.Boxed as BoxedArray import qualified Data.Array.Comfort.Shape as Shape+import qualified Data.Set as Set import Data.Array.Comfort.Boxed (Array)+import Data.Map (Map)+import Data.Set (Set) +import qualified Combinatorics  + data Op = Add | Mul    deriving (Eq, Ord, Enum, Show) -sizeFromOps :: Array (Shape.LowerTriangular ShapeInt) op -> Int-sizeFromOps = succ . Shape.size . Shape.triangularSize . BoxedArray.shape+newtype ShapeOp = ShapeOp {shapeOpSize :: Int} +instance Shape.C ShapeOp where+   size (ShapeOp n) = max 0 $ n-1++instance Shape.Indexed ShapeOp where+   type Index ShapeOp = Int+   indices sh = take (Shape.size sh) [0..]+   unifiedOffset sh = Shape.unifiedOffset (Shape.ZeroBased (Shape.size sh))+++sizeFromOps :: Array (Shape.LowerTriangular ShapeOp) op -> Int+sizeFromOps = shapeOpSize . Shape.triangularSize . BoxedArray.shape++ type ShapeInt = Shape.ZeroBased Int   type SolutionCheck a =-      BoxedArray.Array (Shape.LowerTriangular ShapeInt) Op ->-      [((Int,Int),a)] ->+      BoxedArray.Array (Shape.LowerTriangular ShapeOp) Op ->+      Map (Int,Int) a ->       Bool+++allCellSelections :: Int -> [Set (Int, Int)]+allCellSelections n =+   map Set.fromList $ Combinatorics.tuples n $ Shape.indices $+   Shape.lowerTriangular $ Shape.ZeroBased n
src/LinearAlgebra.hs view
@@ -1,5 +1,7 @@ module LinearAlgebra where +import Common (allCellSelections)+ import qualified Numeric.LAPACK.Matrix.Triangular as Triangular import qualified Numeric.LAPACK.Matrix.Layout as Layout import qualified Numeric.LAPACK.Matrix as Matrix@@ -8,14 +10,14 @@ import Numeric.LAPACK.Matrix (ShapeInt, (#*|)) import Numeric.LAPACK.Format ((##)) -import qualified Combinatorics- import qualified Data.Array.Comfort.Boxed as BoxedArray import qualified Data.Array.Comfort.Storable as Array+import qualified Data.Array.Comfort.Bool as ComfortSet import qualified Data.Array.Comfort.Shape as Shape-import qualified Data.IntSet as IntSet-import qualified Data.Set as Set+import qualified Data.Map as Map import Data.Array.Comfort.Storable (Array)+import Data.Map (Map)+import Data.Set (Set)  import Data.Foldable (for_) import Data.Tuple.HT (mapSnd)@@ -24,6 +26,7 @@  {- $setup >>> import qualified Data.Array.Comfort.Storable as Array+>>> import qualified Data.Map as Map >>> import Data.Tuple.HT (mapSnd) >>> >>> myRound :: Double -> Integer@@ -71,45 +74,43 @@    Matrix.fromRows (Shape.lowerTriangular shape) $    map (pyramid . Vector.unit shape) $ take n [0..] -addIndices :: [[Maybe a]] -> [((Int,Int), a)]-addIndices puzzle = do+addIndices :: [[Maybe a]] -> Map (Int,Int) a+addIndices puzzle = Map.fromList $ do    (i, xs) <- zip [0..] puzzle    (j, Just x) <- zip [0..] xs    return ((i,j),x)  {- |->>> mapSnd (map myRound . Array.toList) $ solve 3 [((0,0),8), ((2,0),1), ((2,2),3)]+>>> mapSnd (map myRound . Array.toList) $ solve 3 $ Map.fromList [((0,0),8), ((2,0),1), ((2,2),3)] (3,[8,3,5,1,2,3]) -} solve ::-   Int -> [((Int,Int),Double)] ->+   Int -> Map (Int,Int) Double ->    (Int, Array (Shape.LowerTriangular ShapeInt) Double) solve n indexed =    let fullBasis = Matrix.transpose $ basis (Matrix.shapeInt n)-       selected =-         Matrix.takeRowArray-            (BoxedArray.vectorFromList (map fst indexed))-            fullBasis+       selected = Matrix.takeRowSet (Map.keysSet indexed) fullBasis    in mapSnd ((fullBasis #*|) . Matrix.flattenColumn)          (Singular.leastSquaresMinimumNormRCond 1e-5 selected $-          Matrix.singleColumn Layout.ColumnMajor $-          Vector.autoFromList (map snd indexed))+          Matrix.singleColumn Layout.ColumnMajor $ Array.fromMap indexed) -solvable :: Int -> [(Int,Int)] -> Bool+solvable :: Int -> Set (Int,Int) -> Bool solvable n =    let shape = Matrix.shapeInt n        fullBasis = basis shape    in \ixs ->          (n==) $ length $ takeWhile (1e-5<) $ Vector.toList $-         (#*| Vector.one shape) $ Singular.values $-         Matrix.takeColumnArray (BoxedArray.vectorFromList ixs) fullBasis+         (#*| Vector.one ixs) $ Singular.values $+         Matrix.takeColumnSet ixs fullBasis -solvables :: Int -> [[(Int,Int)]]+{- |+>>> map (length . solvables) [0..5]+[1,1,3,17,149,1824]+-}+solvables :: Int -> [Set (Int,Int)] solvables n =    let check = solvable n-   in filter check $-      Combinatorics.tuples n $ Shape.indices $-      Shape.lowerTriangular $ Matrix.shapeInt n+   in filter check $ allCellSelections n  {- Check, whether a sum pyramid contains a sub-pyramid of size k@@ -117,27 +118,12 @@ If yes, then the pyramid has redundancies in a sub-pyramid and is not solvable. -}-wellcrowded :: Int -> [(Int,Int)] -> Bool+wellcrowded :: Int -> Set (Int,Int) -> Bool wellcrowded n ixs =    let triShape = Shape.lowerTriangular $ Matrix.shapeInt n-       set = Set.fromList ixs-       countSubTriangle (i,j) k =-         length $-         filter (\(si,sj) -> Set.member (i+si,j+sj) set) $-         Shape.indices $ Shape.lowerTriangular $ Matrix.shapeInt k-   in and $ do-         (i,j) <- Shape.indices triShape-         k <- [0..n-i]-         return $ countSubTriangle (i,j) k <= k--wellcrowdedIntSet :: Int -> [(Int,Int)] -> Bool-wellcrowdedIntSet n ixs =-   let triShape = Shape.lowerTriangular $ Matrix.shapeInt n-       set = IntSet.fromList $ map (Shape.offset triShape) ixs+       set = ComfortSet.fromSet triShape ixs        countSubTriangle (i,j) k =-         length $-         filter (\(si,sj) ->-            flip IntSet.member set $ Shape.offset triShape (i+si,j+sj)) $+         length $ filter (\(si,sj) -> ComfortSet.member (i+si,j+sj) set) $          Shape.indices $ Shape.lowerTriangular $ Matrix.shapeInt k    in and $ do          (i,j) <- Shape.indices triShape@@ -155,20 +141,18 @@  . * . * . . * -}-counterexamples :: Int -> [[(Int, Int)]]+counterexamples :: Int -> [Set (Int, Int)] counterexamples n =    let check = solvable n-   in filter (\ixs -> check ixs /= wellcrowded n ixs) $-      Combinatorics.tuples n $ Shape.indices $-      Shape.lowerTriangular $ Matrix.shapeInt n+   in filter (\ixs -> check ixs /= wellcrowded n ixs) $ allCellSelections n  -boolMatrix :: Int -> [(Int, Int)] -> Matrix.Lower ShapeInt Float+boolMatrix :: Int -> Set (Int, Int) -> Matrix.Lower ShapeInt Float boolMatrix n ixs =    Triangular.fromLowerRowMajor $    Array.fromAssociations 0       (Shape.lowerTriangular $ Matrix.shapeInt n)-      (map (\ix -> (ix,1::Float)) ixs)+      (Map.toList $ Map.fromSet (const (1::Float)) ixs)   test :: IO ()
src/Main.hs view
@@ -4,11 +4,9 @@ import qualified UniqueLogic as Logic import Common -import qualified Combinatorics- import qualified Control.Monad.Trans.Class as MT import qualified Control.Monad.Trans.State as MS-import Control.Monad (replicateM, join)+import Control.Monad (replicateM, join, guard) import Control.Applicative (pure, (<*>), (<|>))  import qualified System.Random as Random@@ -18,6 +16,7 @@ import qualified Data.Array.Comfort.Boxed as BoxedArray import qualified Data.Array.Comfort.Shape as Shape import qualified Data.List.HT as ListHT+import qualified Data.Map as Map import qualified Data.Set as Set import Data.Array.Comfort.Boxed (Array, (!)) import Data.Foldable (for_)@@ -47,7 +46,7 @@    Allowed ->    Array ShapeInt Integer ->    MS.State g-      (Array (Shape.LowerTriangular ShapeInt) Op,+      (Array (Shape.LowerTriangular ShapeOp) Op,        Array (Shape.LowerTriangular ShapeInt) Integer) pyramid allowed base = do    let nextRow xs =@@ -71,10 +70,9 @@                else go ys0    let xs0 = BoxedArray.toList base    let shape@(Shape.ZeroBased n) = BoxedArray.shape base-   let shape1 = Shape.ZeroBased (n-1)    (ops,xs) <- go xs0    return-      (BoxedArray.fromList (Shape.lowerTriangular shape1) $+      (BoxedArray.fromList (Shape.lowerTriangular (ShapeOp n)) $          concat $ reverse ops,        BoxedArray.fromList (Shape.lowerTriangular shape) $          concat $ reverse (xs0:xs))@@ -84,7 +82,7 @@    SolutionCheck Integer ->    Allowed -> Int -> Integer ->    MS.State g-      (Array (Shape.LowerTriangular ShapeInt) Op,+      (Array (Shape.LowerTriangular ShapeOp) Op,        Array (Shape.LowerTriangular ShapeInt) (Integer,Bool)) construct check allowed n maxV = do    let shape = Shape.ZeroBased n@@ -95,7 +93,7 @@          selected <-             MS.evalStateT (replicateM n pick) $             Set.fromList $ Shape.indices triShape-         let puzzle = map (\ij -> (ij, pyr!ij)) selected+         let puzzle = Map.fromSet (pyr!) $ Set.fromList selected          if check ops puzzle             then return selected             else go@@ -107,35 +105,39 @@  latexFromPuzzle ::    String ->-   Either Int (Array (Shape.LowerTriangular ShapeInt) Op) ->+   Either Int (Array (Shape.LowerTriangular ShapeOp) Op) ->    Array (Shape.LowerTriangular ShapeInt) (Integer,Bool) ->    [String]-latexFromPuzzle hidden mops xs =+latexFromPuzzle hiddenMacro mops xs =    let n = either id sizeFromOps mops in    printf "\\begin{picture}(%d,%d)" (2*n) n :-   map (\(i,j) -> printf "\\put(%d,%d){\\framebox(2,1){}}" (n-1-i + 2*j) (n-i))-      (Shape.indices $ Shape.lowerTriangular $ Shape.ZeroBased n) ++-   (BoxedArray.toAssociations xs >>= \((i,j),(x,display)) ->-      if null hidden && not display-         then []-         else-            let cell :: String-                cell =-                   if display-                      then printf "%d" x-                      else printf "\\%s{%d}" hidden x-            in [printf "\\put(%d,%d){\\makebox(2,1)[c]{%s}}"-                  (n-1-i + 2*j) (n-i) cell]) +++   (take n [0..] >>= \i ->+      printf "\\put(%d,%d){\\line(0,-1){1}\\line(1,0){%d}\\line(0,-1){1}}"+         (n-1-i) (n-i) (2*i+2) :+      flip map (take (n-i-1) $ iterate (2+) (2+i)) (\j ->+         printf "\\put(%d,%d){\\line(0,1){1}}" j i)) +++   printf "\\put(0,0){\\line(1,0){%d}}" (2*n) :+   (do+      ((i,j),(x,display)) <- BoxedArray.toAssociations xs+      guard $ display || not (null hiddenMacro)+      let cell :: String+          cell =+             if display+                then printf "%d" x+                else printf "\\%s{%d}" hiddenMacro x+      [printf "\\put(%d,%d){\\makebox(2,1)[c]{%s}}" (n-1-i + 2*j) (n-i-1) cell])+   ++    (case mops of       Left _ -> []       Right ops ->          let half = 0.5 :: Double in          BoxedArray.toAssociations ops >>= \((i,j),op) ->+            let h = n-i-1 in             [printf "\\put(%d,%d){\\textcolor{white}{\\circle*{0.5}}}"-               (n-i + 2*j) (n-i),-             printf "\\put(%d,%d){\\circle{0.5}}" (n-i + 2*j) (n-i),+               (n-i + 2*j) h,+             printf "\\put(%d,%d){\\circle{0.5}}" (n-i + 2*j) h,              printf "\\put(%.1f,%.1f){\\makebox(1,1)[c]{$%s$}}"-               (fromIntegral (n-i + 2*j) - half) (fromIntegral (n-i) - half)+               (fromIntegral (n-i + 2*j) - half) (fromIntegral h - half)                (case op of Add -> "+"; Mul -> "\\times{}")]) ++    "\\end{picture}" :    []@@ -143,7 +145,7 @@ mainCreate ::    (SolutionCheck Integer, (Allowed,Bool)) ->    Int -> Int -> Integer -> String -> String -> IO ()-mainCreate (check,(allowed,displayOps)) n number maxV env hidden =+mainCreate (check,(allowed,displayOps)) n number maxV env hiddenMacro =    putStr . unlines .       concatMap          ((if null env@@ -151,7 +153,7 @@             else (\pic ->                      printf "\\begin{%s}" env : pic ++                      printf "\\end{%s}" env : []))-            . uncurry (latexFromPuzzle hidden)+            . uncurry (latexFromPuzzle hiddenMacro)             . mapFst (if displayOps then Right else const (Left n))) .       MS.evalState (replicateM number $ construct check allowed n maxV)          =<< Random.initStdGen@@ -163,10 +165,11 @@          <*>             (                (OP.flag'-                  (\ops xs -> LinAlg.solvable (sizeFromOps ops) (map fst xs),+                  (\ops xs ->+                        LinAlg.solvable (sizeFromOps ops) (Map.keysSet xs),                      (Allowed {allowedAdd = True, allowedMul = False}, False)) $                   OP.long "allow-gaps" <>-                  OP.help "Employ both addition and multiplication")+                  OP.help "Puzzles maybe not be solvable step by step")                <|>                (fmap ((,) Logic.solvableMixed) $                   (OP.flag'@@ -249,12 +252,10 @@ 573549 13604001 -}-mainCount :: (Int -> [(Int,Int)] -> Bool) -> IO ()+mainCount :: (Int -> Set (Int,Int) -> Bool) -> IO () mainCount check =    for_ [0..] $ \n ->-      print $ length $ filter (check n) $-      Combinatorics.tuples n $ Shape.indices $-      Shape.lowerTriangular $ Shape.ZeroBased n+      print $ length $ filter (check n) $ allCellSelections n  commandCount :: OP.Mod OP.CommandFields (IO ()) commandCount =
src/UniqueLogic.hs view
@@ -6,23 +6,24 @@ import qualified UniqueLogic.ST.TF.System.Simple as Sys import qualified UniqueLogic.ST.TF.ZeroFractional as ZeroFrac -import qualified Combinatorics- import Control.Monad.ST (ST, runST)  import qualified Data.Array.Comfort.Boxed as BoxedArray import qualified Data.Array.Comfort.Shape as Shape import qualified Data.Traversable as Trav import qualified Data.Foldable as Fold+import qualified Data.Map as Map import Data.Array.Comfort.Boxed ((!))+import Data.Map (Map)+import Data.Set (Set) import Data.Foldable (for_, traverse_) import Data.Maybe (isJust)-import Data.Tuple.HT (mapSnd)   {- $setup >>> import qualified Data.Array.Comfort.Boxed as BoxedArray >>> import qualified Data.Array.Comfort.Shape as Shape+>>> import qualified Data.Map as Map >>> import Common -} @@ -32,11 +33,8 @@  system ::    BoxedArray.Array-      (Shape.LowerTriangular ShapeInt)-      (Variable s a ->-       Variable s a ->-       Variable s a ->-       System s ()) ->+      (Shape.LowerTriangular ShapeOp)+      (Variable s a -> Variable s a -> Variable s a -> System s ()) ->    ST s       (BoxedArray.Array (Shape.LowerTriangular ShapeInt) (Variable s a),        System s ())@@ -55,40 +53,38 @@   {- |->>> solve 3 [((0,0),1), ((1,0),1), ((2,0),1::Integer)]+>>> solve 3 $ Map.fromList [((0,0),1), ((1,0),1), ((2,0),1::Integer)] BoxedArray...Triangular... 3... [Just 1,Just 1,Just 0,Just 1,Just 0,Just 0] ->>> solve 3 [((0,0),1), ((2,0),1), ((2,2),1::Integer)]+>>> solve 3 $ Map.fromList [((0,0),1), ((2,0),1), ((2,2),1::Integer)] BoxedArray...Triangular... 3... [Just 1,Nothing,Nothing,Just 1,Nothing,Just 1] -} solve ::    (Num a) =>-   Int -> [((Int,Int),a)] ->+   Int -> Map (Int,Int) a ->    BoxedArray.Array (Shape.LowerTriangular ShapeInt) (Maybe a) solve n xs =    runST       (do          (vars, sys) <-             system $-            BoxedArray.replicate-               (Shape.lowerTriangular $ Shape.ZeroBased $ n-1)-               Rule.add+            BoxedArray.replicate (Shape.lowerTriangular $ ShapeOp n) Rule.add          Sys.solve $ do             sys-            for_ xs $ \(ij,x) ->+            for_ (Map.toList xs) $ \(ij,x) ->                Rule.equ (vars!ij) =<< Sys.constant x          traverse Sys.query vars)  {- |->>> solveMixed (BoxedArray.fromList (Shape.lowerTriangular $ Shape.ZeroBased 1) [Mul]) [((0,0),0), ((1,1),0::Rational)]+>>> solveMixed (BoxedArray.fromList (Shape.lowerTriangular $ ShapeOp 2) [Mul]) (Map.fromList [((0,0),0), ((1,1),0::Rational)]) BoxedArray...Triangular... 2... [Just (0 % 1),Nothing,Just (0 % 1)]->>> solveMixed (BoxedArray.fromList (Shape.lowerTriangular $ Shape.ZeroBased 1) [Mul]) [((0,0),0), ((1,1),5::Rational)]+>>> solveMixed (BoxedArray.fromList (Shape.lowerTriangular $ ShapeOp 2) [Mul]) (Map.fromList [((0,0),0), ((1,1),5::Rational)]) BoxedArray...Triangular... 2... [Just (0 % 1),Just (0 % 1),Just (5 % 1)] -} solveMixed ::    (ZeroFrac.C a) =>-   BoxedArray.Array (Shape.LowerTriangular ShapeInt) Op ->-   [((Int,Int),a)] ->+   BoxedArray.Array (Shape.LowerTriangular ShapeOp) Op ->+   Map (Int,Int) a ->    BoxedArray.Array (Shape.LowerTriangular ShapeInt) (Maybe a) solveMixed ops xs =    runST@@ -100,21 +96,22 @@          (vars, sys) <- system $ fmap rule ops          Sys.solve $ do             sys-            for_ xs $ \(ij,x) ->+            for_ (Map.toList xs) $ \(ij,x) ->                Rule.equ (vars!ij) =<< Sys.constant x          traverse Sys.query vars)  -solvable :: Int -> [(Int, Int)] -> Bool-solvable n = Fold.all isJust . solve n . map (\ij -> (ij, 0::Integer))+solvable :: Int -> Set (Int, Int) -> Bool+solvable n = Fold.all isJust . solve n . Map.fromSet (const (0::Integer)) -solvables :: Int -> [[(Int,Int)]]-solvables n =-   filter (solvable n) $-   Combinatorics.tuples n $ Shape.indices $-   Shape.lowerTriangular $ Shape.ZeroBased n+{- |+>>> map (length . solvables) [0..5]+[1,1,3,16,122,1188]+-}+solvables :: Int -> [Set (Int,Int)]+solvables n = filter (solvable n) $ allCellSelections n   solvableMixed :: SolutionCheck Integer solvableMixed ops puzzle =-   Fold.all isJust $ solveMixed ops $ map (mapSnd toRational) puzzle+   Fold.all isJust $ solveMixed ops $ fmap toRational puzzle
sum-pyramid.cabal view
@@ -1,5 +1,5 @@ Name:                sum-pyramid-Version:             0.0+Version:             0.0.1 Synopsis:            Create Sum Pyramid (Additionstreppe) exercises Description:   Create Sum Pyramid (Additionstreppe) exercises.@@ -7,6 +7,18 @@   and the program emits LaTeX code for puzzles.   .   > sum-pyramid create --size 5+  .+  > nix-shell --run "make puzzle.pdf"+  .+  You may also use multiplications (@--multiplication@),+  or both addition and multiplication (@--mixed@).+  In case of additions only,+  you may allow puzzles that are uniquely solvable,+  but possibly not step-by-step (@--allow-gaps@).+  You can also control via LaTeX macros+  whether and how unknown cells are displayed.+  .+  Example output: http://code.henning-thielemann.de/sum-pyramid/puzzle.pdf Homepage:            https://hub.darcs.net/thielema/sum-pyramid License:             BSD3 License-File:        LICENSE@@ -21,7 +33,7 @@   puzzle.tex  Source-Repository this-  Tag:         0.0+  Tag:         0.0.1   Type:        darcs   Location:    https://hub.darcs.net/thielema/sum-pyramid @@ -31,12 +43,12 @@  Executable sum-pyramid   Build-Depends:-    lapack >=0.5.1 && <0.6,+    lapack >=0.5.2 && <0.6,     unique-logic-tf >=0.5.1 && <0.6,     combinatorial >=0.1.1 && <0.2,-    random >=1.2.1 && <1.3,-    comfort-array >=0.5 && <0.6,-    containers >=0.5.4 && <0.8,+    random >=1.2.1 && <1.4,+    comfort-array >=0.5.5 && <0.6,+    containers >=0.5.4 && <0.9,     transformers >=0.3 && <0.7,     shell-utility >=0.1 && <0.2,     optparse-applicative >=0.11 && <0.19,@@ -63,7 +75,7 @@     containers,     transformers,     utility-ht,-    base+    base >=4.5 && <5   Default-Language:    Haskell2010   GHC-Options:         -Wall   Hs-Source-Dirs:      src, test
test/Test/LinearAlgebra.hs view
@@ -1,5 +1,5 @@ -- Do not edit! Automatically created with doctest-extract from src/LinearAlgebra.hs-{-# LINE 25 "src/LinearAlgebra.hs" #-}+{-# LINE 27 "src/LinearAlgebra.hs" #-}  module Test.LinearAlgebra where @@ -7,8 +7,9 @@ import Test.DocTest.Base import qualified Test.DocTest.Driver as DocTest -{-# LINE 26 "src/LinearAlgebra.hs" #-}+{-# LINE 28 "src/LinearAlgebra.hs" #-} import     qualified Data.Array.Comfort.Storable as Array+import     qualified Data.Map as Map import     Data.Tuple.HT (mapSnd)  myRound     :: Double -> Integer@@ -16,10 +17,17 @@  test :: DocTest.T () test = do- DocTest.printPrefix "LinearAlgebra:81: "-{-# LINE 81 "src/LinearAlgebra.hs" #-}+ DocTest.printPrefix "LinearAlgebra:84: "+{-# LINE 84 "src/LinearAlgebra.hs" #-}  DocTest.example(-{-# LINE 81 "src/LinearAlgebra.hs" #-}-    mapSnd (map myRound . Array.toList) $ solve 3 [((0,0),8), ((2,0),1), ((2,2),3)]+{-# LINE 84 "src/LinearAlgebra.hs" #-}+    mapSnd (map myRound . Array.toList) $ solve 3 $ Map.fromList [((0,0),8), ((2,0),1), ((2,2),3)]   )   [ExpectedLine [LineChunk "(3,[8,3,5,1,2,3])"]]+ DocTest.printPrefix "LinearAlgebra:107: "+{-# LINE 107 "src/LinearAlgebra.hs" #-}+ DocTest.example(+{-# LINE 107 "src/LinearAlgebra.hs" #-}+    map (length . solvables) [0..5]+  )+  [ExpectedLine [LineChunk "[1,1,3,17,149,1824]"]]
test/Test/UniqueLogic.hs view
@@ -10,35 +10,43 @@ {-# LINE 24 "src/UniqueLogic.hs" #-} import     qualified Data.Array.Comfort.Boxed as BoxedArray import     qualified Data.Array.Comfort.Shape as Shape+import     qualified Data.Map as Map import     Common  test :: DocTest.T () test = do- DocTest.printPrefix "UniqueLogic:58: "-{-# LINE 58 "src/UniqueLogic.hs" #-}+ DocTest.printPrefix "UniqueLogic:56: "+{-# LINE 56 "src/UniqueLogic.hs" #-}  DocTest.example(-{-# LINE 58 "src/UniqueLogic.hs" #-}-    solve 3 [((0,0),1), ((1,0),1), ((2,0),1::Integer)]+{-# LINE 56 "src/UniqueLogic.hs" #-}+    solve 3 $ Map.fromList [((0,0),1), ((1,0),1), ((2,0),1::Integer)]   )   [ExpectedLine [LineChunk "BoxedArray",WildCardChunk,LineChunk "Triangular",WildCardChunk,LineChunk " 3",WildCardChunk,LineChunk " [Just 1,Just 1,Just 0,Just 1,Just 0,Just 0]"]]- DocTest.printPrefix "UniqueLogic:61: "-{-# LINE 61 "src/UniqueLogic.hs" #-}+ DocTest.printPrefix "UniqueLogic:59: "+{-# LINE 59 "src/UniqueLogic.hs" #-}  DocTest.example(-{-# LINE 61 "src/UniqueLogic.hs" #-}-    solve 3 [((0,0),1), ((2,0),1), ((2,2),1::Integer)]+{-# LINE 59 "src/UniqueLogic.hs" #-}+    solve 3 $ Map.fromList [((0,0),1), ((2,0),1), ((2,2),1::Integer)]   )   [ExpectedLine [LineChunk "BoxedArray",WildCardChunk,LineChunk "Triangular",WildCardChunk,LineChunk " 3",WildCardChunk,LineChunk " [Just 1,Nothing,Nothing,Just 1,Nothing,Just 1]"]]- DocTest.printPrefix "UniqueLogic:83: "-{-# LINE 83 "src/UniqueLogic.hs" #-}+ DocTest.printPrefix "UniqueLogic:79: "+{-# LINE 79 "src/UniqueLogic.hs" #-}  DocTest.example(-{-# LINE 83 "src/UniqueLogic.hs" #-}-    solveMixed (BoxedArray.fromList (Shape.lowerTriangular $ Shape.ZeroBased 1) [Mul]) [((0,0),0), ((1,1),0::Rational)]+{-# LINE 79 "src/UniqueLogic.hs" #-}+    solveMixed (BoxedArray.fromList (Shape.lowerTriangular $ ShapeOp 2) [Mul]) (Map.fromList [((0,0),0), ((1,1),0::Rational)])   )   [ExpectedLine [LineChunk "BoxedArray",WildCardChunk,LineChunk "Triangular",WildCardChunk,LineChunk " 2",WildCardChunk,LineChunk " [Just (0 % 1),Nothing,Just (0 % 1)]"]]- DocTest.printPrefix "UniqueLogic:85: "-{-# LINE 85 "src/UniqueLogic.hs" #-}+ DocTest.printPrefix "UniqueLogic:81: "+{-# LINE 81 "src/UniqueLogic.hs" #-}  DocTest.example(-{-# LINE 85 "src/UniqueLogic.hs" #-}-    solveMixed (BoxedArray.fromList (Shape.lowerTriangular $ Shape.ZeroBased 1) [Mul]) [((0,0),0), ((1,1),5::Rational)]+{-# LINE 81 "src/UniqueLogic.hs" #-}+    solveMixed (BoxedArray.fromList (Shape.lowerTriangular $ ShapeOp 2) [Mul]) (Map.fromList [((0,0),0), ((1,1),5::Rational)])   )   [ExpectedLine [LineChunk "BoxedArray",WildCardChunk,LineChunk "Triangular",WildCardChunk,LineChunk " 2",WildCardChunk,LineChunk " [Just (0 % 1),Just (0 % 1),Just (5 % 1)]"]]+ DocTest.printPrefix "UniqueLogic:108: "+{-# LINE 108 "src/UniqueLogic.hs" #-}+ DocTest.example(+{-# LINE 108 "src/UniqueLogic.hs" #-}+    map (length . solvables) [0..5]+  )+  [ExpectedLine [LineChunk "[1,1,3,16,122,1188]"]]