From 2de47e54abd2ee89a3a283ecd4331600b1fd9f23 Mon Sep 17 00:00:00 2001 From: Seongbeom Park Date: Sun, 3 Apr 2022 14:16:48 +0900 Subject: [PATCH 01/11] request extra/bringing-a-gun-to-a-trainer-fight --- .../constraints.txt | 0 .../readme.txt | 47 +++++++++++++++++++ .../solution.py | 2 + .../disorderly-escape}/constraints.txt | 0 .../disorderly-escape/readme.txt | 0 .../disorderly-escape/solution.py | 0 extra/dodge-the-lasers/constraints.txt | 21 +++++++++ {level5 => extra}/dodge-the-lasers/readme.txt | 0 .../dodge-the-lasers/solution.py | 0 9 files changed, 70 insertions(+) rename {level5/disorderly-escape => extra/bringing-a-gun-to-a-trainer-fight}/constraints.txt (100%) create mode 100644 extra/bringing-a-gun-to-a-trainer-fight/readme.txt create mode 100644 extra/bringing-a-gun-to-a-trainer-fight/solution.py rename {level5/dodge-the-lasers => extra/disorderly-escape}/constraints.txt (100%) rename {level5 => extra}/disorderly-escape/readme.txt (100%) rename {level5 => extra}/disorderly-escape/solution.py (100%) create mode 100644 extra/dodge-the-lasers/constraints.txt rename {level5 => extra}/dodge-the-lasers/readme.txt (100%) rename {level5 => extra}/dodge-the-lasers/solution.py (100%) diff --git a/level5/disorderly-escape/constraints.txt b/extra/bringing-a-gun-to-a-trainer-fight/constraints.txt similarity index 100% rename from level5/disorderly-escape/constraints.txt rename to extra/bringing-a-gun-to-a-trainer-fight/constraints.txt diff --git a/extra/bringing-a-gun-to-a-trainer-fight/readme.txt b/extra/bringing-a-gun-to-a-trainer-fight/readme.txt new file mode 100644 index 0000000..4310409 --- /dev/null +++ b/extra/bringing-a-gun-to-a-trainer-fight/readme.txt @@ -0,0 +1,47 @@ +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. diff --git a/extra/bringing-a-gun-to-a-trainer-fight/solution.py b/extra/bringing-a-gun-to-a-trainer-fight/solution.py new file mode 100644 index 0000000..c01262b --- /dev/null +++ b/extra/bringing-a-gun-to-a-trainer-fight/solution.py @@ -0,0 +1,2 @@ +def​ ​solution(dimensions,​ ​your_position,​ ​trainer_position,​ ​distance): +​ ​​ ​​ ​​ ​#Your​ ​code​ ​here \ No newline at end of file diff --git a/level5/dodge-the-lasers/constraints.txt b/extra/disorderly-escape/constraints.txt similarity index 100% rename from level5/dodge-the-lasers/constraints.txt rename to extra/disorderly-escape/constraints.txt diff --git a/level5/disorderly-escape/readme.txt b/extra/disorderly-escape/readme.txt similarity index 100% rename from level5/disorderly-escape/readme.txt rename to extra/disorderly-escape/readme.txt diff --git a/level5/disorderly-escape/solution.py b/extra/disorderly-escape/solution.py similarity index 100% rename from level5/disorderly-escape/solution.py rename to extra/disorderly-escape/solution.py diff --git a/extra/dodge-the-lasers/constraints.txt b/extra/dodge-the-lasers/constraints.txt new file mode 100644 index 0000000..f201987 --- /dev/null +++ b/extra/dodge-the-lasers/constraints.txt @@ -0,0 +1,21 @@ +Java +==== +Your code will be compiled using standard Java 8. All tests will be run by calling the solution() method inside the Solution class + +Execution time is limited. + +Wildcard imports and some specific classes are restricted (e.g. java.lang.ClassLoader). You will receive an error when you verify your solution if you have used a blacklisted class. + +Third-party libraries, input/output operations, spawning threads or processes and changes to the execution environment are not allowed. + +Your solution must be under 32000 characters in length including new lines and and other non-printing characters. + +Python +====== +Your code will run inside a Python 2.7.13 sandbox. All tests will be run by calling the solution() function. + +Standard libraries are supported except for bz2, crypt, fcntl, mmap, pwd, pyexpat, select, signal, termios, thread, time, unicodedata, zipimport, zlib. + +Input/output operations are not allowed. + +Your solution must be under 32000 characters in length including new lines and and other non-printing characters. diff --git a/level5/dodge-the-lasers/readme.txt b/extra/dodge-the-lasers/readme.txt similarity index 100% rename from level5/dodge-the-lasers/readme.txt rename to extra/dodge-the-lasers/readme.txt diff --git a/level5/dodge-the-lasers/solution.py b/extra/dodge-the-lasers/solution.py similarity index 100% rename from level5/dodge-the-lasers/solution.py rename to extra/dodge-the-lasers/solution.py -- 2.47.2 From 9f746920734b784c235c3a5f47d96fdc7057ca8b Mon Sep 17 00:00:00 2001 From: Seongbeom Park Date: Sun, 3 Apr 2022 15:34:08 +0900 Subject: [PATCH 02/11] first try Verifying solution... Test 1 failed Test 2 passed! Test 3 failed [Hidden] Test 4 passed! [Hidden] Test 5 passed! [Hidden] Test 6 passed! [Hidden] Test 7 passed! [Hidden] Test 8 passed! [Hidden] Test 9 passed! [Hidden] Test 10 passed! [Hidden] --- .../solution.py | 64 ++++++++++++++++++- 1 file changed, 62 insertions(+), 2 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 c01262b..19867ab 100644 --- a/extra/bringing-a-gun-to-a-trainer-fight/solution.py +++ b/extra/bringing-a-gun-to-a-trainer-fight/solution.py @@ -1,2 +1,62 @@ -def​ ​solution(dimensions,​ ​your_position,​ ​trainer_position,​ ​distance): -​ ​​ ​​ ​​ ​#Your​ ​code​ ​here \ No newline at end of file +def solution(dimentions, your_position, trainer_position, distance): + direction_target_map = {} + for reflected_position, is_trainer in generate_relected_positions(dimentions, your_position, trainer_position, distance): + direction = reduce_direction((reflected_position[0] - your_position[0], reflected_position[1] - your_position[1])) + travel = travel_distance(your_position, reflected_position) + if (direction in direction_target_map): + if travel < direction_target_map[direction][0]: + direction_target_map[direction] = (travel, is_trainer) + else: + direction_target_map[direction] = (travel, is_trainer) + return len([k for k, (d, is_trainer) in direction_target_map.items() if is_trainer]) + +def generate_relected_positions(dimentions, your_position, trainer_position, distance): + room_width, room_height = dimentions + x_range = distance // room_width + 1 + y_range = distance // room_height + 1 + for room_x in range(-x_range, x_range): + for room_y in range(-y_range, 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_distance = travel_distance(your_position, reflected_your_position) + reflected_trainer_distance = travel_distance(your_position, reflected_trainer_position) + if reflected_your_distance <= distance: + yield reflected_your_position, False + if reflected_trainer_distance <= distance: + yield reflected_trainer_position, True + +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 reduce_direction(direction): + if direction[0] == 0 or direction[1] == 0: + return direction + gcd = abs_gcd(direction[0], direction[1]) + return direction[0]/gcd, direction[1]/gcd + +def travel_distance(origin, target): + return ((target[0] - origin[0])**2 + (target[1] - origin[1])**2) ** 0.5 + +tests = [ + (([3, 2], [1, 1], [2, 1], 4), 7), + (([300,275], [150,150], [185,100], 500), 9) +] + +for i, o in tests: + result = solution(*i) + print(i, result == o, result, o) -- 2.47.2 From 6bcc561a2e0e61e4d38e964d47b32c3cf5ce49bd Mon Sep 17 00:00:00 2001 From: Seongbeom Park Date: Sun, 3 Apr 2022 15:44:38 +0900 Subject: [PATCH 03/11] handling direction with zeros Verifying solution... Test 1 passed! Test 2 passed! Test 3 failed [Hidden] Test 4 passed! [Hidden] Test 5 passed! [Hidden] Test 6 passed! [Hidden] Test 7 passed! [Hidden] Test 8 passed! [Hidden] Test 9 passed! [Hidden] Test 10 passed! [Hidden] --- extra/bringing-a-gun-to-a-trainer-fight/solution.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 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 19867ab..25cc02c 100644 --- a/extra/bringing-a-gun-to-a-trainer-fight/solution.py +++ b/extra/bringing-a-gun-to-a-trainer-fight/solution.py @@ -1,6 +1,6 @@ def solution(dimentions, your_position, trainer_position, distance): direction_target_map = {} - for reflected_position, is_trainer in generate_relected_positions(dimentions, your_position, trainer_position, distance): + for reflected_position, is_trainer in generate_reflected_positions(dimentions, your_position, trainer_position, distance): direction = reduce_direction((reflected_position[0] - your_position[0], reflected_position[1] - your_position[1])) travel = travel_distance(your_position, reflected_position) if (direction in direction_target_map): @@ -10,7 +10,7 @@ def solution(dimentions, your_position, trainer_position, distance): direction_target_map[direction] = (travel, is_trainer) return len([k for k, (d, is_trainer) in direction_target_map.items() if is_trainer]) -def generate_relected_positions(dimentions, your_position, trainer_position, distance): +def generate_reflected_positions(dimentions, your_position, trainer_position, distance): room_width, room_height = dimentions x_range = distance // room_width + 1 y_range = distance // room_height + 1 @@ -44,8 +44,12 @@ def abs_gcd(x, y): return abs(m) def reduce_direction(direction): - if direction[0] == 0 or direction[1] == 0: - return direction + if direction[0] == 0 and direction[1] == 0: + return 0, 0 + elif direction[0] == 0: + return 0, direction[1] / abs(direction[1]) + elif direction[1] == 0: + return direction[0] / abs(direction[0]), 0 gcd = abs_gcd(direction[0], direction[1]) return direction[0]/gcd, direction[1]/gcd -- 2.47.2 From c10da560a42e2cd01a3c12c64355c22334e4f763 Mon Sep 17 00:00:00 2001 From: Seongbeom Park Date: Sun, 3 Apr 2022 16:22:34 +0900 Subject: [PATCH 04/11] iterate near room first Verifying solution... Test 1 passed! Test 2 passed! Test 3 failed [Hidden] Test 4 passed! [Hidden] Test 5 passed! [Hidden] Test 6 passed! [Hidden] Test 7 passed! [Hidden] Test 8 passed! [Hidden] Test 9 passed! [Hidden] Test 10 passed! [Hidden] --- .../solution.py | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 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 25cc02c..82cc86c 100644 --- a/extra/bringing-a-gun-to-a-trainer-fight/solution.py +++ b/extra/bringing-a-gun-to-a-trainer-fight/solution.py @@ -1,21 +1,26 @@ def solution(dimentions, your_position, trainer_position, distance): direction_target_map = {} - for reflected_position, is_trainer in generate_reflected_positions(dimentions, your_position, trainer_position, distance): - direction = reduce_direction((reflected_position[0] - your_position[0], reflected_position[1] - your_position[1])) - travel = travel_distance(your_position, reflected_position) + for reflected_position, direction, length, is_trainer in generate_reflected_positions(dimentions, your_position, trainer_position, distance): if (direction in direction_target_map): - if travel < direction_target_map[direction][0]: - direction_target_map[direction] = (travel, is_trainer) + if length < direction_target_map[direction][0]: + direction_target_map[direction] = (length, is_trainer) else: - direction_target_map[direction] = (travel, is_trainer) + direction_target_map[direction] = (length, is_trainer) return len([k for k, (d, is_trainer) in direction_target_map.items() if is_trainer]) +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_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 range(-x_range, x_range): - for room_y in range(-y_range, y_range): + 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 @@ -29,12 +34,18 @@ def generate_reflected_positions(dimentions, your_position, trainer_position, di 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_distance = travel_distance(your_position, reflected_your_position) - reflected_trainer_distance = travel_distance(your_position, reflected_trainer_position) - if reflected_your_distance <= distance: - yield reflected_your_position, False - if reflected_trainer_distance <= distance: - yield reflected_trainer_position, True + 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 def abs_gcd(x, y): m, n = abs(x), abs(y) @@ -43,6 +54,9 @@ def abs_gcd(x, y): m, n = n, t return abs(m) +def calc_direction(origin, target): + return reduce_direction((target[0] - origin[0], target[1] - origin[1])) + def reduce_direction(direction): if direction[0] == 0 and direction[1] == 0: return 0, 0 @@ -53,7 +67,7 @@ def reduce_direction(direction): gcd = abs_gcd(direction[0], direction[1]) return direction[0]/gcd, direction[1]/gcd -def travel_distance(origin, target): +def line_length(origin, target): return ((target[0] - origin[0])**2 + (target[1] - origin[1])**2) ** 0.5 tests = [ -- 2.47.2 From bbb6e568150eec3036a7054f7b210978bb9171d2 Mon Sep 17 00:00:00 2001 From: Seongbeom Park Date: Sun, 3 Apr 2022 17:24:59 +0900 Subject: [PATCH 05/11] 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: -- 2.47.2 From 26d04b4f0864f87229442dab9a7dd85fdbd736fb Mon Sep 17 00:00:00 2001 From: Seongbeom Park Date: Sun, 3 Apr 2022 17:36:19 +0900 Subject: [PATCH 06/11] reduce sqrt calculation Verifying solution... Test 1 passed! Test 2 passed! Test 3 failed [Hidden] Test 4 passed! [Hidden] Test 5 passed! [Hidden] Test 6 passed! [Hidden] Test 7 passed! [Hidden] Test 8 passed! [Hidden] Test 9 passed! [Hidden] Test 10 passed! [Hidden] --- .../solution.py | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 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 23f76b8..4995414 100644 --- a/extra/bringing-a-gun-to-a-trainer-fight/solution.py +++ b/extra/bringing-a-gun-to-a-trainer-fight/solution.py @@ -2,21 +2,14 @@ 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): + for position, direction, is_trainer in generate_reflected_positions(dimentions, your_position, trainer_position, distance): 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) + prev_is_trainer, prev_position = direction_target_map[direction] + if abs(position[0] - your_position[0]) < abs(prev_position[0] - your_position[0]): + direction_target_map[direction] = (is_trainer, position) else: - if is_trainer: - count += 1 - direction_target_map[direction] = (length, is_trainer) - return count + direction_target_map[direction] = (is_trainer, position) + return len([0 for d, (is_trainer, position) in direction_target_map.items() if is_trainer and line_length(your_position, position) <= distance]) def generate_room_id(dimentions, your_position, distance): memo = [] @@ -53,15 +46,11 @@ def generate_reflected_positions(dimentions, your_position, trainer_position, di 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 + yield reflected_your_position, your_direction, 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 + yield reflected_trainer_position, trainer_direction, True memo[your_direction] = 0 memo[trainer_direction] = 0 -- 2.47.2 From 9a4dfda57835afdeeb2de3867fc43a2be06392f6 Mon Sep 17 00:00:00 2001 From: Seongbeom Park Date: Sun, 3 Apr 2022 18:19:18 +0900 Subject: [PATCH 07/11] reduce using sqrt operation Verifying solution... Test 1 passed! Test 2 passed! Test 3 failed [Hidden] Test 4 passed! [Hidden] Test 5 passed! [Hidden] Test 6 passed! [Hidden] Test 7 passed! [Hidden] Test 8 passed! [Hidden] Test 9 passed! [Hidden] Test 10 passed! [Hidden] --- .../solution.py | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 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 4995414..c616589 100644 --- a/extra/bringing-a-gun-to-a-trainer-fight/solution.py +++ b/extra/bringing-a-gun-to-a-trainer-fight/solution.py @@ -1,26 +1,25 @@ import math def solution(dimentions, your_position, trainer_position, distance): - direction_target_map = {} - for position, direction, is_trainer in generate_reflected_positions(dimentions, your_position, trainer_position, distance): - if direction in direction_target_map: - prev_is_trainer, prev_position = direction_target_map[direction] + nearest_target = {} + for position, is_trainer in generate_reflected_positions(dimentions, your_position, trainer_position, distance): + direction = calc_direction(your_position, position) + if direction in nearest_target: + prev_position, prev_is_trainer = nearest_target[direction] if abs(position[0] - your_position[0]) < abs(prev_position[0] - your_position[0]): - direction_target_map[direction] = (is_trainer, position) + nearest_target[direction] = (position, is_trainer) else: - direction_target_map[direction] = (is_trainer, position) - return len([0 for d, (is_trainer, position) in direction_target_map.items() if is_trainer and line_length(your_position, position) <= distance]) + nearest_target[direction] = (position, is_trainer) + return len([0 for d, (position, is_trainer) in nearest_target.items() if is_trainer and line_length(your_position, position) <= distance]) def generate_room_id(dimentions, your_position, distance): memo = [] - room_width, room_height = dimentions + room_width = dimentions[0] + room_height = dimentions[1] 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: @@ -29,30 +28,30 @@ def generate_room_id(dimentions, your_position, distance): yield - room_x - 1, - room_y - 1 def generate_reflected_positions(dimentions, your_position, trainer_position, distance): - memo = {} room_width, room_height = dimentions 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 + x_base = room_x*room_width + y_base = room_y*room_height + your_x_offset = your_position[0] + your_y_offset = your_position[1] + trainer_x_offset = trainer_position[0] + trainer_y_offset = trainer_position[1] if (x_reflected): - your_x_offset = room_width - your_x_offset - trainer_x_offset = room_width - trainer_x_offset + reflected_your_x_position = x_base + room_width - your_x_offset + reflected_trainer_x_position = x_base + room_width - trainer_x_offset + else: + reflected_your_x_position = x_base + your_x_offset + reflected_trainer_x_position = x_base + 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: - yield reflected_your_position, your_direction, 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: - yield reflected_trainer_position, trainer_direction, True - memo[your_direction] = 0 - memo[trainer_direction] = 0 + reflected_your_y_position = y_base + room_height - your_y_offset + reflected_trainer_y_position = y_base + room_height - trainer_y_offset + else: + reflected_your_y_position = y_base + your_y_offset + reflected_trainer_y_position = y_base + trainer_y_offset + yield (reflected_your_x_position, reflected_your_y_position), False + yield (reflected_trainer_x_position, reflected_trainer_y_position), True def abs_gcd(x, y): m, n = abs(x), abs(y) @@ -62,14 +61,15 @@ def abs_gcd(x, y): return m def reduce_direction(direction): - if direction[0] == 0 and direction[1] == 0: + x, y = direction + if x == 0 and y == 0: return 0, 0 - elif direction[0] == 0: - return 0, (1 if direction[1] > 0 else -1) - elif direction[1] == 0: - return (1 if direction[0] > 0 else -1), 0 - gcd = abs_gcd(direction[0], direction[1]) - return direction[0]/gcd, direction[1]/gcd + elif x == 0: + return 0, (1 if y > 0 else -1) + elif y == 0: + return (1 if x > 0 else -1), 0 + gcd = abs_gcd(x, y) + return x/gcd, y/gcd def calc_direction(origin, target): return reduce_direction((target[0] - origin[0], target[1] - origin[1])) @@ -80,9 +80,9 @@ def line_length(origin, target): tests = [ (([3, 2], [1, 1], [2, 1], 4), 7), (([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), + (([300,275], [150,150], [185,100], 2), 0), + # (([3, 2], [1, 1], [2, 1], 10000), 1), ] for i, o in tests: -- 2.47.2 From efeed5bf55428e8ccdbb9699bf0957a19b13cf29 Mon Sep 17 00:00:00 2001 From: Seongbeom Park Date: Sun, 3 Apr 2022 20:01:34 +0900 Subject: [PATCH 08/11] change how to count the result --- .../solution.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 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 c616589..c745adf 100644 --- a/extra/bringing-a-gun-to-a-trainer-fight/solution.py +++ b/extra/bringing-a-gun-to-a-trainer-fight/solution.py @@ -2,7 +2,7 @@ import math def solution(dimentions, your_position, trainer_position, distance): nearest_target = {} - for position, is_trainer in generate_reflected_positions(dimentions, your_position, trainer_position, distance): + for position, is_trainer in generate_positions(dimentions, your_position, trainer_position, distance): direction = calc_direction(your_position, position) if direction in nearest_target: prev_position, prev_is_trainer = nearest_target[direction] @@ -10,7 +10,7 @@ def solution(dimentions, your_position, trainer_position, distance): nearest_target[direction] = (position, is_trainer) else: nearest_target[direction] = (position, is_trainer) - return len([0 for d, (position, is_trainer) in nearest_target.items() if is_trainer and line_length(your_position, position) <= distance]) + return sum(1 for (position, is_trainer) in nearest_target.values() if is_trainer and line_length(your_position, position) <= distance) def generate_room_id(dimentions, your_position, distance): memo = [] @@ -27,7 +27,7 @@ def generate_room_id(dimentions, your_position, distance): yield room_x, - room_y - 1 yield - room_x - 1, - room_y - 1 -def generate_reflected_positions(dimentions, your_position, trainer_position, distance): +def generate_positions(dimentions, your_position, trainer_position, distance): room_width, room_height = dimentions for room_x, room_y in generate_room_id(dimentions, your_position, distance): x_reflected = room_x % 2 == 1 @@ -53,8 +53,7 @@ def generate_reflected_positions(dimentions, your_position, trainer_position, di yield (reflected_your_x_position, reflected_your_y_position), False yield (reflected_trainer_x_position, reflected_trainer_y_position), True -def abs_gcd(x, y): - m, n = abs(x), abs(y) +def gcd(m, n): while n != 0: t = m % n m, n = n, t @@ -68,8 +67,8 @@ def reduce_direction(direction): return 0, (1 if y > 0 else -1) elif y == 0: return (1 if x > 0 else -1), 0 - gcd = abs_gcd(x, y) - return x/gcd, y/gcd + g = gcd(abs(x), abs(y)) + return x/g, y/g def calc_direction(origin, target): return reduce_direction((target[0] - origin[0], target[1] - origin[1])) @@ -82,7 +81,8 @@ tests = [ (([300,275], [150,150], [185,100], 500), 9), (([3, 2], [1, 1], [2, 1], 2), 1), (([300,275], [150,150], [185,100], 2), 0), - # (([3, 2], [1, 1], [2, 1], 10000), 1), + (([3, 2], [1, 1], [2, 1], 1000), 397845), + (([30, 20], [10, 10], [20, 10], 10000), 397845), ] for i, o in tests: -- 2.47.2 From 23b848f68c24d462cc3661734fdedddb5787d094 Mon Sep 17 00:00:00 2001 From: Seongbeom Park Date: Sun, 3 Apr 2022 20:33:12 +0900 Subject: [PATCH 09/11] update solution --- extra/bringing-a-gun-to-a-trainer-fight/solution.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 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 c745adf..bc4d031 100644 --- a/extra/bringing-a-gun-to-a-trainer-fight/solution.py +++ b/extra/bringing-a-gun-to-a-trainer-fight/solution.py @@ -13,19 +13,13 @@ def solution(dimentions, your_position, trainer_position, distance): return sum(1 for (position, is_trainer) in nearest_target.values() if is_trainer and line_length(your_position, position) <= distance) def generate_room_id(dimentions, your_position, distance): - memo = [] room_width = dimentions[0] room_height = dimentions[1] 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): - memo += [(room_x, room_y)] + for room_x in range(-x_range, x_range): + for room_y in range(-y_range, y_range): 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_positions(dimentions, your_position, trainer_position, distance): room_width, room_height = dimentions -- 2.47.2 From 10ea977e282012248796ce893a8045605506c420 Mon Sep 17 00:00:00 2001 From: Seongbeom Park Date: Tue, 5 Apr 2022 13:48:33 +0900 Subject: [PATCH 10/11] Reduce iteration by cutting rectangle to circle Verifying solution... All test cases passed. Use submit solution.py to submit your solution --- .../solution.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 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 bc4d031..29d61fa 100644 --- a/extra/bringing-a-gun-to-a-trainer-fight/solution.py +++ b/extra/bringing-a-gun-to-a-trainer-fight/solution.py @@ -6,7 +6,7 @@ def solution(dimentions, your_position, trainer_position, distance): direction = calc_direction(your_position, position) if direction in nearest_target: prev_position, prev_is_trainer = nearest_target[direction] - if abs(position[0] - your_position[0]) < abs(prev_position[0] - your_position[0]): + if abs(position[0] - your_position[0]) < abs(prev_position[0] - your_position[0]) or abs(position[1] - your_position[1]) < abs(prev_position[1] - your_position[1]): nearest_target[direction] = (position, is_trainer) else: nearest_target[direction] = (position, is_trainer) @@ -17,9 +17,17 @@ def generate_room_id(dimentions, your_position, distance): room_height = dimentions[1] x_range = distance / room_width + 1 y_range = distance / room_height + 1 - for room_x in range(-x_range, x_range): - for room_y in range(-y_range, y_range): - yield room_x, room_y + boundary = {0: y_range + 1} + for x in range(1, x_range): + while line_length(your_position, (x*room_width, y_range*room_height)) > distance and y_range > 0: + y_range -= 1 + boundary[x] = y_range + 1 + for x in range(x_range): + for y in range(boundary[x]): + yield x, y + yield x, - y - 1 + yield - x - 1, y + yield - x - 1, - y - 1 def generate_positions(dimentions, your_position, trainer_position, distance): room_width, room_height = dimentions -- 2.47.2 From a99ef0ae81d6c50a6144ca7f6ec3bba99bf241cb Mon Sep 17 00:00:00 2001 From: Seongbeom Park Date: Tue, 5 Apr 2022 13:53:04 +0900 Subject: [PATCH 11/11] Update Readme --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6cefd6f..b36f423 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,12 @@ * Completed in: 6 hrs, 49 mins, 26 secs. * DP & Optimization +## Encrypted message +CFcSBwgCCBoHRhkKU1cGAA4AGU5YQR5THBwNFwoGGAxTQQMQVBUSBg4EAAwQRhUQVBUHFAQTGRpT QQMQVBkPERkECQAWDVwXX1BGEwgJBAwCBFRVHQRGUlFBShwaDVZTGBUFVUdBShsVA1tZBwNGUlFB ShoVB1wXX1BGFAQOSklOQR5HGh5AVRY= + +## Extra +* Requested problems after level 5 clear + ### dodge-the-laser * Completed in: 2 days, 20 hrs, 22 mins, 39 secs. * References @@ -42,6 +48,6 @@ * Reference * [Burnside's lemma: counting up to symmetries, Youtube](https://www.youtube.com/watch?v=D0d9bYZ_qDY) -## Encrypted message -CFcSBwgCCBoHRhkKU1cGAA4AGU5YQR5THBwNFwoGGAxTQQMQVBUSBg4EAAwQRhUQVBUHFAQTGRpT QQMQVBkPERkECQAWDVwXX1BGEwgJBAwCBFRVHQRGUlFBShwaDVZTGBUFVUdBShsVA1tZBwNGUlFB ShoVB1wXX1BGFAQOSklOQR5HGh5AVRY= +### bringing-a-gun-to-a-trainer-fight +* Completed in: 1 day, 23 hrs, 49 mins, 54 secs. -- 2.47.2