This puzzle is borrowed from   math-frolic.blogspot.



Given the following twelve statements, which of them are true?

 1.  This is a numbered list of twelve statements.
 2.  Exactly 3 of the last 6 statements are true.
 3.  Exactly 2 of the even-numbered statements are true.
 4.  If statement 5 is true, then statements 6 and 7 are both true.
 5.  The 3 preceding statements are all false.
 6.  Exactly 4 of the odd-numbered statements are true.
 7.  Either statement 2 or 3 is true, but not both.
 8.  If statement 7 is true, then 5 and 6 are both true.
 9.  Exactly 3 of the first 6 statements are true.
10.  The next two statements are both true.
11.  Exactly 1 of statements 7, 8 and 9 are true.
12.  Exactly 4 of the preceding statements are true.



Task

When you get tired of trying to figure it out in your head,
write a program to solve it, and print the correct answer or answers.



Extra credit

Print out a table of near misses, that is, solutions that are contradicted by only a single statement.




import Data.List (findIndices)
 
tf :: [[Int] -> Bool] -> [[Int]]
tf = traverse (const [1, 0])
 
wrongness :: [Int] -> [[Int] -> Bool] -> [Int]
wrongness ns ps = findIndices id (zipWith (/=) ns (map (fromEnum . ($ ns)) ps))
 
statements :: [[Int] -> Bool]
statements =
  [ (== 12) . length
  , 3 ⊂ [length statements - 6 ..]
  , 2 ⊂ [1,3 ..]
  , 4 → [4 .. 6]
  , 0 ⊂ [1 .. 3]
  , 4 ⊂ [0,2 ..]
  , 1 ⊂ [1, 2]
  , 6 → [4 .. 6]
  , 3 ⊂ [0 .. 5]
  , 2 ⊂ [10, 11]
  , 1 ⊂ [6, 7, 8]
  , 4 ⊂ [0 .. 10]
  ]
  where
    (⊂), (→)  :: Int -> [Int] -> [Int] -> Bool
    (s ⊂ x) b = s == (sum . map (b !!) . takeWhile (< length b)) x
    (a → x) b = (b !! a == 0) || all ((== 1) . (b !!)) x
 
testall :: [[Int] -> Bool] -> Int -> [([Int], [Int])]
testall s n =
  [ (b, w)
  | b <- tf s
  , w <- [wrongness b s]
  , length w == n ]
 
main :: IO ()
main =
  let t = testall statements
  in do putStrLn "Answer"
        mapM_ print $ t 0
        putStrLn "Near misses"
        mapM_ print $ t 1