from __future__ import print_function   #so this will work with Py 2.7

'''
December 2017 Math Puzzler Solution
  https://sites.monroecc.edu/mathpuzzler/2017/12/01/december-2017-puzzle
  Dave Vogel - dvogel003@monroecc.edu

  As shown in the figure to the right, there are three
switches used to control a traffic light. Each switch
has three possible settings of a, b, or c, and the
specific color (green, yellow, or red) of the traffic
light is completely determined by the combined
settings of the switches. Your job is to determine
all of the settings of the switches that result in a
green light based on the following information.

 - Only one light is on for each of the settings.
 - When all three switches are in the a-position (setting aaa), the
 light is yellow.
 - When switch 1 is in the b-position and switches 2 and 3 are in
 the a-position (setting baa), the light is red.
 - From any given setting, if you change the positions of all three
 switches, the light will change color. 
'''

class Light:
  '''
     Object to simulate a traffic light whose color is determined by the switches
     sw1, sw2, ...
  '''
  
  def __init__(self, sw1, sw2, sw3):

    self.sw1 = sw1                    #Position of first switch ('a', 'b', or 'c')
    self.sw2 = sw2                    # ditto for second switch
    self.sw3 = sw3                    # ...
    self.index = sw1 + sw2 + sw3      #Used for dictionary index (for ex. 'aaa')
    self.color = ''                   #Color of this switch combination
    
    self.notColor = {'R':False, 'Y':False, 'G':False}   #Change to True as it is determined



  def __repr__(self):
    '''
       Textual representation of a Light
    '''

    resp = self.index + ' ' + self.color
    
    if debug:
      resp += '\t' + str(self.notColor)

    return resp
  
  ####End of Light object
  

###Subroutines used in Main
def moveKnown():
  '''
     Move all the Lights with known colors from the unknown dictionary to
     the known dictionary
  '''
  keysToDelete = []                   #Which Lights are known and can be removed
  
  for key, light in unknown.items():
    if light.color != '':             #If the color is now known
      known[key] = light              # add to the known pile
      temp[key] = light               # and the temp pile
      keysToDelete.append(key)        # and mark for removal from unknown pile

  for key in keysToDelete:            #And remove it
    del unknown[key]



def setNotColors(aKnown):
  '''
     Find and mark what the colors that the Light CAN'T be.  See rules:  If all
     three switches are different, 2 lights can't be the same color.
  '''

  for key in unknown.keys():
    #If all the switch positions are different
    if unknown[key].sw1 != aKnown.sw1 and \
       unknown[key].sw2 != aKnown.sw2 and \
       unknown[key].sw3 != aKnown.sw3:
      unknown[key].notColor[aKnown.color] = True  #Then this Light CAN'T be the color of aKnown



def setColor():
  '''
     If two of the colors of a Light and know to can't be the color, then the color
     must be the other color.
  '''

  for key in unknown.keys():
    if unknown[key].notColor['R'] and unknown[key].notColor['Y']:
      unknown[key].color = 'G'
    elif unknown[key].notColor['Y'] and unknown[key].notColor['G']:
      unknown[key].color = 'R'
    elif unknown[key].notColor['R'] and unknown[key].notColor['G']:
      unknown[key].color = 'Y'


  
####MAIN
if __name__ == '__main__':

  debug = False                   #Set to True for more informative Light.__repr__()
  
  #Build the initial conditions
  known = {}                      #Known color for switch combinations
  unknown = {}                    #Unknown color for switch combinations
  temp = {}                       #New knowns
  for i in ['a','b','c']:
    for j in ['a','b','c']:
      for k in ['a','b','c']:
        aLight = Light(i, j, k)
        unknown[aLight.index] = aLight
  unknown['aaa'].color = "Y"          #Given in rules: aaa is yellow
  unknown['baa'].color = "R"          # and baa is red.


  #Now find the solution
  while unknown != {}:                #Run this until the unknown dictionary is empty
    moveKnown()                       #Find all knowns, move to known dictionary
    for key, aKnown in temp.items():  #Find and mark all the NOT colors
      setNotColors(aKnown)
    setColor()                        #Set the color of all the new knowns

  for aKey in sorted(known.keys()):   #Display the results (in order)
    print(known[aKey])