幾天前我開始了這個問題(下面的代碼)。
Bringing a Gun to a Trainer Fight
=================================
Uh-oh -- you've been cornered by one of Commander Lambdas elite bunny trainers! Fortunately, you grabbed a beam weapon from an abandoned storeroom while you were running through the station, so you have a chance to fight your way out. But the beam weapon is potentially dangerous to you as well as to the bunny trainers: its beams reflect off walls, meaning you'll have to be very careful where you shoot to avoid bouncing a shot toward yourself!
Luckily, the beams can only travel a certain maximum distance before becoming too weak to cause damage. You also know that if a beam hits a corner, it will bounce back in exactly the same direction. And of course, if the beam hits either you or the bunny trainer, it will stop immediately (albeit painfully).
Write a function solution(dimensions, your_position, trainer_position, distance) that gives an array of 2 integers of the width and height of the room, an array of 2 integers of your x and y coordinates in the room, an array of 2 integers of the trainer's x and y coordinates in the room, and returns an integer of the number of distinct directions that you can fire to hit the elite trainer, given the maximum distance that the beam can travel.
The room has integer dimensions [1 < x_dim <= 1250, 1 < y_dim <= 1250]. You and the elite trainer are both positioned on the integer lattice at different distinct positions (x, y) inside the room such that [0 < x < x_dim, 0 < y < y_dim]. Finally, the maximum distance that the beam can travel before becoming harmless will be given as an integer 1 < distance <= 10000.
For example, if you and the elite trainer were positioned in a room with dimensions [3, 2], your_position [1, 1], trainer_position [2, 1], and a maximum shot distance of 4, you could shoot in seven different directions to hit the elite trainer (given as vector bearings from your location): [1, 0], [1, 2], [1, -2], [3, 2], [3, -2], [-3, 2], and [-3, -2]. As specific examples, the shot at bearing [1, 0] is the straight line horizontal shot of distance 1, the shot at bearing [-3, -2] bounces off the left wall and then the bottom wall before hitting the elite trainer with a total shot distance of sqrt(13), and the shot at bearing [1, 2] bounces off just the top wall before hitting the elite trainer with a total shot distance of sqrt(5).
Languages
=========
To provide a Java solution, edit Solution.java
To provide a Python solution, edit solution.py
Test cases
==========
Your code should pass the following test cases.
Note that it may also be run against hidden test cases not shown here.
-- Java cases --
Input:
Solution.solution([3,2], [1,1], [2,1], 4)
Output:
7
Input:
Solution.solution([300,275], [150,150], [185,100], 500)
Output:
9
-- Python cases --
Input:
solution.solution([3,2], [1,1], [2,1], 4)
Output:
7
Input:
solution.solution([300,275], [150,150], [185,100], 500)
Output:
9
Use verify [file] to test your solution and see how it does. When you are finished editing your code, use submit [file] to submit your answer. If your solution passes the test cases, it will be removed from your home folder.
我讓兩個測驗用例都通過了我的計算機,但由于某種原因,當我在平臺上驗證代碼時,兩個測驗用例中只有第二個通過(第一個失敗)。此外,第 4、5 和 6 個測驗用例通過(全部隱藏),其余(共 10 個)失敗。這是我的代碼:
from math import sqrt, ceil, atan2
def solution(dimensions, your_position, trainer_position, distance):
# calculate maximum repetiions of current room in mirrored room
cp_x = int(ceil((your_position[0] distance) / dimensions[0]))
cp_y = int(ceil((your_position[1] distance) / dimensions[1]))
# generate all possible positions in q1
q1_player = [your_position]
q1_trainer = [trainer_position]
for i in range(0, cp_x):
for j in range(0, cp_y):
if i == 0 and j == 0:
continue
else:
temp_player = [your_position[0] i * dimensions[0], your_position[1] j * dimensions[1]]
temp_trainer = [trainer_position[0] i * dimensions[0], trainer_position[1] j * dimensions[1]]
if i % 2 != 0:
temp_player[0] = temp_player[0] - (2 * your_position[0]) dimensions[0]
temp_trainer[0] = temp_trainer[0] - (2 * trainer_position[0]) dimensions[0]
if j % 2 != 0:
temp_player[1] = temp_player[1] - (2 * your_position[1]) dimensions[1]
temp_trainer[1] = temp_trainer[1] - (2 * trainer_position[1]) dimensions[1]
q1_player.append(temp_player)
q1_trainer.append(temp_trainer)
# generate all possible positions in q2, q3, and q4
q2_player = [[-x, y] for [x, y] in q1_player]
q2_trainer = [[-x, y] for [x, y] in q1_trainer]
q3_player = [[-x, -y] for [x, y] in q1_player]
q3_trainer = [[-x, -y] for [x, y] in q1_trainer]
q4_player = [[x, -y] for [x, y] in q1_player]
q4_trainer = [[x, -y] for [x, y] in q1_trainer]
# generate distances from original player
player = [[x, y, dist(your_position, [x, y]), 1] for [x, y] in q1_player q2_player q3_player q4_player]
trainer = [[x, y, dist(your_position, [x, y]), 2] for [x, y] in q1_trainer q2_trainer q3_trainer q4_trainer]
corners = [[x, y, dist(your_position, [x, y]), 3] for [x, y] in [(0, 0), (dimensions[0], 0), (dimensions[0], dimensions[1]), (0, dimensions[1])]]
# filter for distances that are too far away
positions = filter(lambda x: x[2] <= float(distance), player trainer corners)
positions = sorted(positions, key=lambda x: x[2]) # so least distance is always first
# reduce list of lists with same angle but grab least distance
angles = {}
for pos in positions[1:]:
agl = ang(your_position, [pos[0], pos[1]])
if agl not in angles:
angles[agl] = pos
# uncomment to see the list of vectors
# print([(pos[0] - your_position[0], pos[1] - your_position[1]) for pos in angles.values() if pos[4] == 2])
# return number of times only trainer is hit
return sum(1 for pos in angles.values() if pos[3] == 2)
def dist(p1, p2):
return sqrt((p1[0] - p2[0])**2 (p1[1] - p2[1])**2)
def ang(p1, p2):
return atan2((p2[1] - p1[1]), (p2[0] - p1[0]))
我從網上獲得了一些額外的測驗用例,并通過運行其他人提交的代碼來檢查答案:
def test():
assert solution([3, 2], [1, 1], [2, 1], 4) == 7
assert solution([2, 5], [1, 2], [1, 4], 11) == 27
assert solution([23, 10], [6, 4], [3, 2], 23) == 8
assert solution([1250, 1250], [1000, 1000], [500, 400], 10000) == 196
assert solution([10, 10], [4, 4], [3, 3], 5000) == 739323
assert solution([3, 2], [1, 1], [2, 1], 7) == 19
assert solution([2, 3], [1, 1], [1, 2], 4) == 7
assert solution([3, 4], [1, 2], [2, 1], 7) == 10
assert solution([4, 4], [2, 2], [3, 1], 6) == 7
assert solution([300, 275], [150, 150], [180, 100], 500) == 9
assert solution([3, 4], [1, 1], [2, 2], 500) == 54243
除了最后一種情況,這里的一切都通過了solution([3, 4], [1, 1], [2, 2], 500) == 54243,我實際上得到了 54239。
我已經堅持了幾個小時,老實說不知道為什么所有這些)和b)為什么我要通過我自己的所有其他測驗用例,除了最后一個。我希望這也能幫助我弄清楚為什么我在平臺上的其他隱藏測驗用例失敗了。
uj5u.com熱心網友回復:
在 Python 2 中,/ 執行整數除法。因此,在代碼中
int(ceil((your_position[0] distance) / dimensions[0]))
是ceil沒用的,因為該值已經被四舍五入了。
此計算不需要浮點運算,出于通常的原因,在這些情況下最好避免使用浮點數。
相反,我們將使用一個函式來獲得“上限整數除法”結果。訣竅是首先添加分子,這樣該值就會增加 1,除非分子已經可以整除。那么,我們需要添加的數量是分母減一。
這個版本應該在 Python 2 和 3 中以相同的方式作業,因為//無論如何都執行下限除法(在 2 中,/整數是下限除法,但浮點值是“真”除法)。
def ceil_div(quotient, divisor):
return (quotient divisor - 1) // divisor
現在我們可以做
def solution(dimensions, your_position, trainer_position, distance):
# calculate maximum repetiions of current room in mirrored room
cp_x = ceil_div((your_position[0] distance), dimensions[0])
cp_y = ceil_div((your_position[1] distance), dimensions[1])
它應該可以在 Python 2 或 Python 3 中作業。我們不再需要強制轉換為int,因為輸入是整數,因此下限除法也會產生整數。
uj5u.com熱心網友回復:
我設法弄清楚我遺漏了什么——我的解決方案在 Python 3 中是正確的,我認為我已經考慮了 Python 2.7 中的所有版本差異,但事實證明還有一個。我相信這與range()我的計算方式或cp_x第一cp_y象限中的最大副本數有關。在我的迭代中添加一個,這樣:
# calculate maximum repetitions of current room in mirrored room
cp_x = int(ceil((your_position[0] distance) / dimensions[0]))
cp_y = int(ceil((your_position[1] distance) / dimensions[1]))
# generate all possible positions in q1
q1_player = [your_position]
q1_trainer = [trainer_position]
for i in range(0, cp_x 1): # ADD ONE HERE
for j in range(0, cp_y 1): # ADD ONE HERE
解決它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/482249.html
標籤:Python python-2.7
