From bbb6e568150eec3036a7054f7b210978bb9171d2 Mon Sep 17 00:00:00 2001 From: Seongbeom Park Date: Sun, 3 Apr 2022 17:24:59 +0900 Subject: [PATCH] memo some more variables --- .../solution.py | 111 +++++++++++------- 1 file changed, 66 insertions(+), 45 deletions(-) diff --git a/extra/bringing-a-gun-to-a-trainer-fight/solution.py b/extra/bringing-a-gun-to-a-trainer-fight/solution.py index 82cc86c..23f76b8 100644 --- a/extra/bringing-a-gun-to-a-trainer-fight/solution.py +++ b/extra/bringing-a-gun-to-a-trainer-fight/solution.py @@ -1,78 +1,99 @@ +import math + def solution(dimentions, your_position, trainer_position, distance): direction_target_map = {} + count = 0 for reflected_position, direction, length, is_trainer in generate_reflected_positions(dimentions, your_position, trainer_position, distance): - if (direction in direction_target_map): - if length < direction_target_map[direction][0]: + if direction in direction_target_map: + prev_length, prev_is_trainer = direction_target_map[direction] + if length < prev_length: + if is_trainer and ~prev_is_trainer: + count += 1 + elif ~is_trainer and prev_is_trainer: + count -= 1 direction_target_map[direction] = (length, is_trainer) else: + if is_trainer: + count += 1 direction_target_map[direction] = (length, is_trainer) - return len([k for k, (d, is_trainer) in direction_target_map.items() if is_trainer]) + return count -def generate_room_id(max): - for room_id in range(max): - yield room_id - for room_id in range(max): - yield - room_id - 1 +def generate_room_id(dimentions, your_position, distance): + memo = [] + room_width, room_height = dimentions + x_range = distance / room_width + 1 + y_range = distance / room_height + 1 + for room_x in range(x_range): + for room_y in range(y_range): + if room_x != 0 and room_y != 0: + if line_length(dimentions, (room_x*dimentions[0], room_y*dimentions[1])) > distance: + continue + memo += [(room_x, room_y)] + yield room_x, room_y + for room_x, room_y in memo: + yield - room_x - 1, room_y + yield room_x, - room_y - 1 + yield - room_x - 1, - room_y - 1 def generate_reflected_positions(dimentions, your_position, trainer_position, distance): memo = {} room_width, room_height = dimentions - x_range = distance // room_width + 1 - y_range = distance // room_height + 1 - for room_x in generate_room_id(x_range): - for room_y in generate_room_id(y_range): - x_reflected = room_x % 2 == 1 - y_reflected = room_y % 2 == 1 - x_base, y_base = room_x*room_width, room_y*room_height - your_x_offset, your_y_offset = your_position - trainer_x_offset, trainer_y_offset = trainer_position - if (x_reflected): - your_x_offset = room_width - your_x_offset - trainer_x_offset = room_width - trainer_x_offset - if (y_reflected): - your_y_offset = room_height - your_y_offset - trainer_y_offset = room_height - trainer_y_offset - reflected_your_position = x_base + your_x_offset, y_base + your_y_offset - reflected_trainer_position = x_base + trainer_x_offset, y_base + trainer_y_offset - reflected_your_direction = calc_direction(your_position, reflected_your_position) - reflected_trainer_direction = calc_direction(your_position, reflected_trainer_position) - if reflected_your_direction not in memo: - reflected_your_distance = line_length(your_position, reflected_your_position) - if reflected_your_distance <= distance: - yield reflected_your_position, reflected_your_direction, reflected_your_distance, False - if reflected_trainer_direction not in memo: - reflected_trainer_distance = line_length(your_position, reflected_trainer_position) - if reflected_trainer_distance <= distance: - yield reflected_trainer_position, reflected_trainer_direction, reflected_trainer_distance, True - memo[reflected_your_direction] = 0 - memo[reflected_trainer_direction] = 0 + for room_x, room_y in generate_room_id(dimentions, your_position, distance): + x_reflected = room_x % 2 == 1 + y_reflected = room_y % 2 == 1 + x_base, y_base = room_x*room_width, room_y*room_height + your_x_offset, your_y_offset = your_position + trainer_x_offset, trainer_y_offset = trainer_position + if (x_reflected): + your_x_offset = room_width - your_x_offset + trainer_x_offset = room_width - trainer_x_offset + if (y_reflected): + your_y_offset = room_height - your_y_offset + trainer_y_offset = room_height - trainer_y_offset + reflected_your_position = x_base + your_x_offset, y_base + your_y_offset + your_direction = calc_direction(your_position, reflected_your_position) + if your_direction not in memo: + reflected_your_distance = line_length(your_position, reflected_your_position) + if reflected_your_distance <= distance: + yield reflected_your_position, your_direction, reflected_your_distance, False + reflected_trainer_position = x_base + trainer_x_offset, y_base + trainer_y_offset + trainer_direction = calc_direction(your_position, reflected_trainer_position) + if trainer_direction not in memo: + reflected_trainer_distance = line_length(your_position, reflected_trainer_position) + if reflected_trainer_distance <= distance: + yield reflected_trainer_position, trainer_direction, reflected_trainer_distance, True + memo[your_direction] = 0 + memo[trainer_direction] = 0 def abs_gcd(x, y): m, n = abs(x), abs(y) while n != 0: t = m % n m, n = n, t - return abs(m) - -def calc_direction(origin, target): - return reduce_direction((target[0] - origin[0], target[1] - origin[1])) + return m def reduce_direction(direction): if direction[0] == 0 and direction[1] == 0: return 0, 0 elif direction[0] == 0: - return 0, direction[1] / abs(direction[1]) + return 0, (1 if direction[1] > 0 else -1) elif direction[1] == 0: - return direction[0] / abs(direction[0]), 0 + return (1 if direction[0] > 0 else -1), 0 gcd = abs_gcd(direction[0], direction[1]) return direction[0]/gcd, direction[1]/gcd +def calc_direction(origin, target): + return reduce_direction((target[0] - origin[0], target[1] - origin[1])) + def line_length(origin, target): - return ((target[0] - origin[0])**2 + (target[1] - origin[1])**2) ** 0.5 + return math.sqrt((target[0] - origin[0])**2 + (target[1] - origin[1])**2) tests = [ (([3, 2], [1, 1], [2, 1], 4), 7), - (([300,275], [150,150], [185,100], 500), 9) + (([300,275], [150,150], [185,100], 500), 9), + (([3, 2], [1, 1], [2, 1], 1), 1), + (([3, 2], [1, 1], [2, 1], 2), 1), + #(([3, 2], [1, 1], [2, 1], 10000), 1), ] for i, o in tests: