Enigmatic Code

Programming Enigma Puzzles

Enigma 521: Changing truths

From New Scientist #1673, 15th July 1989 [link]

As I made my way through the jungle with my truthful guide Lamoura, we came upon a clearing, at the centre of which was a large stone. On the stone were carved the following four sentences:

(A) B is true today and C and D are false today, and D is moon.
(B) An even number of A, B, C, D are false today or C is moon.
(C) B is true today and A and D are false today, and B is moon.
(D) B is true today and A and C are false today, and A is moon.

Lamoura explained that beginning on the morrow and running for the next few days was the festival of the Green Moon. So we decided to camp there until the festival was over.

Lamoura told me that on each day of the festival, each of the four sentences is true or false; she also explained that to say that a sentence is moon means that on at least one day of the festival the sentence is true and on at lease one day it is false.

As each day of the festival dawned, a local native gave me a piece of paper stating which sentences were true that day and which were false. I kept these papers and at the end of the festival, I was able to check that what was written on them agreed with what Lamoura had told me. I also noticed that no two papers said the same thing.

How many days did the festival last, which sentence or sentences were true every day, which were false every day, and which were moon?

[enigma521]

One response to “Enigma 521: Changing truths

  1. Jim Randell 14 October 2019 at 8:45 am

    Each day the setter is given a piece of paper detailing which statement is true and which is false (they are all either true or false on each day), so each day the piece of paper consists of a 4 values chosen from “true” and “false”. So there are only 2^4 = 16 possible different slips of paper.

    This Python program considers possible “moon” values for each of the statements, and given these values select possible daily truth values for the statements.

    Once the daily values have been collected we select some sequence of at least 2 of the values to represent the pieces of paper for each day. We can then verify that the initial “moon” values hold.

    It runs in 88ms.

    Run: [ @repl.it ]

    from enigma import subsets, printf
    
    # label the statements
    statements = (A, B, C, D) = (1, 2, 3, 4)
    
    # consider which statements are "moon"
    for moon in subsets(statements):
    
      # collect possible truth values for each statement
      ss = list()
      for (tA, tB, tC, tD) in subsets((False, True), size=4, select="M"):
    
        # A: "(B is true) and (C is false) and (D is false) and (D is moon)"
        if not(tA == (tB and not(tC) and not(tD) and (D in moon))): continue
    
        # B: "(an even number of A, B, C, D are false) or (C is moon)"
        if not(tB == (((tA, tB, tC, tD).count(False) % 2 == 0) or (C in moon))): continue
    
        # C: "(B is true) and (A is false) and (D is false) and (B is moon)"
        if not(tC == (tB and not(tA) and not(tD) and (B in moon))): continue
    
        # D: "(B is true) and (A is false) and (C is false) and (A is moon)"
        if not(tD == (tB and not(tA) and not(tC) and (A in moon))): continue
    
        ss.append((tA, tB, tC, tD))
    
      # consider sequences of truths for each of at least 2 days
      for days in subsets(ss, min_size=2, select="P"):
        # and check the moon values match
        (ts, fs, ms) = (list(), list(), list())
        for (s, vs) in zip(statements, zip(*days)):
          vs = set(vs)
          if len(vs) == 1:
            (ts if vs.pop() else fs).append(s)
          else:
            ms.append(s)
        if tuple(ms) != moon: continue
    
        # output solution
        printf("{n} days = {days}", n=len(days))
        printf("true = {ts}; false = {fs}; moon = {ms}")
        printf()
    

    Solution: The festival lasted 2 days. B was true each day. C was false each day. A and D were moon.

    On one of the days the statements have the values:

    A = true; B = true; C = false; D = false

    A is true, as: B is true and C and D are false, and D is moon.
    B is true, as: an even number (2) of A, B, C, D are false.
    C is false, as: A is not false (and B is not moon).
    D is false, as: A is not false (and A is not moon)

    On the other day the statements have the values:

    A = false; B = true; C = false; D = true

    A is false, as: D is not false.
    B is true, as: an even number (2) of A, B, C, D are false.
    C is false, as: D is not false (and B is not moon).
    D is true, as: B is true and A and C are false, and A is moon.

    And we can verify that A and D are moon, B is always true and C is always false, as required.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: