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])