83 lines
3 KiB
Text
83 lines
3 KiB
Text
\( Solve the "Twelve Statements" puzzle
|
|
See https://rosettacode.org/wiki/Twelve_statements
|
|
Emphasis is on unterstandability.
|
|
\)
|
|
main (p):+
|
|
\ uses presentation syntax
|
|
for r = give bit permutations 12
|
|
if is solution r
|
|
print 'Found,', join r
|
|
tell result r as sentences
|
|
|
|
\( Function to evaluate the setting in the row (s)
|
|
True if the new booleans in (n) are the same as in (s)
|
|
There are more tricky variants, but this is easy to debug
|
|
\)
|
|
is solution (s):
|
|
n =: new row size s.Count
|
|
n[1] =: s.Count = 12
|
|
n[2] =: in s exactly 3 of 12, 11, 10, 9, 8, 7
|
|
n[3] =: in s exactly 2 of 2, 4, 6, 8, 10, 12
|
|
n[4] =: in s if 5 then 6 and 7
|
|
n[5] =: in s exactly 0 of 4, 3, 2
|
|
n[6] =: in s exactly 4 of 1, 3, 5, 7, 9, 11
|
|
n[7] =: in s exactly 1 of 2, 3
|
|
n[8] =: in s if 7 then 5 and 6
|
|
n[9] =: in s exactly 3 of 1, 2, 3, 4, 5, 6
|
|
n[10] =: in s exactly 2 of 11, 12
|
|
n[11] =: in s exactly 1 of 7, 8, 9
|
|
n[12] =: in s exactly 4 of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
|
|
|
|
return (row n as tuple) = (row s as tuple)
|
|
|
|
\ In row (s), exactly (n) of the elements given by (list) are true
|
|
in (s) exactly (n) of (list):
|
|
?# i =: tuple list give values
|
|
? s[i] \ if true
|
|
n =- 1
|
|
:> n = 0
|
|
|
|
\ logical implication
|
|
in (s) if (a) then (b) and (c):
|
|
? s[a]
|
|
:> s[b] & s[c]
|
|
:> ?+
|
|
|
|
\( Scan function to supoly a row of (n) boolean values
|
|
Relays to a scan to give all bit patterns as integers
|
|
and converts to a row of booleans.
|
|
\)
|
|
give bit permutations (n):
|
|
v =: from 0 upto 2^n - 1 \ call scan function
|
|
? $ = () \ done ?
|
|
:> \ yes, return void
|
|
\ creation of a new row is cheap, no need to reuse one
|
|
s =: new row size n
|
|
?# i =: from 1 upto n \ check each bit
|
|
s[i] =: integer v bit is set i-1 \ boolean
|
|
:> s
|
|
|
|
\( Tell true and false sentenes
|
|
A string literal is used for better readablilty
|
|
\)
|
|
tell result (res) as sentences:
|
|
\ create a tuple of text lines by successive accumulation
|
|
ps =: " 1. This is a numbered list of twelve statements."
|
|
ps =, " 2. Exactly 3 of the last 6 statements are true."
|
|
ps =, " 3. Exactly 2 of the even-numbered statements are true."
|
|
ps =, " 4. If statement 5 is true, then statements 6 and 7 are both true."
|
|
ps =, " 5. The 3 preceding statements are all false."
|
|
ps =, " 6. Exactly 4 of the odd-numbered statements are true."
|
|
ps =, " 7. Either statement 2 or 3 is true, but not both."
|
|
ps =, " 8. If statement 7 is true, then 5 and 6 are both true."
|
|
ps =, " 9. Exactly 3 of the first 6 statements are true."
|
|
ps =, "10. The next two statements are both true."
|
|
ps =, "11. Exactly 1 of statements 7, 8 and 9 are true."
|
|
ps =, "12. Exactly 4 of the preceding statements are true."
|
|
|
|
?# i =: res::give keys
|
|
? res[i]
|
|
v =: ' true:'
|
|
|
|
|
v =: 'false;'
|
|
print v, ps[i]
|