Twelve statements: Difference between revisions
Content deleted Content added
Move Java so it is inserted in alphabetical order. |
→{{header|Uiua}}: Improved algorithm |
||
(144 intermediate revisions by 58 users not shown) | |||
Line 1:
{{task|Puzzles}}
[[Category:CHR]]
{{omit from|Brlcad}}
{{omit from|GUISS}}
{{omit from|Openscad}}
{{omit from|TPP}}
This puzzle is borrowed from [http://math-frolic.blogspot.co.uk/2012/08/mind-wrenching.html
Given the following twelve statements, which of them are true?
<pre>
5. The 3 preceding statements are all false.
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.
</pre>
;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.
<br><br>
=={{header|11l}}==
{{trans|Nim}}
{{trans|Python}}
<syntaxhighlight lang="11l">[([Int] -> Bool)] predicates
predicates [+]= st -> st.len == 12
predicates [+]= st -> sum(st[(len)-6 ..]) == 3
predicates [+]= st -> sum(st[(1..).step(2)]) == 2
predicates [+]= st -> I st[4] {(st[5] [&] st[6])} E 1
predicates [+]= st -> sum(st[1.<4]) == 0
predicates [+]= st -> sum(st[(0..).step(2)]) == 4
predicates [+]= st -> sum(st[1.<3]) == 1
predicates [+]= st -> I st[6] {(st[4] [&] st[5])} E 1
predicates [+]= st -> sum(st[0.<6]) == 3
predicates [+]= st -> (st[10] [&] st[11])
predicates [+]= st -> sum(st[6.<9]) == 1
predicates [+]= st -> sum(st[0.<11]) == 4
F to_str(b)
R (0.<12).filter(i -> @b[i]).map(i -> i + 1).join(‘ ’)
print(‘Exact hits:’)
L(n) 0 .< (1 << 12)
V bools = [0] * 12
L(i) 12
I n [&] (1 << (11 - i)) != 0
bools[i] = 1
L(predicate) predicates
I Int(predicate(bools)) != bools[L.index]
L.break
L.was_no_break
print(‘ ’to_str(bools))
print("\nNear misses:")
L(n) 0 .< (1 << 12)
V bools = [0] * 12
L(i) 12
I n [&] (1 << (11 - i)) != 0
bools[i] = 1
V count = 0
L(predicate) predicates
I Int(predicate(bools)) == bools[L.index]
count++
I count == 11
L(predicate) predicates
V i = L.index
I Int(predicate(bools)) != bools[i]
print(f:‘ (Fails at statement {i + 1:2}) {to_str(bools)}’)
L.break</syntaxhighlight>
{{out}}
<pre>
Exact hits:
1 3 4 6 7 11
Near misses:
(Fails at statement 1) 5 8 11
(Fails at statement 1) 5 8 10 11 12
(Fails at statement 1) 4 8 10 11 12
(Fails at statement 8) 1 5
(Fails at statement 11) 1 5 8
(Fails at statement 12) 1 5 8 11
(Fails at statement 12) 1 5 8 10 11 12
(Fails at statement 8) 1 5 6 9 11
(Fails at statement 8) 1 4
(Fails at statement 12) 1 4 8 10 11 12
(Fails at statement 6) 1 4 6 8 9
(Fails at statement 7) 1 3 4 8 9
(Fails at statement 9) 1 3 4 6 7 9
(Fails at statement 12) 1 2 4 7 9 12
(Fails at statement 10) 1 2 4 7 9 10
(Fails at statement 8) 1 2 4 7 8 9
</pre>
=={{header|Ada}}==
{{works with|Ada 2012}}
Here is the main program, using a generic package Logic.
The expression function introduced by the new standard Ada 2012
are very handy for this task.
<
procedure Twelve_Statements is
Line 104 ⟶ 196:
Ada.Text_IO.Put_Line("Near Misses:");
Try(T => (1..12 => False), Fail => 1);
end Twelve_Statements;</
{{out}}
Line 131 ⟶ 223:
Here is the definition the package Logic:
<
Number_Of_Statements: Positive;
package Logic is
Line 146 ⟶ 238:
function Half(T: Table; Which: Even_Odd) return Table;
end Logic;</
And here is the implementation of the "convenience functions" in Logic:
<
function Sum(T: Table) return Natural is
Line 176 ⟶ 268:
end Half;
end Logic;</
=={{header|ALGOL W}}==
<syntaxhighlight lang="algolw">begin
% we have 12 statements to determine the truth/falsehood of (see task) %
logical array stmt, expected( 1 :: 12 );
% logical (boolean) to integer utility procedure %
integer procedure toInteger ( logical value v ) ; if v then 1 else 0;
% procedure to determine whether the statements are true or not %
procedure findExpectedValues ;
begin
expected( 1 ) := true;
expected( 2 ) := 3 = ( toInteger( stmt( 7 ) ) + toInteger( stmt( 8 ) )
+ toInteger( stmt( 9 ) ) + toInteger( stmt( 10 ) )
+ toInteger( stmt( 11 ) ) + toInteger( stmt( 12 ) )
);
expected( 3 ) := 2 = ( toInteger( stmt( 2 ) ) + toInteger( stmt( 4 ) )
+ toInteger( stmt( 6 ) ) + toInteger( stmt( 8 ) )
+ toInteger( stmt( 10 ) ) + toInteger( stmt( 12 ) )
);
expected( 4 ) := ( not stmt( 5 ) ) or ( stmt( 6 ) and stmt( 7 ) );
expected( 5 ) := not ( stmt( 2 ) or stmt( 3 ) or stmt( 4 ) );
expected( 6 ) := 4 = ( toInteger( stmt( 1 ) ) + toInteger( stmt( 3 ) )
+ toInteger( stmt( 5 ) ) + toInteger( stmt( 7 ) )
+ toInteger( stmt( 9 ) ) + toInteger( stmt( 11 ) )
);
expected( 7 ) := stmt( 2 ) not = stmt( 3 );
expected( 8 ) := ( not stmt( 7 ) ) or ( stmt( 5 ) and stmt( 6 ) );
expected( 9 ) := 3 = ( toInteger( stmt( 1 ) ) + toInteger( stmt( 2 ) )
+ toInteger( stmt( 3 ) ) + toInteger( stmt( 4 ) )
+ toInteger( stmt( 5 ) ) + toInteger( stmt( 6 ) )
);
expected( 10 ) := stmt( 11 ) and stmt( 12 );
expected( 11 ) := 1 = ( toInteger( stmt( 7 ) )
+ toInteger( stmt( 8 ) )
+ toInteger( stmt( 9 ) )
);
expected( 12 ) := 4 = ( toInteger( stmt( 1 ) ) + toInteger( stmt( 2 ) )
+ toInteger( stmt( 3 ) ) + toInteger( stmt( 4 ) )
+ toInteger( stmt( 5 ) ) + toInteger( stmt( 6 ) )
+ toInteger( stmt( 7 ) ) + toInteger( stmt( 8 ) )
+ toInteger( stmt( 9 ) ) + toInteger( stmt( 10 ) )
+ toInteger( stmt( 11 ) )
);
end expected ;
% clearly, statement 1 is true, however to enumerate the near %
% solutions, we need to consider "solutions" where statement 1 is false %
% we iterate through the possibilities for the statements, %
% looking for a non-contradictory set of values %
% we print the solutions with allowedContradictions contradictions %
procedure printSolutions ( integer value allowedContradictions
; string(60) value heading
) ;
begin
logical array wrong( 1 :: 12 );
write( heading );
write( " 1 2 3 4 5 6 7 8 9 10 11 12" );
write( " ====================================" );
% there are 12 statements, so we have 2^12 possible combinations %
for solution := 1 until 4096 do begin
integer n, incorrect;
% convert the number to the set of true/false values %
n := solution;
for dPos := 1 until 12 do begin
stmt( dPos ) := odd( n );
n := n div 2;
end for_dPos ;
% get the expected values of the statements, based on the %
% suggested values %
findExpectedValues;
% count the contradictions, if we have the required number, %
% print the solution %
incorrect := 0;
for dPos := 1 until 12 do begin
wrong( dPos ) := expected( dPos ) not = stmt( dPos );
incorrect := incorrect + toInteger( wrong( dPos ) );
end for_dPos ;
if incorrect = allowedContradictions then begin
% have a solution %
write( " " );
for s := 1 until 12 do writeon( s_w := 0
, " "
, if stmt( s ) then "T" else "-"
, if wrong( s ) then "*" else " "
);
end ;
end for_solution ;
end printSolutions ;
% find complete solutions %
printSolutions( 0, "Solutions" );
% find near solutions %
printSolutions( 1, "Near solutions (incorrect values marked ""*"")" );
end.</syntaxhighlight>
{{out}}
<pre>Solutions
1 2 3 4 5 6 7 8 9 10 11 12
====================================
T - T T - T T - - - T -
Near solutions (incorrect values marked "*")
1 2 3 4 5 6 7 8 9 10 11 12
====================================
T - - T - - - -* - - - -
T - - - T - - -* - - - -
T - - - T - - T - - -* -
T - T T - T T - T* - - -
T - T T - - -* T T - - -
T - - T - T* - T T - - -
T T - T - - T T* T - - -
T T - T - - T - T T* - -
-* - - - T - - T - - T -
T - - - T - - T - - T -*
T - - - T T - -* T - T -
T T - T - - T - T - - T*
-* - - T - - - T - T T T
T - - T - - - T - T T T*
-* - - - T - - T - T T T
T - - - T - - T - T T T*
</pre>
=={{header|AppleScript}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="applescript">on twelveStatements()
set statements to " 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."
script o
property posits : {}
property upshots : missing value
on countTrues(indexList)
set sum to 0
repeat with i in indexList
if (my posits's item i) then set sum to sum + 1
end repeat
return sum
end countTrues
end script
-- While setting up, test statement 1, whose truth isn't about the others' truths.
set statements to statements's paragraphs
set nStatements to (count statements)
set statement1Truth to (nStatements = 12)
repeat with stmt from 1 to nStatements
set end of o's o's posits to false
tell (statements's item stmt's words) to set statement1Truth to ¬
((statement1Truth) and ((count) > 1) and (beginning = stmt as text))
end repeat
set output to {}
set firstIteration to true
repeat (2 ^ nStatements) times
-- Postulate answer:
if (firstIteration) then
set firstIteration to false
else -- "Increment" the 'posits' boolean array binarily.
repeat with stmt from 1 to nStatements
set o's posits's item stmt to (not (o's posits's item stmt))
if (result) then exit repeat -- No carry.
end repeat
end if
-- Test consistency:
tell o's posits to set o's upshots to {statement1Truth, ¬
(o's countTrues({7, 8, 9, 10, 11, 12}) = 3), ¬
(o's countTrues({2, 4, 6, 8, 10, 12}) = 2), ¬
((not (item 5)) or ((item 6) and (item 7))), ¬
(not ((item 2) or (item 3) or (item 4))), ¬
(o's countTrues({1, 3, 5, 7, 9, 11}) = 4), ¬
((item 2) ≠ (item 3)), ¬
((not (item 7)) or ((item 5) and (item 6))), ¬
(o's countTrues({1, 2, 3, 4, 5, 6}) = 3), ¬
((item 11) and (item 12)), ¬
(o's countTrues({7, 8, 9}) = 1), ¬
(o's countTrues({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}) = 4)}
set nMatches to 0
repeat with stmt from 1 to nStatements
if ((o's posits's item stmt) = (o's upshots's item stmt)) then set nMatches to nMatches + 1
end repeat
if (nMatches > nStatements - 2) then
set statementsPositedTrue to {}
repeat with stmt from 1 to nStatements
set thisPosit to o's posits's item stmt
if (thisPosit) then set end of statementsPositedTrue to stmt
if ((thisPosit) ≠ (o's upshots's item stmt)) then set failure to stmt
end repeat
set statementsPositedTrue's last item to "and " & statementsPositedTrue's end
if ((count statementsPositedTrue) > 2) then
set statementsPositedTrue to join(statementsPositedTrue, ", ")
else
set statementsPositedTrue to join(statementsPositedTrue, space)
end if
if (nMatches = nStatements) then
set output's end to "SOLUTION: statements " & statementsPositedTrue & " are true."
else
set output's end to "Near miss when statements " & statementsPositedTrue & ¬
" are posited true: posit for statement " & failure & " fails."
end if
end if
end repeat
return join(output, linefeed)
end twelveStatements
on join(lst, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delim
set txt to lst as text
set AppleScript's text item delimiters to astid
return txt
end join
twelveStatements()</syntaxhighlight>
{{output}}
<syntaxhighlight lang="applescript">"Near miss when statements 1 and 4 are posited true: posit for statement 8 fails.
Near miss when statements 1 and 5 are posited true: posit for statement 8 fails.
Near miss when statements 1, 5, and 8 are posited true: posit for statement 11 fails.
Near miss when statements 1, 3, 4, 6, 7, and 9 are posited true: posit for statement 9 fails.
Near miss when statements 1, 3, 4, 8, and 9 are posited true: posit for statement 7 fails.
Near miss when statements 1, 4, 6, 8, and 9 are posited true: posit for statement 6 fails.
Near miss when statements 1, 2, 4, 7, 8, and 9 are posited true: posit for statement 8 fails.
Near miss when statements 1, 2, 4, 7, 9, and 10 are posited true: posit for statement 10 fails.
SOLUTION: statements 1, 3, 4, 6, 7, and 11 are true.
Near miss when statements 5, 8, and 11 are posited true: posit for statement 1 fails.
Near miss when statements 1, 5, 8, and 11 are posited true: posit for statement 12 fails.
Near miss when statements 1, 5, 6, 9, and 11 are posited true: posit for statement 8 fails.
Near miss when statements 1, 2, 4, 7, 9, and 12 are posited true: posit for statement 12 fails.
Near miss when statements 4, 8, 10, 11, and 12 are posited true: posit for statement 1 fails.
Near miss when statements 1, 4, 8, 10, 11, and 12 are posited true: posit for statement 12 fails.
Near miss when statements 5, 8, 10, 11, and 12 are posited true: posit for statement 1 fails.
Near miss when statements 1, 5, 8, 10, 11, and 12 are posited true: posit for statement 12 fails."</syntaxhighlight>
=={{header|AutoHotkey}}==
Just like the Python version, this code uses bruteforce (4096 iterations) to set 12 flags and test all statements on each iteration.
If the proposed flags match the results after validating each statement, we have the solution.
The code shows all cases where we have at least S-1 matches (where S = 12 statements).
<syntaxhighlight lang="autohotkey">; Note: the original puzzle provides 12 statements and starts with
; "Given the following twelve statements...", so the first statement
; should ignore the F1 flag and always be true (see "( N == 1 )").
S := 12 ; number of statements
Output := ""
Loop, % 2**S {
;;If !Mod(A_Index,100) ;; optional 'if' to show the loop progress
;; ToolTip, Index: %A_Index%
SetFlags(A_Index-1), Current := "", Count := 0
Loop, %S%
R := TestStatement(A_Index), Current .= " " R, Count += (R == F%A_Index%)
If ( Count >= S-1 )
Output .= Count " ->" Current "`n"
If ( Count = S )
Solution := "`nSolution = " Current
}
ToolTip
MsgBox, % Output . Solution
Return
;-------------------------------------------------------------------------------------
SetFlags(D) {
Local I
Loop, %S%
I := S-A_Index+1 , F%I% := (D >> (S-A_Index)) & 1
}
;-------------------------------------------------------------------------------------
TestStatement(N) {
Local I, C := 0
If ( N == 1 ) ; This is a numbered list of twelve statements.
Return ( S == 12 ) ; should always be true
If ( N == 2 ) { ; Exactly 3 of the last 6 statements are true.
Loop, 6
I := S-A_Index+1 , C += F%I%
Return ( C == 3 )
}
If ( N == 3 ) { ; Exactly 2 of the even-numbered statements are true.
Loop, %S%
C += ( !Mod(A_Index,2) & F%A_Index% )
Return ( C == 2 )
}
If ( N == 4 ) ; If statement 5 is true, then statements 6 and 7 are both true.
Return ( F5 ? F6 & F7 : 1 )
If ( N == 5 ) { ; The 3 preceding statements are all false.
Loop, 3
I := N-A_Index , C += F%I%
Return ( C == 0 )
}
If ( N == 6 ) { ; Exactly 4 of the odd-numbered statements are true.
Loop, %S%
C += ( !!Mod(A_Index,2) & F%A_Index% )
Return ( C == 4 )
}
If ( N == 7 ) ; Either statement 2 or 3 is true, but not both.
Return ( F2 ^ F3 )
If ( N == 8 ) ; If statement 7 is true, then 5 and 6 are both true.
Return ( F7 ? F5 & F6 : 1 )
If ( N == 9 ) { ; Exactly 3 of the first 6 statements are true.
Loop, 6
C += F%A_Index%
Return ( C == 3 )
}
If ( N == 10 ) ; The next two statements are both true.
Return ( F11 & F12 )
If ( N == 11 ) ; Exactly 1 of statements 7, 8 and 9 are true
Return ( F7+F8+F9 == 1 )
If ( N == 12 ) { ; Exactly 4 of the preceding statements are true
Loop, % N-1
C += F%A_Index%
Return ( C == 4 )
}
}</syntaxhighlight>
{{out}}
<pre>11 -> 1 0 0 1 0 0 0 1 0 0 0 0
11 -> 1 0 0 0 1 0 0 1 0 0 0 0
11 -> 1 0 0 0 1 0 0 1 0 0 1 0
11 -> 1 0 1 1 0 1 1 0 0 0 0 0
11 -> 1 0 1 1 0 0 1 1 1 0 0 0
11 -> 1 0 0 1 0 0 0 1 1 0 0 0
11 -> 1 1 0 1 0 0 1 0 1 0 0 0
11 -> 1 1 0 1 0 0 1 0 1 0 0 0
12 -> 1 0 1 1 0 1 1 0 0 0 1 0
11 -> 1 0 0 0 1 0 0 1 0 0 1 0
11 -> 1 0 0 0 1 0 0 1 0 0 1 1
11 -> 1 0 0 0 1 1 0 1 1 0 1 0
11 -> 1 1 0 1 0 0 1 0 1 0 0 0
11 -> 1 0 0 1 0 0 0 1 0 1 1 1
11 -> 1 0 0 1 0 0 0 1 0 1 1 0
11 -> 1 0 0 0 1 0 0 1 0 1 1 1
11 -> 1 0 0 0 1 0 0 1 0 1 1 0
Solution = 1 0 1 1 0 1 1 0 0 0 1 0</pre>
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
DIM Pass%(nStatements%), T%(nStatements%)
Line 222 ⟶ 663:
NEXT try%
END</
{{out}}
<pre>
Near miss with statements 1 4 true (failed 8).
Line 243 ⟶ 684:
Near miss with statements 1 5 8 10 11 12 true (failed 12).
</pre>
=={{header|Bracmat}}==
<syntaxhighlight lang="bracmat">(
( number
= n done ntest oldFT
. !arg:(?done.(=?ntest).?oldFT)
& 0:?n
& ( !done
: ?
( !ntest
. !oldFT&1+!n:?n&~
)
?
| !n
)
)
& ( STATEMENTS
= ( (1."This is a numbered list of twelve statements.")
. 1
. (
= n nr done toDo
. !arg:(?done.?toDo)
& 0:?n
& whl
' ( !done:(?nr.?) ?done
& 1+!n:!nr:?n
)
& whl
' ( !toDo:((?nr.?).?) ?toDo
& 1+!n:!nr:?n
)
& (!n:12&true|false)
)
)
( (2."Exactly 3 of the last 6 statements are true.")
. end
. (
= done toDo lastSix
. !arg:(?done.?toDo)
& !done:? [-7 ?lastSix
& ( number$(!lastSix.(=?).true):3
& true
| false
)
)
)
( (3."Exactly 2 of the even-numbered statements are true.")
. end
. (
= done toDo ii
. !arg:(?done.?toDo)
& ( number
$ ( !done
. (=?ii&!ii*1/2:~/)
. true
)
: 2
& true
| false
)
)
)
( (4."If statement 5 is true, then statements 6 and 7 are both true.")
. 7
. (
= done toDo
. !arg:(?done.?toDo)
& ( !done
: ( ? (5.false) ?
| ? (6.true) ?
: ? (7.true) ?
)
& true
| false
)
)
)
( (5."The 3 preceding statements are all false.")
. 5
. (
= done toDo
. !arg:(?done.?toDo)
& ( !done
: ?
(?.false)
(?.false)
(?.false)
(?.?)
& true
| false
)
)
)
( (6."Exactly 4 of the odd-numbered statements are true.")
. end
. (
= done toDo i
. !arg:(?done.?toDo)
& ( number
$ ( !done
. (=?i&!i*1/2:/)
. true
)
: 4
& true
| false
)
)
)
( (7."Either statement 2 or 3 is true, but not both.")
. 7
. (
= done toDo
. !arg:(?done.?toDo)
& ( number
$ (!done.(=2|3).true)
: 1
& true
| false
)
)
)
( (8."If statement 7 is true, then 5 and 6 are both true.")
. 8
. (
= done toDo
. !arg:(?done.?toDo)
& ( !done
: ( ? (7.false) ?
| ? (5.true) ?
: ? (6.true) ?
)
& true
| false
)
)
)
( (9."Exactly 3 of the first 6 statements are true.")
. 9
. (
= done toDo firstSix
. !arg:(?done.?toDo)
& !done:?firstSix [6 ?
& ( number$(!firstSix.(=?).true):3
& true
| false
)
)
)
( (10."The next two statements are both true.")
. 12
. (
= done toDo
. !arg:(?done.?toDo)
& ( !done:? (?.true) (?.true)
& true
| false
)
)
)
( (11."Exactly 1 of statements 7, 8 and 9 are true.")
. 11
. (
= done toDo
. !arg:(?done.?toDo)
& ( number
$ ( !done
. (=7|8|9)
. true
)
: 1
& true
| false
)
)
)
( (12."Exactly 4 of the preceding statements are true.")
. 12
. (
= done toDo preceding
. !arg:(?done.?toDo)
& !done:?preceding (?.?)
& ( number$(!preceding.(=?).true):4
& true
| false
)
)
)
)
& ( TestTruth
= done toDo postponedTests testToBePostponed
, n when test FT oldFT A Z text
, postponedTest testNow
. !arg:(?done.?toDo.?postponedTests)
& ( !toDo:
& "We have come to the end of the list of tests.
Perform any tests that had to be postponed until now."
& whl
' ( !postponedTests
: (?.?oldFT.(=?postponedTest)) ?A
& postponedTest$(!done.):!oldFT
& !A:?postponedTests
)
& !postponedTests:
& out$("Solution:" !done)
& ~
| !toDo
: ((?n.?text).?when.(=?test)) ?toDo
& "'false' and 'true' are just two symbols, not 'boolean values'.
You can choose other symbols if you like.
The program first guesses the first symbol and assigns it to the variable FT.
After backtracking, the second symbol is guessed and assigned to FT.
This is done for each statement."
& false true
: ?
%@?FT
( ?
& 1+!guesses:?guesses
& (!n.!FT):?testNow
& "Do all tests that had to be postponed until now, unless one of those tests
fails. Remove the successful tests from the list of postponed tests."
& whl
' ( !postponedTests
: ?A
(!n.?oldFT.(=?postponedTest))
?Z
& postponedTest$(!done !testNow.!toDo)
: !oldFT
& !A !Z:?postponedTests
)
& "Check that all tests that had to be postponed until now are removed from
the list of postponed tests. Only then go on with looking at testing
the current statement. Backtrack if a test failed."
& !postponedTests:~(? (!n.?) ?)
& ( !when:>!n
& "The current statement cannot be tested right now. Postpone it to
the earliest coming statement where the current statement can be
tested.
(The earliest statement, denoted by 'when', is computed manually.)"
& (!when.!FT.'$test):?testToBePostponed
| "No need to postpone. Test the current statement now."
& :?testToBePostponed
& "If the test fails, backtrack. If it succeeds, go on to the next
statement."
& test$(!done !testNow.!toDo):!FT
)
& "So far so good. Test the next statements. (recursively)"
& TestTruth
$ ( !done !testNow
. !toDo
. !testToBePostponed !postponedTests
)
)
)
)
& 0:?guesses
& TestTruth$(.!STATEMENTS.)
| out
$ ( str
$ ( "That's it. I made "
!guesses
" true/false guesses in all. (A brute force method needs 2^12="
2^12
" guesses."
)
)
);</syntaxhighlight>
{{out}}
<pre> Solution:
(1.true)
(2.false)
(3.true)
(4.true)
(5.false)
(6.true)
(7.true)
(8.false)
(9.false)
(10.false)
(11.true)
(12.false)
That's it. I made 220 true/false guesses in all. (A brute force method needs 2^12=4096 guesses.</pre>
=={{header|C sharp}}==
{{works with|C sharp|6}}
<syntaxhighlight lang="csharp">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; //Cannot access 'this' in anonymous method...
return string.Join(" ", from i in 1.To(12) select copy[i] ? "T" : "F");
}
}
//Extension methods
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;
}
}
}</syntaxhighlight>
{{out}}
<pre>
Wrong at 8: T F F T F F F F F F F F
Wrong at 8: T F F F T F F F F F F F
Wrong at 11: T F F F T F F T F F F F
Wrong at 9: T F T T F T T F T F F F
Wrong at 7: T F T T F F F T T F F F
Wrong at 6: T F F T F T F T T F F F
Wrong at 8: T T F T F F T T T F F F
Wrong at 10: T T F T F F T F T T F F
All correct: T F T T F T T F F F T F
Wrong at 1: F F F F T F F T F F T F
Wrong at 12: T F F F T F F T F F T F
Wrong at 8: T F F F T T F F T F T F
Wrong at 12: T T F T F F T F T F F T
All wrong: F F T T T T F F T T F T
All wrong: F T T F T T T F T F T T
Wrong at 1: F F F T F F F T F T T T
Wrong at 12: T F F T F F F T F T T T
Wrong at 1: F F F F T F F T F T T T
Wrong at 12: T F F F T F F T F T T T</pre>
=={{header|C++}}==
{{works with|gcc 5.1.0 c++11}}
<syntaxhighlight lang="c++">#include <iostream>
#include <vector>
#include <string>
#include <cmath>
using namespace std;
// convert int (0 or 1) to string (F or T)
inline
string str(int n)
{
return n ? "T": "F";
}
int main(void)
{
int solution_list_number = 1;
vector<string> st;
st = {
" 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."
}; // Good solution is: 1 3 4 6 7 11 are true
int n = 12; // Number of statements.
int nTemp = (int)pow(2, n); // Number of solutions to check.
for (int counter = 0; counter < nTemp; counter++)
{
vector<int> s;
for (int k = 0; k < n; k++)
{
s.push_back((counter >> k) & 0x1);
}
vector<int> test(12);
int sum = 0;
// check each of the nTemp solutions for match.
// 1. This is a numbered list of twelve statements.
test[0] = s[0];
// 2. Exactly 3 of the last 6 statements are true.
sum = s[6]+ s[7]+s[8]+s[9]+s[10]+s[11];
test[1] = ((sum == 3) == s[1]);
// 3. Exactly 2 of the even-numbered statements are true.
sum = s[1]+s[3]+s[5]+s[7]+s[9]+s[11];
test[2] = ((sum == 2) == s[2]);
// 4. If statement 5 is true, then statements 6 and 7 are both true.
test[3] = ((s[4] ? (s[5] && s[6]) : true) == s[3]);
// 5. The 3 preceding statements are all false.
test[4] = (((s[1] + s[2] + s[3]) == 0) == s[4]);
// 6. Exactly 4 of the odd-numbered statements are true.
sum = s[0] + s[2] + s[4] + s[6] + s[8] + s[10];
test[5] = ((sum == 4) == s[5]);
// 7. Either statement 2 or 3 is true, but not both.
test[6] = (((s[1] + s[2]) == 1) == s[6]);
// 8. If statement 7 is true, then 5 and 6 are both true.
test[7] = ((s[6] ? (s[4] && s[5]) : true) == s[7]);
// 9. Exactly 3 of the first 6 statements are true.
sum = s[0]+s[1]+s[2]+s[3]+s[4]+s[5];
test[8] = ((sum == 3) == s[8]);
// 10. The next two statements are both true.
test[9] = ((s[10] && s[11]) == s[9]);
// 11. Exactly 1 of statements 7, 8 and 9 are true.
sum = s[6]+ s[7] + s[8];
test[10] = ((sum == 1) == s[10]);
// 12. Exactly 4 of the preceding statements are true.
sum = s[0]+s[1]+s[2]+s[3]+s[4]+s[5]+s[6]+s[7]+s[8]+s[9]+s[10];
test[11] = ((sum == 4) == s[11]);
// Check test results and print solution if 11 or 12 are true
int resultsTrue = 0;
for(unsigned int i = 0; i < test.size(); i++){
resultsTrue += test[i];
}
if(resultsTrue == 11 || resultsTrue == 12){
cout << solution_list_number++ << ". " ;
string output = "1:"+str(s[0])+" 2:"+str(s[1])+" 3:"+str(s[2])
+" 4:"+str(s[3])+" 5:"+str(s[4])+" 6:"+ str(s[5])
+" 7:"+str(s[6])+" 8:"+str(s[7])+" 9:"+str(s[8])
+" 10:"+str(s[9])+" 11:"+str(s[10])+" 12:"+ str(s[11]);
if (resultsTrue == 12) {
cout << "Full Match, good solution!" << endl;
cout << "\t" << output << endl;
}
else if(resultsTrue == 11){
int i;
for(i = 0; i < 12; i++){
if(test[i] == 0){
break;
}
}
cout << "Missed by one statement: " << st[i] << endl;
cout << "\t" << output << endl;
}
}
}
}
</syntaxhighlight>
{{out}}
<pre>
1. Missed by one statement: 8. If statement 7 is true, then 5 and 6 are both true.
1:T 2:F 3:F 4:T 5:F 6:F 7:F 8:F 9:F 10:F 11:F 12:F
2. Missed by one statement: 8. If statement 7 is true, then 5 and 6 are both true.
1:T 2:F 3:F 4:F 5:T 6:F 7:F 8:F 9:F 10:F 11:F 12:F
3. Missed by one statement: 11. Exactly 1 of statements 7, 8 and 9 are true.
1:T 2:F 3:F 4:F 5:T 6:F 7:F 8:T 9:F 10:F 11:F 12:F
4. Missed by one statement: 9. Exactly 3 of the first 6 statements are true.
1:T 2:F 3:T 4:T 5:F 6:T 7:T 8:F 9:T 10:F 11:F 12:F
5. Missed by one statement: 7. Either statement 2 or 3 is true, but not both.
1:T 2:F 3:T 4:T 5:F 6:F 7:F 8:T 9:T 10:F 11:F 12:F
6. Missed by one statement: 6. Exactly 4 of the odd-numbered statements are true.
1:T 2:F 3:F 4:T 5:F 6:T 7:F 8:T 9:T 10:F 11:F 12:F
7. Missed by one statement: 8. If statement 7 is true, then 5 and 6 are both true.
1:T 2:T 3:F 4:T 5:F 6:F 7:T 8:T 9:T 10:F 11:F 12:F
8. Missed by one statement: 10. The next two statements are both true.
1:T 2:T 3:F 4:T 5:F 6:F 7:T 8:F 9:T 10:T 11:F 12:F
9. Full Match, good solution!
1:T 2:F 3:T 4:T 5:F 6:T 7:T 8:F 9:F 10:F 11:T 12:F
10. Missed by one statement: 1. This is a numbered list of twelve statements.
1:F 2:F 3:F 4:F 5:T 6:F 7:F 8:T 9:F 10:F 11:T 12:F
11. Missed by one statement: 12. Exactly 4 of the preceding statements are true.
1:T 2:F 3:F 4:F 5:T 6:F 7:F 8:T 9:F 10:F 11:T 12:F
12. Missed by one statement: 8. If statement 7 is true, then 5 and 6 are both true.
1:T 2:F 3:F 4:F 5:T 6:T 7:F 8:F 9:T 10:F 11:T 12:F
13. Missed by one statement: 12. Exactly 4 of the preceding statements are true.
1:T 2:T 3:F 4:T 5:F 6:F 7:T 8:F 9:T 10:F 11:F 12:T
14. Missed by one statement: 1. This is a numbered list of twelve statements.
1:F 2:F 3:F 4:T 5:F 6:F 7:F 8:T 9:F 10:T 11:T 12:T
15. Missed by one statement: 12. Exactly 4 of the preceding statements are true.
1:T 2:F 3:F 4:T 5:F 6:F 7:F 8:T 9:F 10:T 11:T 12:T
16. Missed by one statement: 1. This is a numbered list of twelve statements.
1:F 2:F 3:F 4:F 5:T 6:F 7:F 8:T 9:F 10:T 11:T 12:T
17. Missed by one statement: 12. Exactly 4 of the preceding statements are true.
1:T 2:F 3:F 4:F 5:T 6:F 7:F 8:T 9:F 10:T 11:T 12:T
</pre>
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">(use '[clojure.math.combinatorics]
(defn xor? [& args]
(odd? (count (filter identity args))))
(defn twelve-statements []
(for [[a b c d e f g h i j k l] (selections [true false] 12)
:when (true? a)
:when (if (= 3 (count (filter true? [g h i j k l]))) (true? b) (false? b))
:when (if (= 2 (count (filter true? [b d f h j l]))) (true? c) (false? c))
:when (if (or (false? e) (every? true? [e f g])) (true? d) (false? d))
:when (if (every? false? [b c d]) (true? e) (false? e))
:when (if (= 4 (count (filter true? [a c e g i k]))) (true? f) (false? f))
:when (if (xor? (true? b) (true? c)) (true? g) (false? g))
:when (if (or (false? g) (every? true? [e f g])) (true? h) (false? h))
:when (if (= 3 (count (filter true? [a b c d e f]))) (true? i) (false? i))
:when (if (every? true? [k l]) (true? j) (false? j))
:when (if (= 1 (count (filter true? [g h i]))) (true? k) (false? k))
:when (if (= 4 (count (filter true? [a b c d e f g h i j k]))) (true? l) (false? l))]
[a b c d e f g h i j k l]))</syntaxhighlight>
{{out}}
<pre>
=> (twelve-statements)
([true false true true false true true false false false true false])
</pre>
=={{header|Common Lisp}}==
<syntaxhighlight lang="lisp">
(defparameter *state* (make-list 12))
(defparameter *statements* '(t ; 1
(= (count-true '(7 8 9 10 11 12)) 3) ; 2
(= (count-true '(2 4 6 8 10 12)) 2) ; 3
(or (not (p 5)) (and (p 6) (p 7))) ; 4
(and (not (p 2)) (not (p 3)) (not (p 4))) ; 5
(= (count-true '(1 3 5 7 9 11)) 4) ; 6
(or (and (p 2) (not (p 3))) (and (not (p 2)) (p 3))) ; 7
(or (not (p 7)) (and (p 5) (p 6))) ; 8
(= (count-true '(1 2 3 4 5 6)) 3) ; 9
(and (p 11) (p 12)) ;10
(= (count-true '(7 8 9)) 1) ;11
(= (count-true '(1 2 3 4 5 6 7 8 9 10 11)) 4))) ;12
(defun start ()
(loop while (not (equal *state* '(t t t t t t t t t t t t)))
do (progn (let ((true-stats (check)))
(cond ((= true-stats 11) (result nil))
((= true-stats 12) (result t))))
(new-state))))
(defun check ()
(loop for el in *state*
for stat in *statements*
counting (eq el (eval stat)) into true-stats
finally (return true-stats)))
(defun count-true (lst)
(loop for i in lst
counting (nth (- i 1) *state*) into total
finally (return total)))
(defun p (n)
(nth (- n 1) *state*))
(defun new-state ()
(let ((contr t))
(loop for i from 0 to 11
do (progn (setf (nth i *state*) (not (eq (nth i *state*) contr)))
(setq contr (and contr (not (nth i *state*))))))))
(defun result (?)
(format t "~:[Missed by one~;Solution:~] ~%~{~:[F~;T~] ~}~%" ? *state*))</syntaxhighlight>
<pre>
Missed by one
T F F T F F F F F F F F
Missed by one
T F F F T F F F F F F F
Missed by one
T F F F T F F T F F F F
Missed by one
T F T T F T T F T F F F
Missed by one
T F T T F F F T T F F F
Missed by one
T F F T F T F T T F F F
Missed by one
T T F T F F T T T F F F
Missed by one
T T F T F F T F T T F F
Solution:
T F T T F T T F F F T F
Missed by one
F F F F T F F T F F T F
Missed by one
T F F F T F F T F F T F
Missed by one
T F F F T T F F T F T F
Missed by one
T T F T F F T F T F F T
Missed by one
F F F T F F F T F T T T
Missed by one
T F F T F F F T F T T T
Missed by one
F F F F T F F T F T T T
Missed by one
T F F F T F F T F T T T
NIL</pre>
=={{header|D}}==
<syntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.functional;
immutable texts = [
Line 262 ⟶ 1,339:
"exactly 4 of the preceding statements are true"];
immutable pure @safe @nogc bool function(in bool[])[12] predicates = [
s => s.length == 12,
s =>
s =>
s => s[4] ? (s[5] && s[6]) : true,
s =>
s =>
s =>
s => s[6] ? (s[4] && s[5]) : true,
s =>
s => s[10] && s[11],
s =>
s =>
void main() @safe {
enum nStats =
foreach (immutable n; 0 .. 2 ^^ nStats) {
bool[nStats] st, matches;
if (matches[].sum >= nStats - 1)
writefln("Missed by statement: %d",
writefln("%-(%s %)", st[].map!q{ "FT"[a] });
}
}
}</syntaxhighlight>
{{out}}
<pre>Missed by statement: 8
T F F T F F F F F F F F
Missed by statement: 8
T F F F T F F F F F F F
Missed by statement: 11
T F F F T F F T F F F F
Missed by statement: 9
T F T T F T T F T F F F
Missed by statement: 7
T F T T F F F T T F F F
Missed by statement: 6
T F F T F T F T T F F F
Missed by statement: 8
T T F T F F T T T F F F
Missed by statement: 10
T T F T F F T F T T F F
>>> Solution:
T F T T F T T F F F T F
Missed by statement: 1
F F F F T F F T F F T F
Missed by statement: 12
T F F F T F F T F F T F
Missed by statement: 8
T F F F T T F F T F T F
Missed by statement: 12
T T F T F F T F T F F T
Missed by statement: 1
F F F T F F F T F T T T
Missed by statement: 12
T F F T F F F T F T T T
Missed by statement: 1
F F F F T F F T F T T T
Missed by statement: 12
T F F F T F F T F T T T</pre>
=={{header|EasyLang}}==
<syntaxhighlight lang=easylang>
len t[] 12
func f n .
if n = 1
return if 12 = 12
elif n =
for i = 7 to
s +=
.
return if s = 3
elif n =
for i
s += t[i]
.
return if s = 2
elif n = 4
if t[5] = 1
return if t[6] + t[7] = 2
.
return 1
elif n = 5
for i = 2 to 4
s += t[i]
.
return if s = 0
elif n = 6
for i = 1 step 2 to 11
s += t[i]
.
return if s = 4
elif n = 7
return if t[2] + t[3] = 1
elif n = 8
if t[7] = 1
return if t[5] + t[6] = 2
.
return 1
elif n = 9
for i = 1 to 6
s += t[i]
.
return if s = 3
elif n = 10
return if t[11] + t[12] = 2
elif n = 11
for i = 7 to 9
s += t[i]
.
return if s = 1
elif n = 12
for i = 1 to 11
s += t[i]
.
return if s = 4
.
.
for tst = 0 to 4095
h = tst
for i to 12
t[i] = h mod 2
h = h div 2
.
s = 0
for i to 12
s += if f i = t[i]
.
if s = 12
print t[]
.
.
</syntaxhighlight>
{{out}}
<pre>
[ 1 0 1 1 0 1 1 0 0 0 1 0 ]
</pre>
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
class
APPLICATION
create
make
feature
make
-- Possible solutions.
do
create s.make_filled (False, 1, 12)
s [1] := True
recurseAll (2)
io.put_string (counter.out + " solution found. ")
end
feature {NONE}
s: ARRAY [BOOLEAN]
check2: BOOLEAN
-- Is statement 2 fulfilled?
local
count: INTEGER
do
across
7 |..| 12 as c
loop
if s [c.item] then
count := count + 1
end
end
Result := s [2] = (count = 3)
end
check3: BOOLEAN
-- Is statement 3 fulfilled?
local
count, i: INTEGER
do
from
i := 2
until
i > 12
loop
if s [i] then
count := count + 1
end
i := i + 2
end
Result := s [3] = (count = 2)
end
check4: BOOLEAN
-- Is statement 4 fulfilled?
do
Result := s [4] = ((not s [5]) or (s [6] and s [7]))
end
check5: BOOLEAN
-- Is statement 5 fulfilled?
do
Result := s [5] = ((not s [2]) and (not s [3]) and (not s [4]))
end
check6: BOOLEAN
-- Is statement 6 fulfilled?
local
count, i: INTEGER
do
from
i := 1
until
i > 11
loop
if s [i] then
count := count + 1
end
i := i + 2
end
Result := s [6] = (count = 4)
end
check7: BOOLEAN
-- Is statement 7 fulfilled?
do
Result := s [7] = ((s [2] or s [3]) and not (s [2] and s [3]))
end
check8: BOOLEAN
-- Is statement 8 fulfilled?
do
Result := s [8] = (not s [7] or (s [5] and s [6]))
end
check9: BOOLEAN
-- Is statement 9 fulfilled?
local
count: INTEGER
do
across
1 |..| 6 as c
loop
if s [c.item] then
count := count + 1
end
end
Result := s [9] = (count = 3)
end
check10: BOOLEAN
-- Is statement 10 fulfilled?
do
Result := s [10] = (s [11] and s [12])
end
check11: BOOLEAN
-- Is statement 11 fulfilled?
local
count: INTEGER
do
across
7 |..| 9 as c
loop
if s [c.item] then
count := count + 1
end
end
Result := s [11] = (count = 1)
end
check12: BOOLEAN
-- Is statement 12 fulfilled?
local
count: INTEGER
do
across
1 |..| 11 as c
loop
if s [c.item] then
count := count + 1
end
end
Result := (s [12] = (count = 4))
end
counter: INTEGER
checkit
-- Check if all statements are correctly solved.
do
if check2 and check3 and check4 and check5 and check6 and check7 and check8 and check9 and check10 and check11 and check12 then
across
1 |..| 12 as c
loop
if s [c.item] then
io.put_string (c.item.out + "%T")
end
end
io.new_line
counter := counter + 1
end
end
recurseAll (k: INTEGER)
-- All possible True and False combinations to check for a solution.
do
if k = 13 then
checkit
else
s [k] := False
recurseAll (k + 1)
s [k] := True
recurseAll (k + 1)
end
end
end
</syntaxhighlight>
{{out}}
<pre>
1 3 4 6 7 11
1 solution found.
</pre>
=={{header|Elena}}==
ELENA 6.x :
<syntaxhighlight lang="elena">import system'routines;
import extensions;
import extensions'text;
extension op
{
printSolution(bits)
= self.zipBy(bits,
(s,b => s.iif("T","F") + (s.xor(b)).iif("* "," "))).summarize(new StringWriter());
toBit()
= self.iif(1,0);
}
puzzle = new Func1[]
{
(bits => bits.Length == 12),
(bits => bits.last(6).selectBy::(x => x.toBit()).summarize() == 3 ),
(bits => bits.zipBy(new Range(1, 12),
(x,i => (i.toInt().isEven()).and(x).toBit())).summarize() == 2 ),
(bits => bits[4].iif(bits[5] && bits[6],true) ),
(bits => ((bits[1] || bits[2]) || bits[3]).Inverted ),
(bits => bits.zipBy(new Range(1, 12),
(x,i => (i.toInt().isOdd()).and(x).toBit() )).summarize() == 4 ),
(bits => bits[1].xor(bits[2]) ),
(bits => bits[6].iif(bits[5] && bits[4],true) ),
(bits => bits.top(6).selectBy::(x => x.toBit() ).summarize() == 3 ),
(bits => bits[10] && bits[11] ),
(bits => (bits[6].toBit() + bits[7].toBit() + bits[8].toBit())==1 ),
(bits => bits.top(11).selectBy::(x => x.toBit()).summarize() == 4 )
};
public program()
{
console.writeLine();
for(int n := 0; n < 2.power(12); n += 1)
{
var bits := BitArray32.load(n).top(12).toArray();
var results := puzzle.selectBy::(r => r(bits)).toArray();
var counts := bits.zipBy(results, (b,r => b.xor(r).toBit() )).summarize();
counts =>
0 { console.printLine("Total hit :",results.printSolution(bits)) }
1 { console.printLine("Near miss :",results.printSolution(bits)) }
12 { console.printLine("Total miss:",results.printSolution(bits)) };
};
console.readChar()
}</syntaxhighlight>
{{out}}
<pre>
Near miss :T F F T F F F T* F F F F
Near miss :T F F F T F F T* F F F F
Near miss :T F F F T F F T F F T* F
Near miss :T F T T F T T F F* F F F
Near miss :T F T T F F T* T T F F F
Near miss :T F F T F F* F T T F F F
Near miss :T T F T F F T F* T F F F
Near miss :T T F T F F T F T F* F F
Total hit :T F T T F T T F F F T F
Near miss :T* F F F T F F T F F T F
Near miss :T F F F T F F T F F T T*
Near miss :T F F F T T F T* T F T F
Near miss :T T F T F F T F T F F F*
Total miss:T* T* F* F* F* F* T* T* F* F* T* F*
Total miss:T* F* F* T* F* F* F* T* F* T* F* F*
Near miss :T* F F T F F F T F T T T
Near miss :T F F T F F F T F T T F*
Near miss :T* F F F T F F T F T T T
Near miss :T F F F T F F T F T T F*
</pre>
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
PROGRAM TWELVE_STMS
!$DYNAMIC
DIM PASS%[0],T%[0]
FUNCTION EOR(X,Y)
EOR=(X AND NOT(Y)) OR (NOT(X) AND Y)
END FUNCTION
BEGIN
NSTATEMENTS%=12
!$DIM PASS%[NSTATEMENTS%],T%[NSTATEMENTS%]
FOR TRY%=0 TO 2^NSTATEMENTS%-1 DO
! Postulate answer:
FOR STMT%=1 TO 12 DO
T%[STMT%]=(TRY% AND 2^(STMT%-1))<>0
END FOR
! Test consistency:
PASS%[1]=T%[1]=(NSTATEMENTS%=12)
PASS%[2]=T%[2]=((T%[7]+T%[8]+T%[9]+T%[10]+T%[11]+T%[12])=-3)
PASS%[3]=T%[3]=((T%[2]+T%[4]+T%[6]+T%[8]+T%[10]+T%[12])=-2)
PASS%[4]=T%[4]=((NOT T%[5] OR (T%[6] AND T%[7])))
PASS%[5]=T%[5]=(NOT T%[2] AND NOT T%[3] AND NOT T%[4])
PASS%[6]=T%[6]=((T%[1]+T%[3]+T%[5]+T%[7]+T%[9]+T%[11])=-4)
PASS%[7]=T%[7]=(EOR(T%[2],T%[3]))
PASS%[8]=T%[8]=((NOT T%[7] OR (T%[5] AND T%[6])))
PASS%[9]=T%[9]=((T%[1]+T%[2]+T%[3]+T%[4]+T%[5]+T%[6])=-3)
PASS%[10]=T%[10]=(T%[11] AND T%[12])
PASS%[11]=T%[11]=((T%[7]+T%[8]+T%[9])=-1)
PASS%[12]=T%[12]=((T%[1]+T%[2]+T%[3]+T%[4]+T%[5]+T%[6]+T%[7]+T%[8]+T%[9]+T%[10]+T%[11])=-4)
SUM=0
FOR I%=1 TO 12 DO
SUM=SUM+PASS%[I%]
END FOR
CASE SUM OF
-11->
PRINT("Near miss with statements ";)
FOR STMT%=1 TO 12 DO
IF T%[STMT%] THEN PRINT(STMT%;) END IF
IF NOT PASS%[STMT%] THEN MISS%=STMT% END IF
END FOR
PRINT("true (failed ";MISS%;").")
END ->
-12->
PRINT("Solution! with statements ";)
FOR STMT%=1 TO 12 DO
IF T%[STMT%] THEN PRINT(STMT%;) END IF
END FOR
PRINT("true.")
END ->
END CASE
END FOR ! TRY%
END PROGRAM</syntaxhighlight>
{{out}}<pre>
Near miss with statements 1 4 true (failed 8 ).
Near miss with statements 1 5 true (failed 8 ).
Near miss with statements 1 5 8 true (failed 11 ).
Near miss with statements 1 3 4 6 7 9 true (failed 9 ).
Near miss with statements 1 3 4 8 9 true (failed 7 ).
Near miss with statements 1 4 6 8 9 true (failed 6 ).
Near miss with statements 1 2 4 7 8 9 true (failed 8 ).
Near miss with statements 1 2 4 7 9 10 true (failed 10 ).
Solution! with statements 1 3 4 6 7 11 true.
Near miss with statements 5 8 11 true (failed 1 ).
Near miss with statements 1 5 8 11 true (failed 12 ).
Near miss with statements 1 5 6 9 11 true (failed 8 ).
Near miss with statements 1 2 4 7 9 12 true (failed 12 ).
Near miss with statements 4 8 10 11 12 true (failed 1 ).
Near miss with statements 1 4 8 10 11 12 true (failed 12 ).
Near miss with statements 5 8 10 11 12 true (failed 1 ).
Near miss with statements 1 5 8 10 11 12 true (failed 12 ).
</pre>
=={{header|Forth}}==
Forth is excellently suited to solve this, because it has excellent support for manipulating bitpatterns.
<syntaxhighlight lang="forth">: lastbit ( n1 -- n2)
dup if 1 swap begin dup 1 <> while swap 1+ swap 1 rshift repeat drop then
;
: bit 1 swap lshift and 0<> ; ( n1 n2 -- f)
: bitcount 0 swap begin dup while dup 1- and swap 1+ swap repeat drop ;
12 constant #stat \ number of statements
\ encoding of the statements
: s1 >r #stat 12 = r> 0 bit = ; \ heavy use of binary
: s2 >r r@ 4032 and bitcount 3 = r> 1 bit = ;
: s3 >r r@ 2730 and bitcount 2 = r> 2 bit = ;
: s4 >r r@ 4 bit 0= 96 r@ over and = or r> 3 bit = ;
: s5 >r r@ 14 and 0= r> 4 bit = ;
: s6 >r r@ 1365 and bitcount 4 = r> 5 bit = ;
: s7 >r r@ 1 bit r@ 2 bit xor r> 6 bit = ;
: s8 >r r@ 6 bit 0= 48 r@ over and = or r> 7 bit = ;
: s9 >r r@ 63 and bitcount 3 = r> 8 bit = ;
: s10 >r 3072 r@ over and = r> 9 bit = ;
: s11 >r r@ 448 and bitcount 1 = r> 10 bit = ;
: s12 >r r@ 2047 and bitcount 4 = r> 11 bit = ;
: list #stat 0 do dup i bit if i 1+ . then loop drop ;
: nearmiss? \ do we have a near miss?
over #stat 1- = if ( true-pattern #true stat-pattern)
." Near miss with statements " dup list ." true (failed "
>r over invert 1 #stat lshift 1- and lastbit 0 .r ." )" cr r>
then \ extract the failed statement
;
\ have we found a solution?
: solution? ( true-pattern #true stat-pattern)
over #stat = if ." Solution! with statements " dup list ." true." cr then
;
: 12statements \ test the twelve patterns
1 #stat lshift 0 do \ create another bit pattern
i s12 2* i s11 + 2* i s10 + 2* i s9 + 2* i s8 + 2* i s7 + 2*
i s6 + 2* i s5 + 2* i s4 + 2* i s3 + 2* i s2 + 2* i s1 +
abs dup bitcount i solution? nearmiss? drop drop drop
loop \ count number of bytes and evaluate
;
12statements</syntaxhighlight>
{{out}}
<pre>
Near miss with statements 1 4 true (failed 8)
Near miss with statements 1 5 true (failed 8)
Near miss with statements 1 5 8 true (failed 11)
Near miss with statements 1 3 4 6 7 9 true (failed 9)
Near miss with statements 1 3 4 8 9 true (failed 7)
Near miss with statements 1 4 6 8 9 true (failed 6)
Near miss with statements 1 2 4 7 8 9 true (failed 8)
Near miss with statements 1 2 4 7 9 10 true (failed 10)
Solution! with statements 1 3 4 6 7 11 true.
Near miss with statements 5 8 11 true (failed 1)
Near miss with statements 1 5 8 11 true (failed 12)
Near miss with statements 1 5 6 9 11 true (failed 8)
Near miss with statements 1 2 4 7 9 12 true (failed 12)
Near miss with statements 4 8 10 11 12 true (failed 1)
Near miss with statements 1 4 8 10 11 12 true (failed 12)
Near miss with statements 5 8 10 11 12 true (failed 1)
Near miss with statements 1 5 8 10 11 12 true (failed 12)
ok
</pre>
=={{header|FreeBASIC}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="freebasic">Dim As Integer nEnunciados = 12, intento, enun, errado
Dim As Integer Afirm(nEnunciados), T(nEnunciados)
For intento = 0 To 2^nEnunciados-1
REM Postular respuesta:
For enun = 1 To 12
T(enun) = (intento And 2^(enun-1)) <> 0
Next enum
REM Prueba de consistencia:
Afirm(1) = T(1) = (nEnunciados = 12)
Afirm(2) = T(2) = ((T(7)+T(8)+T(9)+T(10)+T(11)+T(12)) = -3)
Afirm(3) = T(3) = ((T(2)+T(4)+T(6)+T(8)+T(10)+T(12)) = -2)
Afirm(4) = T(4) = ((Not T(5) Or (T(6) And T(7))))
Afirm(5) = T(5) = (Not T(2) And Not T(3) And Not T(4))
Afirm(6) = T(6) = ((T(1)+T(3)+T(5)+T(7)+T(9)+T(11)) = -4)
Afirm(7) = T(7) = ((T(2) Or T(3)))
Afirm(8) = T(8) = ((Not T(7) Or (T(5) And T(6))))
Afirm(9) = T(9) = ((T(1)+T(2)+T(3)+T(4)+T(5)+T(6)) = -3)
Afirm(10) = T(10) = (T(11) And T(12))
Afirm(11) = T(11) = ((T(7)+T(8)+T(9)) = -1)
Afirm(12) = T(12) = ((T(1)+T(2)+T(3)+T(4)+T(5)+T(6) + T(7)+T(8)+T(9)+T(10)+T(11)) = -4)
Dim As Integer suma = 0
For cont As Integer = 1 To 12
suma += Afirm(cont)
Next cont
Select Case suma
Case -11
Color 7: Print "Casi resuelto, con los enunciados ";
For enun = 1 To 12
If T(enun) Then Print ; enun; " ";
If Not Afirm(enun) Then errado = enun
Next enun
Print "verdaderos (falsos"; errado; ")."
Case -12
Color 10: Print "Resuelto! con los enunciados ";
For enun = 1 To 12
If T(enun) Then Print ; enun; " ";
Next enun
Print "verdaderos."
End Select
Next intento
Sleep</syntaxhighlight>
=={{header|Go}}==
<
import "fmt"
Line 472 ⟶ 2,085:
solution <- tz
}
}</
{{out}}
<pre>
Line 493 ⟶ 2,106:
near miss: 1 5 8 10 11 12
</pre>
=={{header|Groovy}}==
Solution:
<syntaxhighlight lang="groovy">enum Rule {
r01( 1, { r()*.num == (1..12) }),
r02( 2, { r(7..12).count { it.truth } == 3 }),
r03( 3, { r(2..12, 2).count { it.truth } == 2 }),
r04( 4, { r(5).truth ? r(6).truth && r(7).truth : true }),
r05( 5, { r(2..4).count { it.truth } == 0 }),
r06( 6, { r(1..11, 2).count { it.truth } == 4 }),
r07( 7, { r(2).truth != r(3).truth }),
r08( 8, { r(7).truth ? r(5).truth && r(6).truth : true }),
r09( 9, { r(1..6).count { it.truth } == 3 }),
r10(10, { r(11).truth && r(12).truth }),
r11(11, { r(7..9).count { it.truth } == 1 }),
r12(12, { r(1..11).count { it.truth } == 4 });
final int num
final Closure statement
boolean truth
static final List<Rule> rules = [ null, r01, r02, r03, r04, r05, r06, r07, r08, r09, r10, r11, r12]
private Rule(num, statement) {
this.num = num
this.statement = statement
}
public static Rule r(int index) { rules[index] }
public static List<Rule> r() { rules[1..12] }
public static List<Rule> r(List<Integer> indices) { rules[indices] }
public static List<Rule> r(IntRange indices) { rules[indices] }
public static List<Rule> r(IntRange indices, int step) { r(indices.step(step)) }
public static void setAllTruth(int bits) {
(1..12).each { r(it).truth = !(bits & (1 << (12 - it))) }
}
public static void evaluate() {
def nearMisses = [:]
(0..<(2**12)).each { i ->
setAllTruth(i)
def truthCandidates = r().findAll { it.truth }
def truthMatchCount = r().count { it.statement() == it.truth }
if (truthMatchCount == 12) {
println ">Solution< ${truthCandidates*.num}"
} else if (truthMatchCount == 11) {
def miss = (1..12).find { r(it).statement() != r(it).truth }
nearMisses << [(truthCandidates): miss]
}
}
nearMisses.each { truths, miss ->
printf ("Near Miss: %-21s (failed %2d)\n", "${truths*.num}", miss)
}
}
}
Rule.evaluate()</syntaxhighlight>
{{out}}
<pre>>Solution< [1, 3, 4, 6, 7, 11]
Near Miss: [1, 2, 4, 7, 8, 9] (failed 8)
Near Miss: [1, 2, 4, 7, 9, 10] (failed 10)
Near Miss: [1, 2, 4, 7, 9, 12] (failed 12)
Near Miss: [1, 3, 4, 6, 7, 9] (failed 9)
Near Miss: [1, 3, 4, 8, 9] (failed 7)
Near Miss: [1, 4, 6, 8, 9] (failed 6)
Near Miss: [1, 4, 8, 10, 11, 12] (failed 12)
Near Miss: [1, 4] (failed 8)
Near Miss: [1, 5, 6, 9, 11] (failed 8)
Near Miss: [1, 5, 8, 10, 11, 12] (failed 12)
Near Miss: [1, 5, 8, 11] (failed 12)
Near Miss: [1, 5, 8] (failed 11)
Near Miss: [1, 5] (failed 8)
Near Miss: [4, 8, 10, 11, 12] (failed 1)
Near Miss: [5, 8, 10, 11, 12] (failed 1)
Near Miss: [5, 8, 11] (failed 1)</pre>
=={{header|Haskell}}==
Shows answers with 1 for true, followed by list of indices of contradicting elements in each set of 1/0s (index is 0-based).
<
tf
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 ..]
, 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
putStrLn "Near misses"
mapM_ print $ t 1</syntaxhighlight>
{{out}}
<pre>
Line 551 ⟶ 2,254:
=={{header|J}}==
In the following 'apply' is the foreign conjunction:
<
128!:2
NB. example
'*:' apply 1 2 3
1 4 9</
This enables us to apply strings (left argument) being verbs to the right argument, mostly a noun.
<
12&=@# NB. 1. This is a numbered list of twelve statements.
3=+/@:{.~&_6 NB. 2. Exactly 3 of the last 6 statements are true.
2= +/@:{~&1 3 5 7 9 11 NB. 3. Exactly 2 of the even-numbered statements are true.
4&{=*./@:{~&4 5 6 NB. 4. If statement 5 is true, then statements 6 and 7 are both true.
0=+/@:{~&1 2 3 NB. 5. The 3 preceding statements are all false.
4=+/@:{~&0 2 4 6 8 10 NB. 6. Exactly 4 of the odd-numbered statements are true.
1=+/@:{~&1 2 NB. 7. Either statement 2 or 3 is true, but not both.
6&{=*./@:{~&4 5 6 NB. 8. If statement 7 is true, then 5 and 6 are both true.
3=+/@:{.~&6 NB. 9. Exactly 3 of the first 6 statements are true.
2=+/@:{~&10 11 NB. 10. The next two statements are both true.
1=+/@:{~&6 7 8 NB. 11. Exactly 1 of statements 7, 8 and 9 are true.
4=+/@:{.~&11 NB. 12. Exactly 4 of the preceding statements are true.
)
testall=: (];"1 0<@I.@:(]~:(apply&><))"1) #:@i.@(2&^)@#</
The output follows the Haskell convention: true/false bitstring followed by the index of a contradiction
'''All true'''
<
┌───────────────────────┬┐
└───────────────────────┴┘</syntaxhighlight>
Or, numerically:
<syntaxhighlight lang="j"> 1+I.;(#~0=#@{::~&_1"1) testall S
1 3 4 6 7 11</syntaxhighlight>
'''Near misses'''
<
┌───────────────────────┬──┐
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
├───────────────────────┼──┤
└───────────────────────┴──┘</syntaxhighlight>
'''Iterative for all true'''
<br>
<
1 0 1 1 0 1 1 0 0 0 1 0</
Here is an alternative representation of the statements which might be slightly easier to read. (The behavior is identical):
<syntaxhighlight lang="j">true=:1 :'(m-1)&{'
S=: <;._2 (0 :0)
12 = # NB. 1. This is a numbered list of twelve statements.
3 (= +/) _6&{. NB. 2. Exactly 3 of the last 6 statements are true.
2 (= +/) (12$0 1)&# NB. 3. Exactly 2 of the even-numbered statements are true.
5 true (<: */) 6 7 true NB. 4. If statement 5 is true, then statements 6 and 7 are both true.
0 (= +/) 2 3 4 true NB. 5. The 3 preceding statements are all false.
4 (= +/) (12$1 0)&# NB. 6. Exactly 4 of the odd-numbered statements are true.
1 (= +/) 2 3 true NB. 7. Either statement 2 or 3 is true, but not both.
7 true (<: */) 5 6 true NB. 8. If statement 7 is true, then 5 and 6 are both true.
3 (= +/) 6&{. NB. 9. Exactly 3 of the first 6 statements are true.
*/@(11 12 true) NB. 10. The next two statements are both true.
1 (= +/) 7 8 9 true NB. 11. Exactly 1 of statements 7, 8 and 9 are true.
4 (= +/) }: NB. 12. Exactly 4 of the preceding statements are true.
)</syntaxhighlight>
And here is an approach which does not use the verb apply, but instead mostly relies on simple arithmetic.
<syntaxhighlight lang="j">'sum not mask'=: |:".;._2(0 :0)
0; 0; 0 0 0 0 0 0 0 0 0 0 0 0 NB. 1. This is a numbered list of twelve statements.
3; 0; 0 0 0 0 0 0 1 1 1 1 1 1 NB. 2. Exactly 3 of the last 6 statements are true.
2; 0; 0 1 0 1 0 1 0 1 0 1 0 1 NB. 3. Exactly 2 of the even-numbered statements are true.
2; 5; 0 0 0 0 0 1 1 0 0 0 0 0 NB. 4. If statement 5 is true, then statements 6 and 7 are both true.
0; 0; 0 1 1 1 0 0 0 0 0 0 0 0 NB. 5. The 3 preceding statements are all false.
4; 0; 1 0 1 0 1 0 1 0 1 0 1 0 NB. 6. Exactly 4 of the odd-numbered statements are true.
1; 0; 0 1 1 0 0 0 0 0 0 0 0 0 NB. 7. Either statement 2 or 3 is true, but not both.
2; 7; 0 0 0 0 1 1 0 0 0 0 0 0 NB. 8. If statement 7 is true, then 5 and 6 are both true.
3; 0; 1 1 1 1 1 1 0 0 0 0 0 0 NB. 9. Exactly 3 of the first 6 statements are true.
2; 0; 0 0 0 0 0 0 0 0 0 0 1 1 NB. 10. The next two statements are both true.
1; 0; 0 0 0 0 0 0 1 1 1 0 0 0 NB. 11. Exactly 1 of statements 7, 8 and 9 are true.
4; 0; 1 1 1 1 1 1 1 1 1 1 1 0 NB. 12. Exactly 4 of the preceding statements are true.
)
propositions=: |:#:i.2^#sum
errors=: propositions~:(1 - not { 1,propositions) >. sum = mask +/ .*propositions</syntaxhighlight>
Now, as before, we can find the consistent set of true and false values:
<syntaxhighlight lang="j"> #:I.0=+/errors
1 0 1 1 0 1 1 0 0 0 1 0
1+I.#:I.0=+/errors NB. true propositions for the consistent case
1 3 4 6 7 11</syntaxhighlight>
And, we can find the set which is inconsistent for only one proposition:
<syntaxhighlight lang="j"> offby1=: 1=+/errors
'Statement ',"1 (":1+I.|: offby1 #"1 errors),"1 ' is inconsistent with exactly ',"1 ((1":@:+I.)"1 #:I.offby1),"1 ' being true'
Statement 1 is inconsistent with exactly 5 8 11 being true
Statement 1 is inconsistent with exactly 5 8 10 11 12 being true
Statement 1 is inconsistent with exactly 4 8 10 11 12 being true
Statement 8 is inconsistent with exactly 1 5 being true
Statement 11 is inconsistent with exactly 1 5 8 being true
Statement 12 is inconsistent with exactly 1 5 8 11 being true
Statement 12 is inconsistent with exactly 1 5 8 10 11 12 being true
Statement 8 is inconsistent with exactly 1 5 6 9 11 being true
Statement 8 is inconsistent with exactly 1 4 being true
Statement 12 is inconsistent with exactly 1 4 8 10 11 12 being true
Statement 6 is inconsistent with exactly 1 4 6 8 9 being true
Statement 7 is inconsistent with exactly 1 3 4 8 9 being true
Statement 9 is inconsistent with exactly 1 3 4 6 7 9 being true
Statement 12 is inconsistent with exactly 1 2 4 7 9 12 being true
Statement 10 is inconsistent with exactly 1 2 4 7 9 10 being true
Statement 8 is inconsistent with exactly 1 2 4 7 8 9 being true</syntaxhighlight>
=={{header|Java}}==
The following Java code uses brute force. It tries to translate the logical statements as naturally as possible. The run time is almost zero.
<syntaxhighlight lang="java">
public class LogicPuzzle
{
Line 741 ⟶ 2,515:
}
}
</syntaxhighlight>
{{out}}
<pre>
Line 749 ⟶ 2,523:
</pre>
=={{header|
{{works with|jq|1.4}}
In this section, we use a brute-force strategy, mainly for the sake
of comparability with many of the other solutions on this page, but
also because it requires only 2^12 tests -- or 2^11 since the truth
of the first statement is manifest. It is worth noting, however,
that an alternative strategy would be to include some of the
constraints inside the generator.
(The truth or falsity of the first statement is not completely "logical" because it requires some kind of inspection that the statements are numbered. It is reasonable, however, to interpret (1) to mean that there are 12 statements.)
One interesting aspect of the following jq program is the
helper function, indexed(filter): it obviates the need here not only
for a specific "select every nth item" filter, but also for a
generic "with_index" annotator.
<syntaxhighlight lang="jq">def indexed(filter):
. as $in
| reduce range(0;length) as $i ([]; if ($i | filter) then . + [$in[$i]] else . end);
def count(value): map(select(. == value)) | length;
# The truth or falsity of the 12 statements can be captured in an array of size 12:
def generate(k):
if k == 1 then [true], [false]
else generate(1) + generate(k-1)
end;
# Input: a boolean array
def evaluate:
[ (length == 12), #1
((.[6:] | count(true)) == 3), #2
((indexed(. % 2 == 1) | count(true)) == 2), #3
(if .[4] then .[5] and .[6] else true end), #4
((.[1:4] | count(false)) == 3), #5
((indexed(. % 2 == 0) | count(true)) == 4), #6
(([.[1], .[2]] | count(true)) == 1), #7
(if .[6] then .[4] and .[5] else true end), #8
((.[0:6] | count(true)) == 3), #9
(.[10] and .[11]), #10
((.[6:9] | count(true)) == 1), #11
((.[0:11] | count(true)) == 4) #12
];
# The following query generates the solution to the problem:
# generate(12) | . as $vector | if evaluate == $vector then $vector else empty end
# Running "task" as defined next would generate
# both the general solution as well as the off-by-one solutions:
def task:
# count agreements
def agreed(x;y): reduce range(0;x|length) as $i (0; if x[$i] == y[$i] then .+1 else . end);
reduce generate(12) as $vector
([]; ($vector | evaluate) as $e
| agreed($vector; $e) as $agreed
| if $agreed == 12 then [[12,$vector]] + .
elif $agreed == 11 then . + [[11, $vector]]
else .
end);
# Since the solutions have been given elsewhere, we simply count the
# number of exact and off-by-one solutions:
task | length</syntaxhighlight>
{{out}}
$ jq -M -n -f Twelve_statements.jq
17
=={{header|Julia}}==
This task involves only 12 statements, so an exhaustive search of the 2^12 possible statement value combinations is quite feasible. The program shows "total misses" and the distribution of numbers of hits in addition to solutions and near misses.
<syntaxhighlight lang="julia">using Printf
function showflaggedbits{T<:BitArray{1}}(a::T, f::T)
tf = map(x->x ? "T" : "F", a)
flg = map(x->x ? "*" : " ", f)
join(tf .* flg, " ")
end
const props = [s -> length(s) == 12,
s -> sum(s[7:12]) == 3,
s -> sum(s[2:2:end]) == 2,
s -> !s[5] || (s[6] & s[7]),
s -> !any(s[2:4]),
s -> sum(s[1:2:end]) == 4,
s -> s[2] $ s[3],
s -> !s[7] || (s[5] & s[6]),
s -> sum(s[1:6]) == 3,
s -> s[11] & s[12],
s -> sum(s[7:9]) == 1,
s -> sum(s[1:end-1]) == 4]
const NDIG = length(props)
NDIG < WORD_SIZE || println("WARNING, too many propositions!")
mhist = zeros(Int, NDIG+1)
println("Checking the ", NDIG, " statements against all possibilities.\n")
print(" "^15)
for i in 1:NDIG
print(@sprintf "%3d" i)
end
println()
for i in 0:(2^NDIG-1)
s = bitpack(digits(i, 2, NDIG))
t = bitpack([p(s) for p in props])
misses = s$t
mcnt = sum(misses)
mhist[NDIG-mcnt+1] += 1
mcnt < 2 || mcnt == NDIG || continue
if mcnt == 0
print(" Exact Match: ")
elseif mcnt == NDIG
print(" Total Miss: ")
else
print(" Near Miss: ")
end
println(showflaggedbits(t, misses))
end
println()
println("Distribution of matches")
println(" Matches Cases")
for i in (NDIG+1):-1:1
println(@sprintf " %2d => %4d" i-1 mhist[i])
end
</syntaxhighlight>
{{out}}
<pre>
Checking the 12 statements against all possibilities.
1 2 3 4 5 6 7 8 9 10 11 12
Near Miss: T F F T F F F T* F F F F
Near Miss: T F F F T F F T* F F F F
Near Miss: T F F F T F F T F F T* F
Near Miss: T F T T F T T F F* F F F
Near Miss: T F T T F F T* T T F F F
Near Miss: T F F T F F* F T T F F F
Near Miss: T T F T F F T F* T F F F
Near Miss: T T F T F F T F T F* F F
Exact Match: T F T T F T T F F F T F
Near Miss: T* F F F T F F T F F T F
Near Miss: T F F F T F F T F F T T*
Near Miss: T F F F T T F T* T F T F
Near Miss: T T F T F F T F T F F F*
Total Miss: T* T* F* F* F* F* T* T* F* F* T* F*
Total Miss: T* F* F* T* F* F* F* T* F* T* F* F*
Near Miss: T* F F T F F F T F T T T
Near Miss: T F F T F F F T F T T F*
Near Miss: T* F F F T F F T F T T T
Near Miss: T F F F T F F T F T T F*
Distribution of matches
Matches Cases
12 => 1
11 => 16
10 => 65
9 => 236
8 => 488
7 => 781
6 => 909
5 => 791
4 => 514
3 => 205
2 => 75
1 => 13
0 => 2
</pre>
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.3
typealias Predicate = (String) -> Boolean
val predicates = listOf<Predicate>(
{ it.length == 13 }, // indexing starts at 0 but first bit ignored
{ (7..12).count { i -> it[i] == '1' } == 3 },
{ (2..12 step 2).count { i -> it[i] == '1' } == 2 },
{ it[5] == '0' || (it[6] == '1' && it[7] == '1') },
{ it[2] == '0' && it[3] == '0' && it[4] == '0' },
{ (1..11 step 2).count { i -> it[i] == '1' } == 4 },
{ (it[2] == '1') xor (it[3] == '1') },
{ it[7] == '0' || (it[5] == '1' && it[6] == '1') },
{ (1..6).count { i -> it[i] == '1' } == 3 },
{ it[11] == '1' && it[12] == '1' },
{ (7..9).count { i -> it[i] == '1' } == 1 },
{ (1..11).count { i -> it[i] == '1' } == 4 }
)
fun show(s: String, indent: Boolean) {
if (indent) print(" ")
for (i in s.indices) if (s[i] == '1') print("$i ")
println()
}
fun main(args: Array<String>) {
println("Exact hits:")
for (i in 0..4095) {
val s = i.toString(2).padStart(13, '0')
var j = 1
if (predicates.all { it(s) == (s[j++] == '1') }) show(s, true)
}
println("\nNear misses:")
for (i in 0..4095) {
val s = i.toString(2).padStart(13, '0')
var j = 1
if (predicates.count { it(s) == (s[j++] == '1') } == 11) {
var k = 1
val iof = predicates.indexOfFirst { it(s) != (s[k++] == '1') } + 1
print(" (Fails at statement ${"%2d".format(iof)}) ")
show(s, false)
}
}
}</syntaxhighlight>
{{out}}
<pre>
Exact hits:
1 3 4 6 7 11
Near misses:
(Fails at statement 1) 5 8 11
(Fails at statement 1) 5 8 10 11 12
(Fails at statement 1) 4 8 10 11 12
(Fails at statement 8) 1 5
(Fails at statement 11) 1 5 8
(Fails at statement 12) 1 5 8 11
(Fails at statement 8) 1 5 6 9 11
(Fails at statement 8) 1 4
(Fails at statement 6) 1 4 6 8 9
(Fails at statement 7) 1 3 4 8 9
(Fails at statement 9) 1 3 4 6 7 9
(Fails at statement 12) 1 2 4 7 9 12
(Fails at statement 10) 1 2 4 7 9 10
(Fails at statement 8) 1 2 4 7 8 9
</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">Print["Answer:\n", Column@Cases[#, {s_, 0} :> s], "\nNear misses:\n",
Column@Cases[#, {s_, 1} :> s]] &[{#,
Count[Boole /@ {Length@# == 12, Total@#[[7 ;;]] == 3,
Total@#[[2 ;; 12 ;; 2]] == 2, #[[5]] (#[[6]] + #[[7]] - 2) ==
0, Total@#[[2 ;; 4]] == 0,
Total@#[[1 ;; 11 ;; 2]] == 4, #[[2]] + #[[3]] ==
1, #[[7]] (#[[5]] + #[[6]] - 2) == 0,
Total@#[[;; 6]] == 3, #[[11]] + #[[12]] == 2,
Total@#[[7 ;; 9]] == 1, Total@#[[;; 11]] == 4} - #,
Except[0]]} & /@ Tuples[{1, 0}, 12]]</syntaxhighlight>
{{Out}}
<pre>Answer:
{1,0,1,1,0,1,1,0,0,0,1,0}
Near misses:
{1,1,0,1,0,0,1,1,1,0,0,0}
{1,1,0,1,0,0,1,0,1,1,0,0}
{1,1,0,1,0,0,1,0,1,0,0,1}
{1,0,1,1,0,1,1,0,1,0,0,0}
{1,0,1,1,0,0,0,1,1,0,0,0}
{1,0,0,1,0,1,0,1,1,0,0,0}
{1,0,0,1,0,0,0,1,0,1,1,1}
{1,0,0,1,0,0,0,0,0,0,0,0}
{1,0,0,0,1,1,0,0,1,0,1,0}
{1,0,0,0,1,0,0,1,0,1,1,1}
{1,0,0,0,1,0,0,1,0,0,1,0}
{1,0,0,0,1,0,0,1,0,0,0,0}
{1,0,0,0,1,0,0,0,0,0,0,0}
{0,0,0,1,0,0,0,1,0,1,1,1}
{0,0,0,0,1,0,0,1,0,1,1,1}
{0,0,0,0,1,0,0,1,0,0,1,0}</pre>
=={{header|Nim}}==
{{trans|Kotlin}}
Not quite a translation as we use an array of booleans instead of a string. There are also other differences but the final result is the same.
<syntaxhighlight lang="nim">import bitops, sequtils, strformat, strutils, sugar
type Bools = array[1..12, bool]
const Predicates = [1: (b: Bools) => b.len == 12,
2: (b: Bools) => b[7..12].count(true) == 3,
3: (b: Bools) => toSeq(countup(2, 12, 2)).mapIt(b[it]).count(true) == 2,
4: (b: Bools) => not b[5] or b[6] and b[7],
5: (b: Bools) => not b[2] and not b[3] and not b[4],
6: (b: Bools) => toSeq(countup(1, 12, 2)).mapIt(b[it]).count(true) == 4,
7: (b: Bools) => b[2] xor b[3],
8: (b: Bools) => not b[7] or b[5] and b[6],
9: (b: Bools) => b[1..6].count(true) == 3,
10: (b: Bools) => b[11] and b[12],
11: (b: Bools) => b[7..9].count(true) == 1,
12: (b: Bools) => b[1..11].count(true) == 4]
proc `$`(b: Bools): string =
toSeq(1..12).filterIt(b[it]).join(" ")
echo "Exacts hits:"
var bools: Bools
for n in 0..4095:
block check:
for i in 1..12: bools[i] = n.testBit(12 - i)
for i, predicate in Predicates:
if predicate(bools) != bools[i]:
break check
echo " ", bools
echo "\nNear misses:"
for n in 0..4095:
for i in 1..12: bools[i] = n.testBit(12 - i)
var count = 0
for i, predicate in Predicates:
if predicate(bools) == bools[i]: inc count
if count == 11:
for i, predicate in Predicates:
if predicate(bools) != bools[i]:
echo &" (Fails at statement {i:2}) {bools}"
break</syntaxhighlight>
{{out}}
<pre>Exacts hits:
1 3 4 6 7 11
Near misses:
(Fails at statement 1) 5 8 11
(Fails at statement 1) 5 8 10 11 12
(Fails at statement 1) 4 8 10 11 12
(Fails at statement 8) 1 5
(Fails at statement 11) 1 5 8
(Fails at statement 12) 1 5 8 11
(Fails at statement 12) 1 5 8 10 11 12
(Fails at statement 8) 1 5 6 9 11
(Fails at statement 8) 1 4
(Fails at statement 12) 1 4 8 10 11 12
(Fails at statement 6) 1 4 6 8 9
(Fails at statement 7) 1 3 4 8 9
(Fails at statement 9) 1 3 4 6 7 9
(Fails at statement 12) 1 2 4 7 9 12
(Fails at statement 10) 1 2 4 7 9 10
(Fails at statement 8) 1 2 4 7 8 9</pre>
=={{header|Pascal}}==
{{works with|Free Pascal|1.06}}
Inspired by the C++ implementation, this version makes extensive use of Pascal's built-in set handling capabilities.
<syntaxhighlight lang="pascal">PROGRAM TwelveStatements;
{
This program searches through the 4095 possible sets
of 12 statements for any which may be self-consistent.
}
CONST
max12b = 4095; { Largest 12 byte number. }
TYPE
statnum = 1..12; { statement numbers }
statset = set of statnum; { sets of statements }
VAR { global variables for use in main algorithm }
trialNumber: integer;
trialSet, testResults: statset;
function Convert(n: integer): statset;
{
Converts an integer into a set of statements.
For each "1" in the last 12 bits of
the integer's binary representation,
a statement number is put into the set.
}
var
i: statnum;
s: statset;
begin
s := []; { Empty set. }
for i := 12 downto 1 do begin
if (n mod 2) = 1 then s := s + [i];
n := n div 2
end;
Convert := s
end;
procedure Express(truths: statset);
{
Writes the statement number of each "truth",
with at least one space in front,
all on one line.
}
var n: statnum;
begin
for n := 1 to 12 do
if n in truths then write(n:3);
writeln
end;
function Count(truths: statset): integer;
{ Counts the statement numbers in the set. }
var
s: statnum;
i: integer;
begin
i := 0;
for s := 1 to 12 do if s in truths then i := i + 1;
Count := i
end;
function Test(truths: statset): statset;
{
Starts with a set of supposedly true statements
and checks which of the 12 statements can actually
be confirmed about the set itself.
}
var
evens, odds, confirmations: statset;
begin
evens := [2, 4, 6, 8, 10, 12];
odds := [1, 3, 5, 7, 9, 11];
{ Statement 1 is necessarily true. }
confirmations := [1];
{ Statement 2 }
if Count(truths * [7..12]) = 3
then confirmations := confirmations + [2];
{ Statement 3 }
if Count(truths * evens) = 2
then confirmations := confirmations + [3];
{ Statement 4 is true if 6 and 7 are true, or if 5 is false. }
if ([6, 7] <= truths) or not (5 in truths)
then confirmations := confirmations + [4];
{ Statement 5 }
if [2, 3, 4] <= truths
then confirmations := confirmations + [5];
{ Statement 6 }
if Count(truths * odds) = 4
then confirmations := confirmations + [6];
{ Statement 7 }
if (2 in truths) xor (3 in truths)
then confirmations := confirmations + [7];
{ Statement 8 is true if 5 and 6 are true, or if 7 is false. }
if ([5, 6] <= truths) or not (7 in truths)
then confirmations := confirmations + [8];
{ Statement 9 }
if Count(truths * [1..6]) = 3
then confirmations := confirmations + [9];
{ Statement 10 }
if [11, 12] <= truths
then confirmations := confirmations + [10];
{ Statement 11 }
if Count(truths * [7, 8, 9]) = 1
then confirmations := confirmations + [11];
{ Statement 12 }
if Count(truths - [12]) = 4
then confirmations := confirmations + [12];
Test := confirmations
end;
BEGIN { Main algorithm. }
for trialNumber := 1 to max12b do begin
trialSet := Convert(trialNumber);
testResults := Test(trialSet);
if testResults = trialSet then Express(trialSet)
end;
writeln('Done. Press ENTER.');
readln
END.</syntaxhighlight>
{{Out}}
<pre>1 3 4 6 7 11
Done. Press ENTER.</pre>
=={{header|Perl}}==
<syntaxhighlight lang="perl">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;
}
</syntaxhighlight>
{{out}}
<pre>1 miss (1): true statements are 5 8 11
1 miss (1): true statements are 5 8 10 11 12
1 miss (1): true statements are 4 8 10 11 12
1 miss (8): true statements are 1 5
1 miss (11): true statements are 1 5 8
1 miss (12): true statements are 1 5 8 11
1 miss (12): true statements are 1 5 8 10 11 12
1 miss (8): true statements are 1 5 6 9 11
1 miss (8): true statements are 1 4
1 miss (12): true statements are 1 4 8 10 11 12
1 miss (6): true statements are 1 4 6 8 9
1 miss (7): true statements are 1 3 4 8 9
Solution: true statements are 1 3 4 6 7 11
1 miss (9): true statements are 1 3 4 6 7 9
1 miss (12): true statements are 1 2 4 7 9 12
1 miss (10): true statements are 1 2 4 7 9 10
1 miss (8): true statements are 1 2 4 7 8 9
</pre>
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">s1</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">12</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">s2</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_eq</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">7</span><span style="color: #0000FF;">..</span><span style="color: #000000;">12</span><span style="color: #0000FF;">],</span><span style="color: #008000;">'1'</span><span style="color: #0000FF;">))=</span><span style="color: #000000;">3</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">s3</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_eq</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)),</span><span style="color: #008000;">'1'</span><span style="color: #0000FF;">))=</span><span style="color: #000000;">2</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">s4</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">5</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">or</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">6</span><span style="color: #0000FF;">..</span><span style="color: #000000;">7</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">"11"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">s5</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">"000"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">s6</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_eq</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)),</span><span style="color: #008000;">'1'</span><span style="color: #0000FF;">))=</span><span style="color: #000000;">4</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">s7</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">s8</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">7</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">or</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">5</span><span style="color: #0000FF;">..</span><span style="color: #000000;">6</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">"11"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">s9</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_eq</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">6</span><span style="color: #0000FF;">],</span><span style="color: #008000;">'1'</span><span style="color: #0000FF;">))=</span><span style="color: #000000;">3</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">s10</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">11</span><span style="color: #0000FF;">..</span><span style="color: #000000;">12</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">"11"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">s11</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_eq</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">7</span><span style="color: #0000FF;">..</span><span style="color: #000000;">9</span><span style="color: #0000FF;">],</span><span style="color: #008000;">'1'</span><span style="color: #0000FF;">))=</span><span style="color: #000000;">1</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">s12</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_eq</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">11</span><span style="color: #0000FF;">],</span><span style="color: #008000;">'1'</span><span style="color: #0000FF;">))=</span><span style="color: #000000;">4</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">rtn</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">s1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s11</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s12</span><span style="color: #0000FF;">}</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">misses</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"\n"</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%012b"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find_all</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'1'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pass</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">fail</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">12</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">pass</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">call_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rtn</span><span style="color: #0000FF;">[</span><span style="color: #000000;">b</span><span style="color: #0000FF;">],{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">})=(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">b</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'1'</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">pass</span> <span style="color: #008080;">then</span> <span style="color: #000000;">fail</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">pass</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">12</span> <span style="color: #008080;">and</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">=</span><span style="color: #000000;">12</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Solution: %v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">=</span><span style="color: #000000;">11</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">misses</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Near miss: %v, fail on %d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fail</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">misses</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Solution: {1,3,4,6,7,11}
Near miss: {5,8,11}, fail on 1
Near miss: {5,8,10,11,12}, fail on 1
Near miss: {4,8,10,11,12}, fail on 1
Near miss: {1,5}, fail on 8
Near miss: {1,5,8}, fail on 11
Near miss: {1,5,8,11}, fail on 12
Near miss: {1,5,8,10,11,12}, fail on 12
Near miss: {1,5,6,9,11}, fail on 8
Near miss: {1,4}, fail on 8
Near miss: {1,4,8,10,11,12}, fail on 12
Near miss: {1,4,6,8,9}, fail on 6
Near miss: {1,3,4,8,9}, fail on 7
Near miss: {1,3,4,6,7,9}, fail on 9
Near miss: {1,2,4,7,9,12}, fail on 12
Near miss: {1,2,4,7,9,10}, fail on 10
Near miss: {1,2,4,7,8,9}, fail on 8
</pre>
=={{header|Picat}}==
{{trans|Prolog}}
<syntaxhighlight lang="picat">% {{trans|Prolog}}
go ?=>
puzzle,
fail, % check for more answers
nl.
go => true.
puzzle =>
% 1. This is a numbered list of twelve statements.
L = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12],
L :: 0..1,
element(1, L, 1),
% 2. Exactly 3 of the last 6 statements are true.
A2 #<=> sum(L[7..12]) #= 3,
% 3. Exactly 2 of the even-numbered statements are true.
A3 #<=> sum([L[I]:I in 1..12,I mod 2 == 0]) #= 2,
% 4. If statement 5 is true, then statements 6 and 7 are both true.
A4 #<=> (A5 #=> (A6 #/\ A7)),
% 5. The 3 preceding statements are all false.
A5 #<=> sum(L[2..4]) #= 0,
% 6. Exactly 4 of the odd-numbered statements are true.
A6 #<=> sum([L[I]:I in 1..12,I mod 2 == 1]) #= 4,
% 7. Either statement 2 or 3 is true, but not both.
A7 #<=> (A2 + A3 #= 1),
% 8. If statement 7 is true, then 5 and 6 are both true.
A8 #<=> (A7 #=> A5 #/\ A6),
% 9. Exactly 3 of the first 6 statements are true.
A9 #<=> sum(L[1..6]) #= 3,
% 10. The next two statements are both true.
A10 #<=> (A11 #/\ A12),
% 11. Exactly 1 of statements 7, 8 and 9 are true.
A11 #<=> (A7 + A8 + A9 #= 1),
% 12. Exactly 4 of the preceding statements are true.
A12 #<=> sum(L[1..11]) #= 4,
solve(L),
println('L'=L),
printf("Statements %w are true.\n", [I.to_string : I in 1..12, L[I] == 1].join(" ")),
nl.</syntaxhighlight>
{{out}}
<pre>L=[1,0,1,1,0,1,1,0,0,0,1,0]
Statements 1 3 4 6 7 11 are true.</pre>
=={{header|Prolog}}==
Works with '''SWI-Prolog''' and '''library(clpfd)'''.
<
% 1. This is a numbered list of twelve statements.
L = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12],
Line 866 ⟶ 3,230:
my_write(_N, 0).
</syntaxhighlight>
{{out}}
<pre> ?- puzzle.
Statements 1 3 4 6 7 11 are true
Line 875 ⟶ 3,239:
Note: we choose to adapt the statement numbering to zero-based indexing in the constraintinfo lambda expressions but convert back to one-based on output.
The program uses brute force to generate all possible boolean values of the twelve statements
then checks if the actual value of the statements matches the proposed or matches apart from exactly one deviation.
Python's boolean type <tt>bool</tt>is a subclass of <tt>int</tt>, so boolean values True, False can be used as integers (1, 0, respectively) in numerical contexts.
This fact is used in the lambda expressions that use function sum.
<syntaxhighlight lang="python">
from itertools import product
#from pprint import pprint as pp
Line 916 ⟶ 3,283:
for stm in full + partial:
printer(*stm)</
{{out}}
Line 954 ⟶ 3,321:
1:T, 2:T, 3:F, 4:T, 5:F, 6:F, 7:T, 8:T, 9:T, 10:F, 11:F, 12:F</pre>
=={{header|
This question really begs to be done with <tt>amb</tt>
<syntaxhighlight lang="racket">
#lang racket
;; A quick `amb' implementation
(define failures null)
(define (fail)
(if (pair? failures) ((first failures)) (error "no more choices!")))
(define (amb/thunks choices)
(let/cc k (set! failures (cons k failures)))
(if (pair? choices)
(let ([choice (first choices)]) (set! choices (rest choices)) (choice))
(begin (set! failures (rest failures)) (fail))))
(define-syntax-rule (amb E ...) (amb/thunks (list (lambda () E) ...)))
(define (assert condition) (unless condition (fail)))
;; just to make things more fun
(define (⇔ x y) (assert (eq? x y)))
(require (only-in racket [and ∧] [or ∨] [implies ⇒] [xor ⊻] [not ¬]))
(define (count xs)
(let loop ([n 0] [xs xs])
(if (null? xs) n (loop (if (car xs) (add1 n) n) (cdr xs)))))
;; even more fun, make []s infix
(require (only-in racket [#%app r:app]))
(define-syntax (#%app stx)
(if (not (eq? #\[ (syntax-property stx 'paren-shape)))
(syntax-case stx () [(_ x ...) #'(r:app x ...)])
(syntax-case stx ()
;; extreme hack on next two cases, so it works for macros too.
[(_ x op y) (syntax-property #'(op x y) 'paren-shape #f)]
[(_ x op y op1 z) (free-identifier=? #'op #'op1)
(syntax-property #'(op x y z) 'paren-shape #f)])))
;; might as well do more
(define-syntax-rule (define-booleans all x ...)
(begin (define x (amb #t #f)) ...
(define all (list x ...))))
(define (puzzle)
(define-booleans all q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12)
;; 1. This is a numbered list of twelve statements.
[q1 ⇔ [12 = (length all)]]
;; 2. Exactly 3 of the last 6 statements are true.
[q2 ⇔ [3 = (count (take-right all 6))]]
;; 3. Exactly 2 of the even-numbered statements are true.
[q3 ⇔ [2 = (count (list q2 q4 q6 q8 q10 q12))]]
;; 4. If statement 5 is true, then statements 6 and 7 are both true.
[q4 ⇔ [q5 ⇒ [q6 ∧ q7]]]
;; 5. The 3 preceding statements are all false.
[q5 ⇔ (¬ [q2 ∨ q3 ∨ q4])]
;; 6. Exactly 4 of the odd-numbered statements are true.
[q6 ⇔ [4 = (count (list q1 q3 q5 q7 q9 q11))]]
;; 7. Either statement 2 or 3 is true, but not both.
[q7 ⇔ [q2 ⊻ q3]]
;; 8. If statement 7 is true, then 5 and 6 are both true.
[q8 ⇔ [q7 ⇒ (and q5 q6)]]
;; 9. Exactly 3 of the first 6 statements are true.
[q9 ⇔ [3 = (count (take all 3))]]
;; 10. The next two statements are both true.
[q10 ⇔ [q11 ∧ q12]]
;; 11. Exactly 1 of statements 7, 8 and 9 are true.
[q11 ⇔ [1 = (count (list q7 q8 q9))]]
;; 12. Exactly 4 of the preceding statements are true.
[q12 ⇔ [4 = (count (drop-right all 1))]]
;; done
(for/list ([i (in-naturals 1)] [q all] #:when q) i))
(puzzle)
;; -> '(1 3 4 6 7 11)
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2016.07}}
<syntaxhighlight lang="raku" line>sub infix:<→> ($protasis, $apodosis) { !$protasis or $apodosis }
my @tests =
{ .end == 12 and all(.[1..12]) === any(True, False) },
{ 3 == [+] .[7..12] },
{ 2 == [+] .[2,4...12] },
{ .[5] → all .[6,7] },
{ none .[2,3,4] },
{ 4 == [+] .[1,3...11] },
{ one .[2,3] },
{ .[7] → all .[5,6] },
{ 3 == [+] .[1..6] },
{ all .[11,12] },
{ one .[7,8,9] },
{ 4 == [+] .[1..11] },
;
my @solutions;
my @misses;
for [X] (True, False) xx 12 {
my @assert = Nil, |$_;
my @result = Nil, |@tests.map({ ?.(@assert) });
my @true = @assert.grep(?*, :k);
my @cons = (@assert Z=== @result).grep(!*, :k);
given @cons {
when 0 { push @solutions, "<{@true}> is consistent."; }
when 1 { push @misses, "<{@true}> implies { "¬" if !@result[~$_] }$_." }
}
}
.say for @solutions;
say "";
say "Near misses:";
.say for @misses;</syntaxhighlight>
{{out}}
<pre><1 3 4 6 7 11> is consistent.
Near misses:
<1 2 4 7 8 9> implies ¬8.
<1 2 4 7 9 10> implies ¬10.
<1 2 4 7 9 12> implies ¬12.
<1 3 4 6 7 9> implies ¬9.
<1 3 4 8 9> implies 7.
<1 4 6 8 9> implies ¬6.
<1 4 8 10 11 12> implies ¬12.
<1 4> implies 8.
<1 5 6 9 11> implies 8.
<1 5 8 10 11 12> implies ¬12.
<1 5 8 11> implies 12.
<1 5 8> implies 11.
<1 5> implies 8.
<4 8 10 11 12> implies 1.
<5 8 10 11 12> implies 1.
<5 8 11> implies 1.</pre>
=={{header|REXX}}==
===generalized logic===
<syntaxhighlight lang="rexx">/*REXX program solves the "Twelve Statement Puzzle". */
q=12; @stmt=right('statement',20) /*number of statements in the puzzle. */
m=0 /*[↓] statement one is TRUE by fiat.*/
do pass=1 for 2 /*find the maximum number of "trues". */
do e=0 for 2**(q-1); n = '1'right( x2b( d2x( e ) ), q-1, 0)
do b=1 for q /*define various bits in the number Q.*/
@.b=substr(n, b, 1) /*define a particular @ bit (in Q).*/
end /*b*/
if @.1 then if yeses(1, 1) \==1 then iterate
if @.2 then if yeses(7, 12) \==3 then iterate
if @.3 then if yeses(2, 12,2) \==2 then iterate
if @.4 then if yeses(5, 5) then if yeses(6, 7) \==2 then iterate
if @.5 then if yeses(2, 4) \==0 then iterate
if @.6 then if yeses(1, 12,2) \==4 then iterate
if @.7 then if yeses(2, 3) \==1 then iterate
if @.8 then if yeses(7, 7) then if yeses(5,6) \==2 then iterate
if @.9 then if yeses(1, 6) \==3 then iterate
if @.10 then if yeses(11,12) \==2 then iterate
if @.11 then if yeses(7, 9) \==1 then iterate
if @.12 then if yeses(1, 11) \==4 then iterate
g=yeses(1, 12)
if pass==1 then do; m=max(m,g); iterate; end
else if g\==m then iterate
do j=1 for q; z=substr(n, j, 1)
if z then say @stmt right(j, 2) " is " word('false true', 1 + z)
end /*tell*/
end /*e*/
end /*pass*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
yeses: parse arg L,H,B; #=0; do i=L to H by word(B 1, 1); #=#+@.i; end; return #</syntaxhighlight>
'''output'''
<pre>
statement 1 is true
statement 3 is true
Line 1,004 ⟶ 3,499:
===discrete logic===
<
q=12; @stmt=right('statement',20) /*number of statements in the puzzle. */
m=0 /*[↓] statement one is TRUE by fiat.*/
do pass=1 for 2 /*find the maximum number of "trues". */
do e=0 for 2**(q-1); n = '1'right( x2b( d2x( e ) ),
do
@.b=substr(n, b, 1) /*define a particular @ bit (in Q).*/
if @.1 then if \ @.1 then iterate
if @.2 then if @.7+@.8+@.9+@.10+@.11+@.12 \==3 then iterate
Line 1,026 ⟶ 3,518:
if @.10 then if \ (@.11 & @.12) then iterate
if @.11 then if @.7+@.8+@.9 \==1 then iterate
if @.12 then if
if pass==1 then do;
else if
do j=1 for q; z=substr(n, j, 1)
if z then say @stmt right(j, 2) " is " word('false true', 1+z)
end
end /*pass*/ /*stick a fork in it, we're all done. */</syntaxhighlight>
'''output''' is the same as the 1<sup>st</sup> version.
<br><br>
===optimized===
<
q=12; @stmt=right('statement',20) /*number of statements in the puzzle. */
m=0 /*[↓] statement one is TRUE by fiat.*/
do pass=1 for 2 /*find the maximum number of "trues". */
do e=0 for 2**(q-1); n = '1'right( x2b( d2x( e ) ),
/*▒▒▒▒ if @1 then
if @2 then if @7+@8+@9+@10+@11+@12 \==3 then iterate
if @3 then if @2+@4+@6+@8+@10+@12 \==2 then iterate
Line 1,060 ⟶ 3,549:
if @10 then if \ (@11 & @12) then iterate
if @11 then if @7+@8+@9 \==1 then iterate
if @12 then if
if pass==1 then do;
else if
do j=1 for q; z=substr(n, j, 1)
end /*j*/
end /*e*/
end /*pass*/ /*stick a fork in it, we're all done. */</syntaxhighlight>
'''output''' is the same as the 1<sup>st</sup> version.
<br><br>
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">constraints = [
->(st) { st.size == 12 },
->(st) { st.last(6).count(true) == 3 },
->(st) { st.each_slice(2).map(&:last).count(true) == 2 },
->(st) { st[4] ? (st[5] & st[6]) : true },
->(st) { st[1..3].none? },
->(st) { st.each_slice(2).map(&:first).count(true) == 4 },
->(st) { st[1] ^ st[2] },
->(st) { st[6] ? (st[4] & st[5]) : true },
->(st) { st.first(6).count(true) == 3 },
->(st) { st[10] & st[11] },
->(st) { st[6..8].one? },
->(st) { st[0,11].count(true) == 4 },
]
Result = Struct.new(:truths, :consistency)
results = [true, false].repeated_permutation(12).map do |truths|
Result.new(truths, constraints.zip(truths).map {|cn,truth| cn[truths] == truth })
end
puts "solution:",
results.find {|r| r.consistency.all? }.truths.to_s
puts "\nnear misses: "
near_misses = results.select {|r| r.consistency.count(false) == 1 }
near_misses.each do |r|
puts "missed by statement #{r.consistency.index(false) + 1}", r.truths.to_s
end</syntaxhighlight>
{{out}}
<pre>
solution:
[true, false, true, true, false, true, true, false, false, false, true, false]
near misses:
missed by statement 8
[true, true, false, true, false, false, true, true, true, false, false, false]
missed by statement 10
[true, true, false, true, false, false, true, false, true, true, false, false]
missed by statement 12
[true, true, false, true, false, false, true, false, true, false, false, true]
missed by statement 9
[true, false, true, true, false, true, true, false, true, false, false, false]
missed by statement 7
[true, false, true, true, false, false, false, true, true, false, false, false]
missed by statement 6
[true, false, false, true, false, true, false, true, true, false, false, false]
missed by statement 12
[true, false, false, true, false, false, false, true, false, true, true, true]
missed by statement 8
[true, false, false, true, false, false, false, false, false, false, false, false]
missed by statement 8
[true, false, false, false, true, true, false, false, true, false, true, false]
missed by statement 12
[true, false, false, false, true, false, false, true, false, true, true, true]
missed by statement 12
[true, false, false, false, true, false, false, true, false, false, true, false]
missed by statement 11
[true, false, false, false, true, false, false, true, false, false, false, false]
missed by statement 8
[true, false, false, false, true, false, false, false, false, false, false, false]
missed by statement 1
[false, false, false, true, false, false, false, true, false, true, true, true]
missed by statement 1
[false, false, false, false, true, false, false, true, false, true, true, true]
missed by statement 1
[false, false, false, false, true, false, false, true, false, false, true, false]
</pre>
=={{header|Scala}}==
===Imperative Programming (Ugly)===
{{trans|Java}}
<syntaxhighlight lang="scala">class LogicPuzzle {
val s = new Array[Boolean](13)
var count = 0
def check2: Boolean = {
var count = 0
for (k <- 7 to 12) if (s(k)) count += 1
s(2) == (count == 3)
}
def check3: Boolean = {
var count = 0
for (k <- 2 to 12 by 2) if (s(k)) count += 1
s(3) == (count == 2)
}
def check4: Boolean = s(4) == (!s(5) || s(6) && s(7))
def check5: Boolean = s(5) == (!s(2) && !s(3) && !s(4))
def check6: Boolean = {
var count = 0
for (k <- 1 to 11 by 2) if (s(k)) count += 1
s(6) == (count == 4)
}
def check7: Boolean = s(7) == ((s(2) || s(3)) && !(s(2) && s(3)))
def check8: Boolean = s(8) == (!s(7) || s(5) && s(6))
def check9: Boolean = {
var count = 0
for (k <- 1 to 6) if (s(k)) count += 1
s(9) == (count == 3)
}
def check10: Boolean = s(10) == (s(11) && s(12))
def check11: Boolean = {
var count = 0
for (k <- 7 to 9) if (s(k)) count += 1
s(11) == (count == 1)
}
def check12: Boolean = {
var count = 0
for (k <- 1 to 11) if (s(k)) count += 1
s(12) == (count == 4)
}
def check(): Unit = {
if (check2 && check3 && check4 && check5 && check6 && check7 && check8 && check9 && check10 && check11 && check12) {
for (k <- 1 to 12) if (s(k)) print(k + " ")
println()
count += 1
}
}
def recurseAll(k: Int): Unit = {
if (k == 13) check()
else {
s(k) = false
recurseAll(k + 1)
s(k) = true
recurseAll(k + 1)
}
}
}
object LogicPuzzle extends App {
val p = new LogicPuzzle
p.s(1) = true
p.recurseAll(2)
println()
println(s"${p.count} Solutions found.")
}</syntaxhighlight>
{{Out}}See it in running in your browser by [https://scastie.scala-lang.org/XaRsz8gOQxavQ5rwMxi9ZA Scastie (JVM)] or
by [https://scalafiddle.io/sf/x73tnT6/1 ScalaFiddle (JavaScript)].
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">var conditions = [
{ false },
{|a| a.len == 13 },
{|a| [a[7..12]].count(true) == 3 },
{|a| [a[2..12 `by` 2]].count(true) == 2 },
{|a| a[5] ? (a[6] && a[7]) : true },
{|a| !a[2] && !a[3] && !a[4] },
{|a| [a[1..11 `by` 2]].count(true) == 4 },
{|a| a[2] == true^a[3] },
{|a| a[7] ? (a[5] && a[6]) : true },
{|a| [a[1..6]].count(true) == 3 },
{|a| [a[11,12]].count(true) == 2 },
{|a| [a[7..9]].count(true) == 1 },
{|a| [a[1..11]].count(true) == 4 },
]
func miss(args) {
1..12 -> grep {|i| conditions[i](args) != args[i] }
}
for k in (^(1<<12)) {
var t = ("0%012b" % k -> chars.map {|bit| bit == '1' })
var no = miss(t)
no.len == 0 && say "Solution: true statements are #{1..12->grep{t[_]}.join(' ')}"
no.len == 1 && say "1 miss (#{no[0]}): true statements are #{1..12->grep{t[_]}.join(' ')}"
}</syntaxhighlight>
{{out}}
<pre>
1 miss (1): true statements are 5 8 11
1 miss (1): true statements are 5 8 10 11 12
1 miss (1): true statements are 4 8 10 11 12
1 miss (8): true statements are 1 5
1 miss (11): true statements are 1 5 8
1 miss (12): true statements are 1 5 8 11
1 miss (12): true statements are 1 5 8 10 11 12
1 miss (8): true statements are 1 5 6 9 11
1 miss (8): true statements are 1 4
1 miss (12): true statements are 1 4 8 10 11 12
1 miss (6): true statements are 1 4 6 8 9
1 miss (7): true statements are 1 3 4 8 9
Solution: true statements are 1 3 4 6 7 11
1 miss (9): true statements are 1 3 4 6 7 9
1 miss (12): true statements are 1 2 4 7 9 12
1 miss (10): true statements are 1 2 4 7 9 10
1 miss (8): true statements are 1 2 4 7 8 9
</pre>
=={{header|Swift Playground}}==
{{works with|Swift|5.2}}
<pre>
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)")
}
}
</pre>
----
Solution found! True are: [1, 3, 4, 6, 7, 11]
=={{header|Tcl}}==
{{works with|Tcl|8.6}} <!-- but not 8.6b3; the lmap command post-dates that release -->
<
# Function to evaluate the truth of a statement
Line 1,149 ⟶ 3,954:
foreach {state j} $differ {
puts "almost found\t[renderstate $state] \u21d2 [expr {[lindex $state $j-1]?"\u00ac":{}}]S($j)"
}</
{{out}}
<pre>
Line 1,169 ⟶ 3,974:
almost found (S(1)?S(2)?¬S(3)?S(4)?¬S(5)?¬S(6)?S(7)?¬S(8)?S(9)?S(10)?¬S(11)?¬S(12)) ? ¬S(10)
almost found (S(1)?S(2)?¬S(3)?S(4)?¬S(5)?¬S(6)?S(7)?S(8)?S(9)?¬S(10)?¬S(11)?¬S(12)) ? ¬S(8)
</pre>
=={{header|TXR}}==
<syntaxhighlight lang="txrlisp">(defmacro defconstraints (name size-name (var) . forms)
^(progn (defvar ,size-name ,(length forms))
(defun ,name (,var)
(list ,*forms))))
(defconstraints con con-count (s)
(= (length s) con-count) ;; tautology
(= (countq t [s -6..t]) 3)
(= (countq t (mapcar (op if (evenp @1) @2) (range 1) s)) 2)
(if [s 4] (and [s 5] [s 6]) t)
(none [s 1..3])
(= (countq t (mapcar (op if (oddp @1) @2) (range 1) s)) 4)
(and (or [s 1] [s 2]) (not (and [s 1] [s 2])))
(if [s 6] (and [s 4] [s 5]) t)
(= (countq t [s 0..6]) 3)
(and [s 10] [s 11])
(= (countq t [s 6..9]) 1)
(= (countq t [s 0..con-count]) 4))
(defun true-indices (truths)
(mappend (do if @1 ^(,@2)) truths (range 1)))
(defvar results
(append-each ((truths (rperm '(nil t) con-count)))
(let* ((vals (con truths))
(consist [mapcar eq truths vals])
(wrong-count (countq nil consist))
(pos-wrong (+ 1 (or (posq nil consist) -2))))
(cond
((zerop wrong-count)
^((:----> ,*(true-indices truths))))
((= 1 wrong-count)
^((:close ,*(true-indices truths) (:wrong ,pos-wrong))))))))
(each ((r results))
(put-line `@r`))</syntaxhighlight>
{{out}}
<pre>close 5 8 11 (wrong 1)
close 1 5 (wrong 8)
close 1 5 8 (wrong 11)
close 1 5 8 11 (wrong 12)
close 1 5 8 10 11 12 (wrong 12)
close 1 5 6 9 11 (wrong 8)
close 1 3 4 8 9 (wrong 7)
----> 1 3 4 6 7 11
close 1 3 4 6 7 9 (wrong 9)
close 1 2 4 7 9 12 (wrong 12)
close 1 2 4 7 9 10 (wrong 10)
close 1 2 4 7 8 9 (wrong 8)</pre>
=={{header|uBasic/4tH}}==
{{trans|BBC Basic}}
<syntaxhighlight lang="text">S = 12
For T = 0 To (2^S)-1
For I = 1 To 12
Push T, 2^(I-1) : Gosub 100
@(I) = Pop() # 0
Next
REM Test consistency:
@(101) = @(1) = (S = 12)
@(102) = @(2) = ((@(7)+@(8)+@(9)+@(10)+@(11)+@(12)) = 3)
@(103) = @(3) = ((@(2)+@(4)+@(6)+@(8)+@(10)+@(12)) = 2)
@(104) = @(4) = ((@(5)=0) + (@(6) * @(7)) # 0)
@(105) = @(5) = ((@(2)=0) * (@(3)=0) * (@(4)=0))
@(106) = @(6) = ((@(1)+@(3)+@(5)+@(7)+@(9)+@(11)) = 4)
@(107) = @(7) = ((@(2) + @(3)) = 1)
@(108) = @(8) = ((@(7)=0) + (@(5) * @(6)) # 0)
@(109) = @(9) = ((@(1)+@(2)+@(3)+@(4)+@(5)+@(6)) = 3)
@(110) = @(10) = (@(11) * @(12))
@(111) = @(11) = ((@(7)+@(8)+@(9)) = 1)
@(112) = @(12) = ((@(1)+@(2)+@(3)+@(4)+@(5)+@(6)+@(7)+@(8)+@(9)+@(10)+@(11)) = 4)
Q = 0
For I = 101 To 112
Q = Q + @(I)
Next
If (Q = 11) Then
Print "Near miss with statements ";
For I = 1 To 12
If @(I) Then
Print I; " ";
Endif
If (@(I+100) = 0) Then
M = I
Endif
Next
Print "true (failed " ;M; ")."
Endif
If (Q = 12) Then
Print "Solution! with statements ";
For I = 1 TO 12
If @(I) Then
Print I; " ";
Endif
Next
Print "true."
Endif
Next
End
100 Rem a hard way to do a binary AND
q = Pop() : p = Pop() : Push 0
Do While (p * q) * (Tos() = 0)
Push Pop() + (p % 2) * (q % 2)
p = p / 2
q = q / 2
Loop
Return</syntaxhighlight>
Output:
<pre>Near miss with statements 1 4 true (failed 8).
Near miss with statements 1 5 true (failed 8).
Near miss with statements 1 5 8 true (failed 11).
Near miss with statements 1 3 4 6 7 9 true (failed 9).
Near miss with statements 1 3 4 8 9 true (failed 7).
Near miss with statements 1 4 6 8 9 true (failed 6).
Near miss with statements 1 2 4 7 8 9 true (failed 8).
Near miss with statements 1 2 4 7 9 10 true (failed 10).
Solution! with statements 1 3 4 6 7 11 true.
Near miss with statements 5 8 11 true (failed 1).
Near miss with statements 1 5 8 11 true (failed 12).
Near miss with statements 1 5 6 9 11 true (failed 8).
Near miss with statements 1 2 4 7 9 12 true (failed 12).
Near miss with statements 4 8 10 11 12 true (failed 1).
Near miss with statements 1 4 8 10 11 12 true (failed 12).
Near miss with statements 5 8 10 11 12 true (failed 1).
Near miss with statements 1 5 8 10 11 12 true (failed 12).</pre>
=={{header|Uiua}}==
{{works with|Uiua|0.12.0-dev.1}}
Defined the rules as functions to avoid the main loop devolving into line noise :-)
<syntaxhighlight lang="uiua">
Even ← =1◿2⇡⧻ # nb indexes are zero-based
S₁ ← =12⧻ # Total is always twelve (don't test)
S₂ ← =3⧻⊚↘6 # Three of last six are true
S₃ ← =2⧻⊚⊏⊚Even. # Exactly two even rules are true
S₄ ← ⨬(⋅1|/↧)⊢.⊏4_5_6 # If 5 is true so must 6 and 7 be.
S₅ ← /↧¬⊏[1 2 3] # 2, 3, 4 are all false
S₆ ← =4⧻⊚⊏⊚¬Even. # Four odd rules are true
S₇ ← =1/+⊏1_2 # 2 xor 3
S₈ ← ⨬(⋅1|/↧)⊢.⇌⊏4_5_6 # If 7 is true so are 6 and 5
S₉ ← =3⧻⊚↙6 # Three of first six are true
S₁₀ ← /↧⊏10_11 # 11 and 12 are both true
S₁₁ ← =1/+⊏6_7_8 # Exactly one of 7, 8, 9 is true
S₁₂ ← =4/+↘¯1 # Exactly four of above are true
⋯+1×2⇡2048 # Generate bits to represent all states of rules 2-12
≡(
# Test each rule against the data and concatenate
⟜[⊃(S₁|S₂|S₃|S₄|S₅|S₆|S₇|S₈|S₉|S₁₀|S₁₁|S₁₂)]
⊟∩□:⊙(⊚⌵-). # Append hit-count
)
°⊟↙2⊕□≡(◇⧻⊢). # Partition by fit, keep only hits and near-misses
&p$"Succeeds when the following rules are true:\n_\n"+1◇⊚⊢↘1◇⊢
⊏⍏≡⊢.°□ # Sort misses
&p"Near Misses:"
≡(&p$"Fails at _\t _"⊃(+1◇⊢⊢|+1⊚°□⊢↘1))
</syntaxhighlight>
{{out}}
<pre>
Succeeds when the following rules are true:
[1 3 4 6 7 11]
Near Misses:
Fails at 6 [1 4 6 8 9]
Fails at 7 [1 3 4 8 9]
Fails at 8 [1 4]
Fails at 8 [1 5]
Fails at 8 [1 2 4 7 8 9]
Fails at 8 [1 5 6 9 11]
Fails at 9 [1 3 4 6 7 9]
Fails at 10 [1 2 4 7 9 10]
Fails at 11 [1 5 8]
Fails at 12 [1 5 8 11]
Fails at 12 [1 2 4 7 9 12]
Fails at 12 [1 4 8 10 11 12]
Fails at 12 [1 5 8 10 11 12]
</pre>
=={{header|VBA}}==
{{trans|Phix}}<syntaxhighlight lang="vb">Public s As String '-- (eg "101101100010")
Public t As Integer '-- scratch
Function s1()
s1 = Len(s) = 12
End Function
Function s2()
t = 0
For i = 7 To 12
t = t - (Mid(s, i, 1) = "1")
Next i
s2 = t = 3
End Function
Function s3()
t = 0
For i = 2 To 12 Step 2
t = t - (Mid(s, i, 1) = "1")
Next i
s3 = t = 2
End Function
Function s4()
s4 = Mid(s, 5, 1) = "0" Or ((Mid(s, 6, 1) = "1" And Mid(s, 7, 1) = "1"))
End Function
Function s5()
s5 = Mid(s, 2, 1) = "0" And Mid(s, 3, 1) = "0" And Mid(s, 4, 1) = "0"
End Function
Function s6()
t = 0
For i = 1 To 12 Step 2
t = t - (Mid(s, i, 1) = "1")
Next i
s6 = t = 4
End Function
Function s7()
s7 = Mid(s, 2, 1) <> Mid(s, 3, 1)
End Function
Function s8()
s8 = Mid(s, 7, 1) = "0" Or (Mid(s, 5, 1) = "1" And Mid(s, 6, 1) = "1")
End Function
Function s9()
t = 0
For i = 1 To 6
t = t - (Mid(s, i, 1) = "1")
Next i
s9 = t = 3
End Function
Function s10()
s10 = Mid(s, 11, 1) = "1" And Mid(s, 12, 1) = "1"
End Function
Function s11()
t = 0
For i = 7 To 9
t = t - (Mid(s, i, 1) = "1")
Next i
s11 = t = 1
End Function
Function s12()
t = 0
For i = 1 To 11
t = t - (Mid(s, i, 1) = "1")
Next i
s12 = t = 4
End Function
Public Sub twelve_statements()
For i = 0 To 2 ^ 12 - 1
s = Right(CStr(WorksheetFunction.Dec2Bin(64 + i \ 128)), 5) _
& Right(CStr(WorksheetFunction.Dec2Bin(256 + i Mod 128)), 7)
For b = 1 To 12
Select Case b
Case 1: If s1 <> (Mid(s, b, 1) = "1") Then Exit For
Case 2: If s2 <> (Mid(s, b, 1) = "1") Then Exit For
Case 3: If s3 <> (Mid(s, b, 1) = "1") Then Exit For
Case 4: If s4 <> (Mid(s, b, 1) = "1") Then Exit For
Case 5: If s5 <> (Mid(s, b, 1) = "1") Then Exit For
Case 6: If s6 <> (Mid(s, b, 1) = "1") Then Exit For
Case 7: If s7 <> (Mid(s, b, 1) = "1") Then Exit For
Case 8: If s8 <> (Mid(s, b, 1) = "1") Then Exit For
Case 9: If s9 <> (Mid(s, b, 1) = "1") Then Exit For
Case 10: If s10 <> (Mid(s, b, 1) = "1") Then Exit For
Case 11: If s11 <> (Mid(s, b, 1) = "1") Then Exit For
Case 12: If s12 <> (Mid(s, b, 1) = "1") Then Exit For
End Select
If b = 12 Then Debug.Print s
Next
Next
End Sub</syntaxhighlight>{{out}}
<pre>Found solution:101101100010</pre>
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Conv, Fmt
var predicates = [
Fn.new { |s| s.count == 13 }, // indexing starts at 0 but first bit ignored
Fn.new { |s| (7..12).count { |i| s[i] == "1" } == 3 },
Fn.new { |s| [2, 4, 6, 8, 10, 12].count { |i| s[i] == "1" } == 2 },
Fn.new { |s| s[5] == "0" || (s[6] == "1" && s[7] == "1") },
Fn.new { |s| s[2] == "0" && s[3] == "0" && s[4] == "0" },
Fn.new { |s| [1, 3, 5, 7, 9, 11].count { |i| s[i] == "1" } == 4 },
Fn.new { |s| Conv.itob(Conv.btoi(s[2] == "1") ^ Conv.btoi(s[3] == "1")) },
Fn.new { |s| s[7] == "0" || (s[5] == "1" && s[6] == "1") },
Fn.new { |s| (1..6).count { |i| s[i] == "1" } == 3 },
Fn.new { |s| s[11] == "1" && s[12] == "1" },
Fn.new { |s| (7..9).count { |i| s[i] == "1" } == 1 },
Fn.new { |s| (1..11).count { |i| s[i] == "1" } == 4 }
]
var show = Fn.new { |s, indent|
if (indent) System.write(" ")
for (i in 0...s.count) if (s[i] == "1") System.write("%(i) ")
System.print()
}
System.print("Exact hits:")
for (i in 0..4095) {
var s = Fmt.swrite("$013b", i)
var j = 1
if (predicates.all { |pred|
var res = pred.call(s) == (s[j] == "1")
j = j + 1
return res
}) show.call(s, true)
}
System.print("\nNear misses:")
for (i in 0..4095) {
var s = Fmt.swrite("$013b", i)
var j = 1
var c = predicates.count { |pred|
var res = pred.call(s) == (s[j] == "1")
j = j + 1
return res
}
if (c == 11) {
var k = 1
for (pred in predicates) {
if (pred.call(s) != (s[k] == "1") ) break
k = k + 1
}
Fmt.write(" (Fails at statement $2d) ", k)
show.call(s, false)
}
}</syntaxhighlight>
{{out}}
<pre>
Exact hits:
1 3 4 6 7 11
Near misses:
(Fails at statement 1) 5 8 11
(Fails at statement 1) 5 8 10 11 12
(Fails at statement 1) 4 8 10 11 12
(Fails at statement 8) 1 5
(Fails at statement 11) 1 5 8
(Fails at statement 12) 1 5 8 11
(Fails at statement 12) 1 5 8 10 11 12
(Fails at statement 8) 1 5 6 9 11
(Fails at statement 8) 1 4
(Fails at statement 12) 1 4 8 10 11 12
(Fails at statement 6) 1 4 6 8 9
(Fails at statement 7) 1 3 4 8 9
(Fails at statement 9) 1 3 4 6 7 9
(Fails at statement 12) 1 2 4 7 9 12
(Fails at statement 10) 1 2 4 7 9 10
(Fails at statement 8) 1 2 4 7 8 9
</pre>
=={{header|XPL0}}==
{{trans|ALGOL W}}
<syntaxhighlight lang "XPL0"> \We have 12 statements to determine the truth/falsehood of (see task).
integer Stmt( 1+12 ), Expected( 1+12 );
\Logical-to-integer utility procedure
function ToInteger; int V ; return if V # 0 then 1 else 0;
\Procedure to determine whether the statements are true or not
procedure FindExpectedValues;
begin
Expected( 1 ) := true;
Expected( 2 ) := 3 = ( ToInteger( Stmt( 7 ) ) + ToInteger( Stmt( 8 ) )
+ ToInteger( Stmt( 9 ) ) + ToInteger( Stmt( 10 ) )
+ ToInteger( Stmt( 11 ) ) + ToInteger( Stmt( 12 ) )
);
Expected( 3 ) := 2 = ( ToInteger( Stmt( 2 ) ) + ToInteger( Stmt( 4 ) )
+ ToInteger( Stmt( 6 ) ) + ToInteger( Stmt( 8 ) )
+ ToInteger( Stmt( 10 ) ) + ToInteger( Stmt( 12 ) )
);
Expected( 4 ) := ( not Stmt( 5 ) ) or ( Stmt( 6 ) and Stmt( 7 ) );
Expected( 5 ) := not ( Stmt( 2 ) or Stmt( 3 ) or Stmt( 4 ) );
Expected( 6 ) := 4 = ( ToInteger( Stmt( 1 ) ) + ToInteger( Stmt( 3 ) )
+ ToInteger( Stmt( 5 ) ) + ToInteger( Stmt( 7 ) )
+ ToInteger( Stmt( 9 ) ) + ToInteger( Stmt( 11 ) )
);
Expected( 7 ) := Stmt( 2 ) # Stmt( 3 );
Expected( 8 ) := ( not Stmt( 7 ) ) or ( Stmt( 5 ) and Stmt( 6 ) );
Expected( 9 ) := 3 = ( ToInteger( Stmt( 1 ) ) + ToInteger( Stmt( 2 ) )
+ ToInteger( Stmt( 3 ) ) + ToInteger( Stmt( 4 ) )
+ ToInteger( Stmt( 5 ) ) + ToInteger( Stmt( 6 ) )
);
Expected( 10 ) := Stmt( 11 ) and Stmt( 12 );
Expected( 11 ) := 1 = ( ToInteger( Stmt( 7 ) )
+ ToInteger( Stmt( 8 ) )
+ ToInteger( Stmt( 9 ) )
);
Expected( 12 ) := 4 = ( ToInteger( Stmt( 1 ) ) + ToInteger( Stmt( 2 ) )
+ ToInteger( Stmt( 3 ) ) + ToInteger( Stmt( 4 ) )
+ ToInteger( Stmt( 5 ) ) + ToInteger( Stmt( 6 ) )
+ ToInteger( Stmt( 7 ) ) + ToInteger( Stmt( 8 ) )
+ ToInteger( Stmt( 9 ) ) + ToInteger( Stmt( 10 ) )
+ ToInteger( Stmt( 11 ) )
);
end; \FindExpectedValues
\Clearly, statement 1 is true. However to enumerate the near
\ solutions, we need to consider "solutions" where statement 1 is false.
\We iterate through the possibilities for the statements,
\ looking for a non-contradictory set of values.
\We print the solutions with allowedContradictions contradictions
procedure PrintSolutions ( AllowedContradictions, Heading ) ;
integer AllowedContradictions, Heading;
integer Wrong( 1+12 );
integer Solution, N, Incorrect, DPos, S;
begin
Text(0, Heading ); CrLf(0);
Text(0, " 1 2 3 4 5 6 7 8 9 10 11 12^m^j" );
Text(0, " ====================================^m^j" );
\There are 12 statements, so we have 2^12 possible combinations
for Solution := 1 to 4096 do begin
\Convert the number to the set of true/false values
N := Solution;
for DPos := 1 to 12 do begin
Stmt( DPos ) := (N & 1) # 0; \very odd
N := N / 2;
end; \for_DPos
\Get the expected values of the statements based on suggested values
FindExpectedValues;
\Count contradictions. If the required number, print solution
Incorrect := 0;
for DPos := 1 to 12 do begin
Wrong( DPos ) := Expected( DPos ) # Stmt( DPos );
Incorrect := Incorrect + ToInteger( Wrong( DPos ) );
end; \for_DPos
if Incorrect = AllowedContradictions then begin
\Have a solution
Text(0, " " );
for S := 1 to 12 do begin
Text(0, " ");
Text(0, if Stmt( S ) then "T" else "-");
Text(0, if Wrong( S ) then "*" else " ");
end;
CrLf(0);
end;
end; \for_solution
end; \PrintSolutions
begin
\Find complete solutions
PrintSolutions( 0, "Solutions" );
\Find near solutions
PrintSolutions( 1, "Near solutions (incorrect values marked ^"*^")" );
end</syntaxhighlight>
{{out}}
<pre>
Solutions
1 2 3 4 5 6 7 8 9 10 11 12
====================================
T - T T - T T - - - T -
Near solutions (incorrect values marked "*")
1 2 3 4 5 6 7 8 9 10 11 12
====================================
T - - T - - - -* - - - -
T - - - T - - -* - - - -
T - - - T - - T - - -* -
T - T T - T T - T* - - -
T - T T - - -* T T - - -
T - - T - T* - T T - - -
T T - T - - T T* T - - -
T T - T - - T - T T* - -
-* - - - T - - T - - T -
T - - - T - - T - - T -*
T - - - T T - -* T - T -
T T - T - - T - T - - T*
-* - - T - - - T - T T T
T - - T - - - T - T T T*
-* - - - T - - T - T T T
T - - - T - - T - T T T*
</pre>
=={{header|Yabasic}}==
{{trans|Phix}}
<syntaxhighlight lang="yabasic">sub s1() return len(s$)=12 end sub
sub s2() local t, i : t=0 : for i=7 to 12 : t = t + (mid$(s$, i, 1) <> "0") : next : return t=3 end sub
sub s3() local t, i : t=0 : for i=2 to 12 step 2 : t = t + (mid$(s$, i, 1) <> "0") : next : return t=2 end sub
sub s4() return mid$(s$, 5, 1) = "0" or (mid$(s$, 6, 1) <> "0" and mid$(s$, 7, 1) <> "0") end sub
sub s5() return mid$(s$, 2, 1) = "0" and mid$(s$, 3, 1) = "0" and mid$(s$, 4, 1) = "0" end sub
sub s6() local t, i : t=0 : for i=1 to 12 step 2 : t = t + mid$(s$, i, 1) <> "0" : next : return t=4 end sub
sub s7() return mid$(s$, 2, 1) <> mid$(s$, 3, 1) end sub
sub s8() return mid$(s$, 7, 1) = "0" or (mid$(s$, 5, 1) <> "0" and mid$(s$, 6, 1) <> "0") end sub
sub s9() local t, i : t=0 : for i=1 to 6 : t = t + mid$(s$, i, 1) <> "0" : next : return t=3 end sub
sub s10() return mid$(s$, 11, 1) <> "0" and mid$(s$, 12, 1) <> "0" end sub
sub s11() local t, i : t=0 : for i=7 to 9 : t = t + mid$(s$, i, 1) <> "0" : next : return t=1 end sub
sub s12() local t, i : t=0 : for i=1 to 11 : t = t + mid$(s$, i, 1) <> "0" : next : return t=4 end sub
dim r$(12)
for b=1 to 12
r$(b) = "s"+str$(b)
next
for i=0 to 2^12-1
s$ = right$("000000000000" + bin$(i), 12)
for b=1 to 12
if execute(r$(b)) <> (mid$(s$, b, 1) <> "0") break
if b=12 print s$
next
next</syntaxhighlight>
=={{header|zkl}}==
<syntaxhighlight lang="zkl">var statements; // list of 13 Bools, statements[0] is garbage to make 1 based
fcn s0 { False } // dummy for padding
fcn s1 { True }
fcn s2 { statements[-6,*].filter().len()==3 }
fcn s3 { [2..12,2].apply(statements.get).filter().len()==2 }
fcn s4 { if(statements[5]) statements[6]==statements[7]==True else True }
fcn s5 { statements[2,3].filter().len()==0 }
fcn s6 { [1..12,2].apply(statements.get).filter().len()==4 }
fcn s7 { statements[2]!=statements[3] }
fcn s8 { if(statements[7]) statements[5]==statements[6]==True else True }
fcn s9 { statements[1,6].filter().len()==3 }
fcn s10{ statements[11]==statements[12]==True }
fcn s11{ statements[7,3].filter().len()==1 }
fcn s12{ statements[1,11].filter().len()==4 }
filters:=T(s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12);
foreach n in ((2).pow(12)){ // 4k
// 5-->"0000000000101"-->("0","0"..."1")-->(F,F,...T)
statements="%013.2B".fmt(n).split("").apply('==("1"));
r:=filters.run(True); // and return list of results
if(r==statements) print("<<<<<<<<<<<<<<<<Solution");
else{
diff:=r.zipWith('!=,statements);
if(diff.sum(0)==1) print("Diff @",diff.filter1n());
}
}
fcn print(msg){
(12).pump(List,'wrap(n){ statements[n] and n or Void.Skip })
.concat(",").println(" : ",vm.pasteArgs());
}</syntaxhighlight>
{{out}}
<pre>
5,8,11 : Diff @1
5,8,10,11,12 : Diff @1
4,8,10,11,12 : Diff @1
1,5 : Diff @8
1,5,8 : Diff @11
1,5,8,11 : Diff @12
1,5,8,10,11,12 : Diff @12
1,5,6,9,11 : Diff @8
1,4 : Diff @8
1,4,8,10,11,12 : Diff @12
1,4,6,8,9 : Diff @6
1,3,4,8,9 : Diff @7
1,3,4,6,7,11 : <<<<<<<<<<<<<<<<Solution
1,3,4,6,7,9 : Diff @9
1,2,4,7,9,12 : Diff @12
1,2,4,7,9,10 : Diff @10
1,2,4,7,8,9 : Diff @8
</pre>
|