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.




use List::Util 'sum';
 
my @condition = ( 
                 sub { 0 }, # dummy sub for index 0
                 sub { 13==@_ },
                 sub { 3==sum @_[7..12] },
                 sub { 2==sum @_[2,4,6,8,10,12] },
                 sub { $_[5] ? ($_[6] and $_[7]) : 1 },
                 sub { !$_[2] and !$_[3] and !$_[4] },
                 sub { 4==sum @_[1,3,5,7,9,11] },
                 sub { $_[2]==1-$_[3] },
                 sub { $_[7] ? ($_[5] and $_[6]) : 1 },
                 sub { 3==sum @_[1..6] },
                 sub { 2==sum @_[11..12] },
                 sub { 1==sum @_[7,8,9] },
                 sub { 4==sum @_[1..11] },
                );
 
sub miss {
  return grep { $condition[$_]->(@_) != $_[$_] } 1..12;
}
 
for (0..2**12-1) {
  my @truth = split //, sprintf "0%012b", $_;
  my @no = miss @truth;
  print "Solution: true statements are ", join( " ", grep { $truth[$_] } 1..12), "\n" if 0 == @no;
  print "1 miss (",$no[0],"): true statements are ", join( " ", grep { $truth[$_] } 1..12), "\n" if 1 == @no;
}
 