Task: Twelve statements



C#: using System;
using System.Collections.Generic;
using System.Linq;
    
public static class TwelveStatements
{
    public static void Main() {
        Func<Statements, bool>[] checks = {
            st => st[1],
            st => st[2] == (7.To(12).Count(i => st[i]) == 3),
            st => st[3] == (2.To(12, by: 2).Count(i => st[i]) == 2),
            st => st[4] == st[5].Implies(st[6] && st[7]),
            st => st[5] == (!st[2] && !st[3] && !st[4]),
            st => st[6] == (1.To(12, by: 2).Count(i => st[i]) == 4),
            st => st[7] == (st[2] != st[3]),
            st => st[8] == st[7].Implies(st[5] && st[6]),
            st => st[9] == (1.To(6).Count(i => st[i]) == 3),
            st => st[10] == (st[11] && st[12]),
            st => st[11] == (7.To(9).Count(i => st[i]) == 1),
            st => st[12] == (1.To(11).Count(i => st[i]) == 4)
        };
        
        for (Statements statements = new Statements(0); statements.Value < 4096; statements++) {
            int count = 0;
            int falseIndex = 0;
            for (int i = 0; i < checks.Length; i++) {
                if (checks[i](statements)) count++;
                else falseIndex = i;
            }
            if (count == 0) Console.WriteLine($"{"All wrong:", -13}{statements}");
            else if (count == 11) Console.WriteLine($"{$"Wrong at {falseIndex + 1}:", -13}{statements}");
            else if (count == 12) Console.WriteLine($"{"All correct:", -13}{statements}");
        }
    }
    
    struct Statements
    {    
        public Statements(int value) : this() { Value = value; }
        
        public int Value { get; }
                
        public bool this[int index] => (Value & (1 << index - 1)) != 0;
        
        public static Statements operator ++(Statements statements) => new Statements(statements.Value + 1);
        
        public override string ToString() {
            Statements copy = this; 
            return string.Join(" ", from i in 1.To(12) select copy[i] ? "T" : "F");
        }
        
    }
    
    
    static bool Implies(this bool x, bool y) => !x || y;
    
    static IEnumerable<int> To(this int start, int end, int by = 1) {
        while (start <= end) {
            yield return start;
            start += by;
        }
    }

}









Ada: with Ada.Text_IO, Logic; 

procedure Twelve_Statements is
   
   package L is new Logic(Number_Of_Statements => 12); use L;
   
   
   function P01(T: Table) return Boolean is (T'Length = 12);              
   function P02(T: Table) return Boolean is (Sum(T(7 .. 12)) = 3);        
   function P03(T: Table) return Boolean is (Sum(Half(T, Even)) = 2);     
   function P04(T: Table) return Boolean is (if T(5) then T(6) and T(7)); 
   function P05(T: Table) return Boolean is 
      ( (not T(2)) and (not T(3)) and (not T(4)) );                       
   function P06(T: Table) return Boolean is (Sum(Half(T, Odd)) = 4);      
   function P07(T: Table) return Boolean is (T(2) xor T(3));              
   function P08(T: Table) return Boolean is (if T(7) then T(5) and T(6)); 
   function P09(T: Table) return Boolean is (Sum(T(1 .. 6)) = 3);         
   function P10(T: Table) return Boolean is (T(11) and T(12));            
   function P11(T: Table) return Boolean is (Sum(T(7..9)) = 1);           
   function P12(T: Table) return Boolean is (Sum(T(1 .. 11)) = 4);        
   
   
   Statement_List: constant Statements :=
     (P01'Access, P02'Access, P03'Access, P04'Access, P05'Access, P06'Access, 
      P07'Access, P08'Access, P09'Access, P10'Access, P11'Access, P12'Access);
   
   
   procedure Try(T: Table; Fail: Natural; Idx: Indices'Base := Indices'First) is
      
      procedure Print_Table(T: Table) is
	 use Ada.Text_IO;
      begin
	 Put("    ");
	 if Fail > 0 then
	    Put("(wrong at");
	    for J in T'Range loop
	       if Statement_List(J)(T) /= T(J) then
		  Put(Integer'Image(J) & (if J < 10 then ")  " else ") "));
	       end if;
	    end loop;
	 end if;
	 if T = (1..12 => False) then
	    Put_Line("All false!");
	 else
	    Put("True are");
	    for J in T'Range loop
	       if T(J) then 
		  Put(Integer'Image(J));
	       end if;
	    end loop;
	    New_Line;
	 end if;
      end Print_Table;
      
      Wrong_Entries: Natural := 0; 
	  
   begin
      if Idx <= T'Last then 
	 Try(T(T'First .. Idx-1) & False & T(Idx+1 .. T'Last), Fail, Idx+1);
	 Try(T(T'First .. Idx-1) & True  & T(Idx+1 .. T'Last), Fail, Idx+1);
      else 
	 for J in T'Range loop 	 
	    if Statement_List(J)(T) /= T(J) then 
	       Wrong_Entries := Wrong_Entries + 1;
	    end if;
	 end loop;
	 if Wrong_Entries = Fail then 
	    Print_Table(T);
	 end if;
      end if;
   end Try;
			 
begin
   Ada.Text_IO.Put_Line("Exact hits:");
   Try(T => (1..12 => False), Fail => 0);
   Ada.Text_IO.New_Line;
   Ada.Text_IO.Put_Line("Near Misses:");
   Try(T => (1..12 => False), Fail => 1);
end Twelve_Statements;