谷歌FooBar带枪参加守卫战

2024-04-20 10:46:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我被困在这个问题上:

Uh-oh - you've been cornered by one of Commander Lambdas elite guards! Fortunately, you grabbed a beam weapon from an abandoned guard post 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 elite guard: 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 guard, it will stop immediately (albeit painfully).

Write a function solution(dimensions, your_position, guard_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 guard'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 guard, 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 guard 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 guard were positioned in a room with dimensions [3, 2], your_position [1, 1], guard_position [2, 1], and a maximum shot distance of 4, you could shoot in seven different directions to hit the elite guard (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 guard 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 guard with a total shot distance of sqrt(5).

我尝试过的

import math
def solution(dimensions, your_position, guard_position, distance):
    positions = make_positions(dimensions, your_position, guard_position, distance) # Gets all the guard and "me" positions when reflecting the rooms. EG if the room is 3x2 and my position is 1,1 then some of the reflected positions will be 1,3 -1,1 etc
    ways = [] # Will store the ways to hit the target.
# This loop filters all the positions and keeps the one that make sense (eg if the bullet will hit me before it hits the target then it wont count it, or if shotting in the same direction can hit many targets it only counts one, it also takes care of the distance req)
    for p in positions:
        valid = True
        if p[0] <= distance and p[-1]: # If the distance is less than or equal to the max distance and it is towards the target (given by p[0]) then I consider this point
            for p2 in positions: # I go through all other shots I could take and make sure that this position is the shortest (eg if I can hit the 2 targets I only want to consider it as 1 hit as I will hit the one closest to me, and I want to make sure I don't hit myself before I hit the guard)
                if p2[1] == p[1] and p2[0] < p[0]:
                    valid = False

            if valid and p[2:4] not in ways:
                ways.append(p[2:4])
    return len(ways) # Returns the number of ways to hit the target

def make_positions(dimensions, your_position, guard_position, distance):
# This function returns all the mirrored positions (up, down, left, right)
    p2 = []
# Gets the maximum number of reflections needed based on the shot distance
    rooms_x = int(math.ceil(float(your_position[0] + distance)/dimensions[0]))
    rooms_y = int(math.ceil(float(your_position[1] + distance)/dimensions[1]))
    
    room_x_back = -1 * rooms_x
    room_y_back = -1 * rooms_y
# Check if I am on the edge so that I don't get weird reflections where I would be on the same spot
    if your_position[0] == 0:
        room_x_back = 0
    elif your_position[0] == dimensions[0]:
        rooms_x = 0
    if your_position[1] == 0:
        room_y_back = 0
    elif your_position[1] == dimensions[1]:
        rooms_y = 0
    for x in range(room_x_back, rooms_x):
        for y in range(room_y_back, rooms_y):
# Takes care of my position in this reflection
            x_pos, y_pos = get_position(dimensions, your_position, x, y) # Gets my new position (x,y)
            dist = get_distance(your_position[0], your_position[1], x_pos, y_pos) # Calculates my distance to my new position (this helps me identify if I will hit myself or the target later on if shooting in this direction can hit both)
            angle = get_angle(your_position[0], your_position[1], x_pos, y_pos) # This gives me the angle I would have to shoot in to hit the new (x,y)
            if dist > 0:
                p2.append([dist, angle, 0])
            
# Take care of the target position in this reflection (very much the same as the code above)
            x_pos, y_pos = get_position(dimensions, guard_position, x, y)
            dist = get_distance(your_position[0], your_position[1], x_pos, y_pos)
            angle = get_angle(your_position[0], your_position[1], x_pos, y_pos)
            p2.append([dist, angle, x_pos, y_pos, 1])
    return p2

def get_position(dimensions, position, x, y):
# Returns the reflected position
# If there are an odd number of reflections in one direction there is a pattern and similarly for evens so I handle both cases.
    if not x % 2:
        x_pos = (x) * dimensions[0] + position[0]
    else:
        x_pos = (x+1) * dimensions[0] - position[0]
    if not y % 2:
        y_pos = (y) * dimensions[1] + position[1]
    else:
        y_pos = (y+1) * dimensions[1] - position[1]
    return x_pos, y_pos

def get_distance(x1,y1,x2,y2):
    return math.sqrt((x2-x1)**2+(y2-y1)**2)

def get_angle(x1,y1,x2,y2):
    #if not x2-x1:
        #return float("inf") if y2 > y1 else float("-inf")
    return math.atan2(x2-x1,y2-y1)

我的代码当前使用反射属性查找所有守卫位置并对其进行计数。我知道这不是最干净的,但我以后会解决的

我目前通过了9/10个测试用例,测试用例3没有通过。我在网上收集并在我的代码上测试的一些示例(我的代码给出了每个示例的正确答案):

解([3,2],[1,1],[2,1],4)-我得到7

解([2,5],[1,2],[1,4],11)-我得到27

解([23,10],[6,4],[3,2],23)-我得到8

解决方案([300275],[150150],[185100],500)-我得到9

解决方案([1250],[10001000],[500400],10000)-我得到196

我一直在寻找为什么我会在测试用例中失败,但找不到原因。有什么帮助吗


Tags: andofthetoinposyouyour