I am trying to solve apparatus problem, paraphrased below.
There is an apparatus with n on/off switches with a one-to-one correspondence to n lights (but with an unknown permutation). We have several different photographs of the apparatus showing different configurations of the switches and lights. Are these photos sufficient to fully describe the device?
Input
First line contains two integers: n (the number of switches, 1 ≤ n ≤ 1000) and m (the number of photographs, 0 ≤ m ≤ 1000).
Each subsequent pair of lines describes the switches and the lights as a string of
1
(on) and0
(off).Output
Write the number of possible different wirings, modulo 1000003.
I have a solution but it takes longer than 2 seconds which is the time limit. I've tried to optimize my code for speed but can't get it within the 2 second limit.
import sys
import math
for line in sys.stdin:
line = line.strip("\n").split(" ")
numSwitches = int(line[0])
numPics = int(line[1])
wiring = {}
inValid = False
for i in range(numPics):
if (inValid):
break
x = sys.stdin.readline().strip("\n")
f_x = sys.stdin.readline().strip("\n")
x_ones = 0
f_x_ones = 0
digit = 0
for i in range(numSwitches):
if f_x[i]=='1':
digit += 2**(numSwitches-i-1)
f_x_ones += 1
for switch in range(numSwitches):
if (x[switch]=='1'):
x_ones += 1
if not (switch in wiring.keys()):
wiring[switch] = digit
else:
wiring[switch] &= digit
if x_ones != f_x_ones:
inValid = True
break
if not inValid:
for i in wiring.values():
if i==0:
inValid = True
break
for possibilities in set(wiring.values()):
frequency = wiring.values().count(possibilities)
if frequency>1:
oneBits = 0
while (possibilities>0):
oneBits += (possibilities%2==1)
possibilities /= 2
if oneBits < frequency:
inValid = True
break
if not inValid:
print math.factorial(numSwitches-numPics)%1000003
else:
print 0
I'm looking for suggestions of ways I should have approached the problem or input on how I can optimize my current code.
Note: Consider the following test case:
3 2
110
011
011
011
My code finds that is invalid in the following manner. First, upon encountering the first photograph (110, 011). The wiring dictionary gets assigned the following keys and values:
wiring[0] = 011
wiring[1] = 011
This means that the first and second switch can light up either the second or third lights. Upon encountering the second photograph (011, 011). wiring is updated as follows:
wiring[1] = 011 & 011 = 011
wiring[2] = 011
Now observe that the state of wiring indicates that all three switches can light up either the second and third lights. This is an inconsistency since 3 switches have to light up three lights, here we have three switches lighting up 2 lights.
110 011
also means that light 3 is turned off by switch 1, so you can infer an input001 100
to your logic. In this way (you should better test) you can probably cut off your inconsistency test. \$\endgroup\$