Problems of Liars and Honesty I don't know what number it is, but it looks interesting so I tried it.
python
import itertools
#Return consistent answers from the player and card deck
consistents = (
lambda players: lambda card_deck: lambda statements:
(
(hands, is_each_honest)
for hands in handss(card_deck)
for is_each_honest in is_each_honests
if statements(hands) == is_each_honest
)
)
#Generator that returns a tuple of each card's hand
handss = lambda card_deck: itertools.permutations(card_deck)
#Tuples of tuples whether each player is honest(Decisive 2)
is_each_honests = (
(True, False, False, True)
,(False, True, True, False)
)
#data
players = (0, 1, 2, 3)
card_deck = (1, 2, 3, 4)
statements = lambda hands: (
hands[0] % 2 == 0
, hands[1] in (3, 4)
, hands[1] in (3, 4) # (Decisive 1)
, hands[3] == 1
)
#Function application and display
for e in consistents(players)(card_deck)(statements):
print(e)
python
#result:
((1, 3, 2, 4), (False, True, True, False))
((1, 3, 4, 2), (False, True, True, False))
((1, 4, 2, 3), (False, True, True, False))
((1, 4, 3, 2), (False, True, True, False))
((3, 4, 1, 2), (False, True, True, False))
((4, 2, 3, 1), (True, False, False, True))
There is a definite decision.
Once the card is handed, the truth of each statement is decided, which simplifies the problem.
There are a total of 6 ways if there are no restrictions, but when B and C are in the same family, the variation is reduced to 2 ways.
python
>>> players = 0, 1, 2, 3
#No restrictions
>>> tuple( tuple( not e in liars for e in players ) for liars in itertools.combinations(players, 2))
((False, False, True, True), (False, True, False, True), (False, True, True, False), (True, False, False, True), (True, False, True, False), (True, True, False, False)) #6 ways
#Limited Liar is AD or otherwise BC
>>> tuple( tuple( not e in liars for e in players ) for liars in itertools.combinations(players, 2) if liars in ((0,3),(1,2)))
((False, True, True, False), (True, False, False, True)) #2 ways
You can calculate it, but there are only two, so I wonder if it's okay to write it directly.
Based on the above
I will try.
B and C are the same whether they are honest or not.
If there are only two ways, it can be expressed by a simple logical value instead of a tuple. If the display is important, you can devise it a little.
python
import itertools
#Return consistent answers from the player and card deck
consistents = (
lambda players: lambda card_deck: lambda statements:
(
(hands, is_AD_honest)
for hands in itertools.permutations(card_deck)
for is_AD_honest in (True, False) # (Decisive 2)
if statements(hands) == (is_AD_honest, not is_AD_honest, is_AD_honest) # (Decisive 1)
)
)
#data
players = (0, 1, 2, 3)
card_deck = (1, 2, 3, 4)
statements = lambda hands: (
hands[0] % 2 == 0
, hands[1] in (3, 4) # (Decisive 1)
, hands[3] == 1
)
#Function application and display
for hands, is_AD_honest in consistents(players)(card_deck)(statements):
print(
(hands, (is_AD_honest, not is_AD_honest, not is_AD_honest, is_AD_honest)) # (Decisive 2)
)
It's easy to understand, but it's a little shorter.
But in the first place ...
If each statement is different (for example, if C says "B is a liar"), the categorical part becomes useless. I will start over.
This is what seems to work even if you rewrite the contents of each statement statements
.
python
import itertools
#Return consistent answers from the player and card deck
consistents = (
lambda players: lambda card_deck: lambda statements:
(
(hands, is_each_honest)
for hands in handss(card_deck)
for is_each_honest in is_each_honests(players)
if statements(hands) == is_each_honest
)
)
#Generator that returns a tuple of each card's hand
handss = lambda card_deck: itertools.permutations(card_deck)
#A generator that returns a tuple of whether each player is honest
is_each_honests = lambda players:(
tuple( e in honests for e in players )
for honests in itertools.combinations(players, 2)
)
#data
players = (0, 1, 2, 3)
card_deck = (1, 2, 3, 4)
statements = lambda hands: (
hands[0] % 2 == 0
, hands[1] in (3, 4)
, hands[1] in (3, 4)
, hands[3] == 1
)
#Function application and display
for e in consistents(players)(card_deck)(statements):
print(e)
However, it is still valid to "convert a reference to a person into a claim about a card's hand," as we did in Decisive 1.
Recommended Posts