Twelve statements: Difference between revisions
Content added Content deleted
(→{{header|Python}}: Add implementation.) |
(Go solution) |
||
Line 21: | Line 21: | ||
Extra credit: also print out a table of near misses, that is, solutions that are contradicted by only a single statement. |
Extra credit: also print out a table of near misses, that is, solutions that are contradicted by only a single statement. |
||
=={{header|Go}}== |
|||
<lang go>package main |
|||
import "fmt" |
|||
// its' not too much more work to check all the permutations concurrently |
|||
var solution = make(chan int) |
|||
var nearMiss = make(chan int) |
|||
var done = make(chan bool) |
|||
func main() { |
|||
// iterate and use the bits as the permutation |
|||
for i := 0; i < 4096; i++ { |
|||
go checkPerm(i) |
|||
} |
|||
// collect the misses and list them after the complete solution(s) |
|||
var ms []int |
|||
for i := 0; i < 4096; { |
|||
select { |
|||
case <-done: |
|||
i++ |
|||
case s := <-solution: |
|||
print12("solution", s) |
|||
case m := <-nearMiss: |
|||
ms = append(ms, m) |
|||
} |
|||
} |
|||
for _, m := range ms { |
|||
print12("near miss", m) |
|||
} |
|||
} |
|||
func print12(label string, bits int) { |
|||
fmt.Print(label, ":") |
|||
for i := 1; i <= 12; i++ { |
|||
if bits&1 == 1 { |
|||
fmt.Print(" ", i) |
|||
} |
|||
bits >>= 1 |
|||
} |
|||
fmt.Println() |
|||
} |
|||
func checkPerm(tz int) { |
|||
// closure returns true if tz bit corresponding to |
|||
// 1-based statement number is 1. |
|||
ts := func(n uint) bool { |
|||
return tz>>(n-1)&1 == 1 |
|||
} |
|||
// variadic closure returns number of statements listed as arguments |
|||
// which have corresponding tz bit == 1. |
|||
ntrue := func(xs ...uint) int { |
|||
nt := 0 |
|||
for _, x := range xs { |
|||
if ts(x) { |
|||
nt++ |
|||
} |
|||
} |
|||
return nt |
|||
} |
|||
// a flag used on repeated calls to test. |
|||
// set to true when first contradiction is found. |
|||
// if another is found, this function (checkPerm) can "short circuit" |
|||
// and return immediately without checking additional statements. |
|||
var con bool |
|||
// closure called to test each statement |
|||
test := func(statement uint, b bool) { |
|||
switch { |
|||
case ts(statement) == b: |
|||
case con: |
|||
panic("bail") |
|||
default: |
|||
con = true |
|||
} |
|||
} |
|||
// short circuit mechanism |
|||
defer func() { |
|||
if x := recover(); x != nil { |
|||
if msg, ok := x.(string); !ok && msg != "bail" { |
|||
panic(x) |
|||
} |
|||
} |
|||
done <- true |
|||
}() |
|||
// 1. This is a numbered list of twelve statements. |
|||
test(1, true) |
|||
// 2. Exactly 3 of the last 6 statements are true. |
|||
test(2, ntrue(7, 8, 9, 10, 11, 12) == 3) |
|||
// 3. Exactly 2 of the even-numbered statements are true. |
|||
test(3, ntrue(2, 4, 6, 8, 10, 12) == 2) |
|||
// 4. If statement 5 is true, then statements 6 and 7 are both true. |
|||
test(4, !ts(5) || ts(6) && ts(7)) |
|||
// 5. The 3 preceding statements are all false. |
|||
test(5, !ts(4) && !ts(3) && !ts(2)) |
|||
// 6. Exactly 4 of the odd-numbered statements are true. |
|||
test(6, ntrue(1, 3, 5, 7, 9, 11) == 4) |
|||
// 7. Either statement 2 or 3 is true, but not both. |
|||
test(7, ts(2) != ts(3)) |
|||
// 8. If statement 7 is true, then 5 and 6 are both true. |
|||
test(8, !ts(7) || ts(5) && ts(6)) |
|||
// 9. Exactly 3 of the first 6 statements are true. |
|||
test(9, ntrue(1, 2, 3, 4, 5, 6) == 3) |
|||
// 10. The next two statements are both true. |
|||
test(10, ts(11) && ts(12)) |
|||
// 11. Exactly 1 of statements 7, 8 and 9 are true. |
|||
test(11, ntrue(7, 8, 9) == 1) |
|||
// 12. Exactly 4 of the preceding statements are true. |
|||
test(12, ntrue(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) == 4) |
|||
// no short circuit? send permutation as either near miss or solution |
|||
if con { |
|||
nearMiss <- tz |
|||
} else { |
|||
solution <- tz |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
solution: 1 3 4 6 7 11 |
|||
near miss: 1 4 |
|||
near miss: 1 5 |
|||
near miss: 1 5 8 |
|||
near miss: 1 3 4 6 7 9 |
|||
near miss: 1 3 4 8 9 |
|||
near miss: 1 4 6 8 9 |
|||
near miss: 1 2 4 7 8 9 |
|||
near miss: 1 2 4 7 9 10 |
|||
near miss: 5 8 11 |
|||
near miss: 1 5 8 11 |
|||
near miss: 1 5 6 9 11 |
|||
near miss: 1 2 4 7 9 12 |
|||
near miss: 1 4 8 10 11 12 |
|||
near miss: 4 8 10 11 12 |
|||
near miss: 5 8 10 11 12 |
|||
near miss: 1 5 8 10 11 12 |
|||
</pre> |
|||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
Shows answers with 1 for true, followed by list of indices of incorrect elements each set of 1/0s (index is 0-based). |
Shows answers with 1 for true, followed by list of indices of incorrect elements each set of 1/0s (index is 0-based). |