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 UIKit
import Foundation

internal enum PaddingOption {
    case Left
    case Right
}
 
extension Array {
    func pad(element: Element, times: Int, toThe: PaddingOption) -> Array<Element> {
        
        let padded = [Element](repeating: element, count: times)
        switch(toThe) {
        case .Left:
            return padded + self
        case .Right:
            return self + padded
        }
    }
 
    func take(n: Int) -> Array<Element> {
        if n <= 0 {
            return []
        } 
        return Array(self[0..<Swift.min(n, self.count)])
    }
 
    func drop(n: Int) -> Array<Element> {
        if n <= 0 {
            return self
        } else if n >= self.count {
            return []
        }
        return Array(self[n..<self.count])
    }
 
    func stride(n: Int) -> Array<Element> {
        var result:[Element] = []
        for i in Swift.stride(from: 0, to: self.count, by: n) {
            result.append(self[i])
        }
        return result
    }
 
    func zipWithIndex() -> Array<(Element, Int)> {
        let result = [(Element, Int)](zip(self, self.indices))
        return result
    }
}
 
extension Int {
    func binaryRepresentationOfLength(length: Int) -> [Int] {
        var binaryRepresentation:[Int] = []
        var value = self
        while (value != 0) {
            binaryRepresentation.append(value & 1)
            value /= 2
        }
        let result = binaryRepresentation.pad(element: 0, times: length-binaryRepresentation.count, toThe: .Right)     
        return result
    }
}
 
let problem = [
    "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."]
 
let statements:[(([Bool]) -> Bool)] = [
    { s in s.count == 12 },
    { s in s.drop(n: 6).filter({ $0 }).count == 3 },
    { s in s.drop(n: 1).stride(n: 2).filter({ $0 }).count == 2 },
    { s in s[4] ? (s[5] && s[6]) : true },
    { s in s.drop(n: 1).take(n: 3).filter({ $0 }).count == 0 },
    { s in s.stride(n: 2).filter({ $0 }).count == 4 },
    { s in [s[1], s[2]].filter({ $0 }).count == 1 },
    { s in s[6] ? (s[4] && s[5]) : true },
    { s in s.take(n: 6).filter({ $0 }).count == 3 },
    { s in [s[10], s[11]].filter({ $0 }).count == 2 },
    { s in [s[6], s[7], s[8]].filter({ $0 }).count == 1 },
    { s in s.take(n: 11).filter({ $0 }).count == 4 }
]
 
for variant in 0..<(1<<statements.count) {
    let attempt = variant.binaryRepresentationOfLength(length: statements.count).map { $0 == 1 }
 
    if statements.map({ $0(attempt) }) == attempt {
        let trueAre = attempt.zipWithIndex().filter { $0.0 }.map { $0.1 + 1 }
        print("Solution found! True are: \(trueAre)")
    }
}

