Enigmatic Code

Programming Enigma Puzzles

Enigma 1321: Christmas cards

From New Scientist #2479, 25th December 2004

For Jesus’s birthday, Mary gave him a new game involving coloured cards. Jesus had 4 red cards and 8 green cards and Mary had 2 blue cards and 10 yellow cards.

The game involved 12 rounds; in each round both players put a card on the table and the higher card won the round. Red was higher than blue but lower than yellow; green was higher than yellow but lower than blue. The winner of each round put their card for the next round on the table first so the other player could see its colour before deciding what colour to play. Mary went first for the first round.

Question 1. Assuming both played as well as possible, how many rounds did Jesus win?

Jesus said it was mystery and perfection, so they played another game. He had 3 red and 3 green cards and Mary had 3 blue and 3 yellow cards. The game had 6 rounds and Jesus went first in the first round.

Question 2. Again assuming best possible play, how many rounds did Jesus win?

[enigma1321]

Advertisements

One response to “Enigma 1321: Christmas cards

  1. Jim Randell 28 May 2014 at 9:31 am

    This Python program runs in 597ms.

    from enigma import printf
    
    # win for J?
    def win(J, M):
      return (1 if J + M in ('RB', 'GY') else 0)
    
    def remove(xs, x):
      xs = list(xs)
      xs.remove(x)
      return ''.join(xs)
    
    # J - cards J is holding
    # M - cards M is holding
    # n - remaining cards
    # p - player to play (0 = J, 1 = M)
    # return number of rounds J wins, plays
    def play(J, M, n, p):
      if n == 1:
        return (win(J, M), J, M)
    
      # consider the possible plays
      if p == 0:
        (A, B, fa, fb) = (J, M, max, min)
      else:
        (A, B, fa, fb) = (M, J, min, max)
        
      plays = list()
      for a in set(A):
        ps = list()
        for b in set(B):
          # and the remaining rounds
          if p == 0:
            w = win(a, b)
            (g, js, ms) = play(remove(J, a), remove(M, b), n - 1, 1)
            ps.append((g + w, a + js, b + ms))
          else:
            w = win(b, a)
            (g, js, ms) = play(remove(J, b), remove(M, a), n - 1, 0)
            ps.append((g + w, b + js, a + ms))
        plays.append(fb(ps, key=lambda x: x[0]))
      return fa(plays, key=lambda x: x[0])
          
    q1 = play('RRRRGGGGGGGG', 'BBYYYYYYYYYY', 12, 1)
    printf("(1) J wins {q1[0]} [J={q1[1]} M={q1[2]}]")
    
    q2 = play('RRRGGG', 'BBBYYY', 6, 0)
    printf("(2) J wins {q2[0]} [J={q2[1]} M={q2[2]}]")
    

    Solution: (1) Jesus wins 6 rounds; (2) Jesus wins 2 rounds.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: