इस समस्या को हल करने के लिए एक प्रसिद्ध विधि है। X_1, ..., x_n को समाधान के भाग के रूप में n'th बटन दबाएं या नहीं, और a_1, ..., an_n प्रारंभिक स्थिति होने दें। आप नीचे कुछ लिख सकते हैं
a_1 a_2 a_3
a_4 a_5 a_6
a_7 a_8 a_9
अब,:
मान लीजिए कि आप एक 3x3 समस्या को सुलझाने रहे हैं, और चर इस तरह स्थापित कर रहे हैं:
x_1 x_2 x_3
x_4 x_5 x_6
x_7 x_8 x_9
और इस प्रारंभिक अवस्था है समीकरण (अंकगणित मॉड्यूलो 2 में) कि समाधान को संतुष्ट करना चाहिए।यह मूल रूप से नियम को एन्कोड कर रहा है कि किस स्विच से एक विशेष प्रकाश टॉगल हो जाता है।
a_1 = x_1 + x_2 + x_4
a_2 = x_1 + x_2 + x_3 + x_5
...
a_5 = x_2 + x_4 + x_5 + x_6 + x_8
...
a_9 = x_6 + x_8 + x_9
अब आप एक साथ समीकरणों के इस सेट को हल करने के लिए गाऊशियन उन्मूलन का उपयोग कर सकते हैं। चूंकि आप अंकगणित मॉड्यूलो 2 में काम कर रहे हैं, यह वास्तविक संख्याओं पर एक साथ समीकरणों की तुलना में वास्तव में थोड़ा आसान है। उदाहरण के लिए, दूसरे समीकरण में x_1 से छुटकारा पाने के लिए, बस इसे पहले समीकरण जोड़ें।
a_1 + a_2 = (x_1 + x_2 + x_4) + (x_1 + x_2 + x_3 + x_5) = x_3 + x_4 + x_5
विशेष रूप से, गणित सापेक्ष 2 में गाऊसी उन्मूलन एल्गोरिथ्म है:
- उस में एक x_1 साथ एक समीकरण उठाओ। इसे नाम दें E_1।
- इसमें एक x_1 के साथ हर दूसरे अज्ञात समीकरण में E_1 जोड़ें।
- x_2, x_3, ...., x_n के लिए दोहराना।
अब, ई_एन एक समीकरण है जिसमें केवल x_n है। आप x_n के मान को प्रतिस्थापित कर सकते हैं जो आप इससे पहले के समीकरणों में प्राप्त करते हैं। E_ {n-1}, ..., E_1 के लिए दोहराएं।
कुल मिलाकर, यह ओ (एन^3) संचालन में समस्या हल करता है।
यहां कुछ कोड है।
class Unsolvable(Exception):
pass
def switches(vs):
n, m = len(vs), len(vs[0])
eqs = []
for i in xrange(n):
for j in xrange(m):
eq = set()
for d in xrange(-1, 2):
if 0 <= i+d < n: eq.add((i+d)*m+j)
if d != 0 and 0 <= j+d < m: eq.add(i*m+j+d)
eqs.append([vs[i][j], eq])
N = len(eqs)
for i in xrange(N):
for j in xrange(i, N):
if i in eqs[j][1]:
eqs[i], eqs[j] = eqs[j], eqs[i]
break
else:
raise Unsolvable()
for j in xrange(i+1, N):
if i in eqs[j][1]:
eqs[j][0] ^= eqs[i][0]
eqs[j][1] ^= eqs[i][1]
for i in xrange(N-1, -1, -1):
for j in xrange(i):
if i in eqs[j][1]:
eqs[j][0] ^= eqs[i][0]
eqs[j][1] ^= eqs[i][1]
return [(i//m,i%m) for i, eq in enumerate(eqs) if eq[0]]
print switches(([1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 0]))
आप इसे एक समय में प्रारंभिक स्थिति देते हैं। यह उन स्विचों को वापस करता है जिन्हें आपको सभी रोशनी बंद करने के लिए दबाए जाने की आवश्यकता होती है।
यह मेरे लैपटॉप पर आधे सेकेंड से भी कम समय में 50x50 समस्या हल करता है।
यह भी देखें [लाइट्स आउट] (http://en.wikipedia.org/wiki/Lights_Out_%28game%29)। – trashgod