के भीतर आप लेजर बीम के साथ एक लक्ष्य को कैसे मार सकते हैं आप आयताकार आकार वाले कमरे के भीतर एक दुश्मन के साथ सामना कर रहे हैं और आपको केवल एक लेजर बीम हथियार मिला है, कमरे में इसमें कोई बाधा नहीं है और दीवारें लेजर बीम को पूरी तरह से प्रतिबिंबित कर सकती हैं। हालांकि लेजर बेकार हो जाने से पहले केवल एक निश्चित दूरी की यात्रा कर सकता है और यदि यह एक कोने पर पहुंच जाता है तो यह उसी दिशा में वापस दिखाई देगा जो यह आया था।पहेली: चार प्रतिबिंबित दीवारों
इस प्रकार पहेली जाती है और आपको अपने स्थान के समन्वय और लक्ष्य के स्थान, कमरे के आयाम और बीम यात्रा की अधिकतम दूरी प्रदान की जाती है। उदाहरण के लिए, तो कमरे में 2 से 3 है और अपने स्थान है (1, 1) और लक्ष्य है (2, 1) तो संभव समाधान हैं:
मैं निम्नलिखित दृष्टिकोण की कोशिश की, से शुरू स्रोत (1, 1) और कोण 0 रेडियंस पर एक वेक्टर बनाएं, वेक्टर पथ और प्रतिबिंबों का पता लगाएं जब तक कि यह लक्ष्य को हिट न करे या वैक्टर की कुल लंबाई अधिकतम अनुमत लंबाई से अधिक हो, 0.001 रेडियंस अंतराल के साथ दोहराए जाने तक इसे दोहराएं पूरा चक्र। इस कोड को मैं अब तक है:
from math import *
UPRIGHT = 0
DOWNRIGHT = 1
DOWNLEFT = 2
UPLEFT = 3
UP = 4
RIGHT = 5
LEFT = 6
DOWN = 7
def roundDistance (a):
b = round (a * 100000)
return b/100000.0
# only used for presenting and doesn't affect percision
def double (a):
b = round (a * 100)
if b/100.0 == b: return int (b)
return b/100.0
def roundAngle (a):
b = round (a * 1000)
return b/1000.0
def isValid (point):
x,y = point
if x < 0 or x > width or y < 0 or y > height: return False
return True
def isCorner (point):
if point in corners: return True
return False
# Find the angle direction in relation to the origin (observer) point
def getDirection (a):
angle = roundAngle (a)
if angle == 0: return RIGHT
if angle > 0 and angle < pi/2: return UPRIGHT
if angle == pi/2: return UP
if angle > pi/2 and angle < pi: return UPLEFT
if angle == pi: return LEFT
if angle > pi and angle < 3 * pi/2: return DOWNLEFT
if angle == 3 * pi/2: return DOWN
return DOWNRIGHT
# Measure reflected vector angle
def getReflectionAngle (tail, head):
v1 = (head[0] - tail[0], head[1] - tail[1])
vx,vy = v1
n = (0, 0)
# Determin the normal vector from the tail's position on the borders
if head[0] == 0: n = (1, 0)
if head[0] == width: n = (-1, 0)
if head[1] == 0: n = (0, 1)
if head[1] == height: n = (0, -1)
nx,ny = n
# Calculate the reflection vector using the formula:
# r = v - 2(v.n)n
r = (vx * (1 - 2 * nx * nx), vy * (1 - 2 * ny * ny))
# calculating the angle of the reflection vector using it's a and b values
# if b (adjacent) is zero that means the angle is either pi/2 or -pi/2
if r[0] == 0:
return pi/2 if r[1] >= 0 else 3 * pi/2
return (atan2 (r[1], r[0]) + (2 * pi)) % (2 * pi)
# Find the intersection point between the vector and borders
def getIntersection (tail, angle):
if angle < 0:
print "Negative angle: %f" % angle
direction = getDirection (angle)
if direction in [UP, RIGHT, LEFT, DOWN]: return None
borderX, borderY = corners[direction]
x0,y0 = tail
opp = borderY - tail[1]
adj = borderX - tail[0]
p1 = (x0 + opp/tan (angle), borderY)
p2 = (borderX, y0 + adj * tan (angle))
if isValid (p1) and isValid (p2):
print "Both intersections are valid: ", p1, p2
if isValid (p1) and p1 != tail: return p1
if isValid (p2) and p2 != tail: return p2
return None
# Check if the vector pass through the target point
def isHit (tail, head):
d = calcDistance (tail, head)
d1 = calcDistance (target, head)
d2 = calcDistance (target, tail)
return roundDistance (d) == roundDistance (d1 + d2)
# Measure distance between two points
def calcDistance (p1, p2):
x1,y1 = p1
x2,y2 = p2
return ((y2 - y1)**2 + (x2 - x1)**2)**0.5
# Trace the vector path and reflections and check if it can hit the target
def rayTrace (point, angle):
path = []
length = 0
tail = point
path.append ([tail, round (degrees (angle))])
while length < maxLength:
head = getIntersection (tail, angle)
if head is None:
#print "Direct reflection at angle (%d)" % angle
return None
length += calcDistance (tail, head)
if isHit (tail, head) and length <= maxLength:
path.append ([target])
return [path, double (length)]
if isCorner (head):
#print "Corner reflection at (%d, %d)" % (head[0], head[1])
return None
p = (double (head[0]), double (head[1]))
path.append ([p, double (degrees (angle))])
angle = getReflectionAngle (tail, head)
tail = head
return None
def solve (w, h, po, pt, m):
# Initialize global variables
global width, height, origin, target, maxLength, corners, borders
width = w
height = h
origin = po
target = pt
maxLength = m
corners = [(w, h), (w, 0), (0, 0), (0, h)]
angle = 0
solutions = []
# Loop in anti-clockwise direction for one cycle
while angle < 2 * pi:
angle += 0.001
path = rayTrace (origin, angle)
if path is not None:
# extract only the points coordinates
route = [x[0] for x in path[0]]
if route not in solutions:
solutions.append (route)
print path
# Anser is 7
solve (3, 2, (1, 1), (2, 1), 4)
# Answer is 9
#solve (300, 275, (150, 150), (185, 100), 500)
कोड किसी भी तरह से काम करता है लेकिन यह सब संभव समाधान नहीं मिल रहा है, मैं इसे में एक बड़ा सटीक समस्या है, मैं 'न जानता हूँ कि मैं कितने दशमलव विचार करना चाहिए जब दूरी या कोण की तुलना करना। मुझे यकीन नहीं है कि यह करने का सही तरीका है लेकिन यह सबसे अच्छा है जो मैं करने में सक्षम था।
सभी समाधान निकालने के लिए मैं अपना कोड कैसे ठीक कर सकता हूं? मुझे इसे कुशल होने की आवश्यकता है क्योंकि कमरा काफी बड़ा हो सकता है (500 x 500)। क्या ऐसा करने के लिए कोई बेहतर तरीका या शायद कुछ प्रकार का एल्गोरिदम है?
क्या आप सभी दीवारों पर लक्ष्य मिरर द्वारा शुरू किया है; फिर सभी दीवारों पर दर्पण छवियों को दर्पण करें और तब तक लेजर के लक्ष्य तक पहुंचने के लिए दूरी बहुत बड़ी हो जाती है? लक्षित लक्ष्य की किसी भी दिशा में किसी भी लेजर शॉट ने उस लक्ष्य को मारा होगा। –
@hiroprotagonist बहुत रोचक, लेकिन मैं टैगेट दर्पण स्थानों की गणना करने के बारे में कैसे जा सकता हूं? – user7342539
क्या इस मामले पर विचार किया जाना चाहिए कि बीम मूल को हिट करता है? या यह हस्तक्षेप के बिना बस इसके माध्यम से जाना होगा? – trincot