Skip to content

Commit 37cff41

Browse files
committed
LeetCode 2543. Check if Point Is Reachable
1 parent 86b6a90 commit 37cff41

File tree

3 files changed

+140
-0
lines changed

3 files changed

+140
-0
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
393393
| [2389. Longest Subsequence With Limited Sum][lc2389] | 🟢 Easy | [![python](res/py.png)][lc2389py] |
394394
| [2421. Number of Good Paths][lc2421] | 🔴 Hard | [![python](res/py.png)][lc2421py] [![rust](res/rs.png)][lc2421rs] |
395395
| [2481. Minimum Cuts to Divide a Circle][lc2481] | 🟢 Easy | [![python](res/py.png)][lc2481py] |
396+
| [2543. Check if Point Is Reachable][lc2543] | 🔴 Hard | [![python](res/py.png)][lc2543py] [![rust](res/rs.png)][lc2543rs] |
396397

397398
[🔝 Back to Top 🔝](#coding-challenges)
398399

@@ -1160,6 +1161,9 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
11601161
[lc2421rs]: leetcode/number-of-good-paths.rs
11611162
[lc2481]: https://leetcode.com/problems/minimum-cuts-to-divide-a-circle/
11621163
[lc2481py]: leetcode/minimum-cuts-to-divide-a-circle.py
1164+
[lc2543]: https://leetcode.com/problems/check-if-point-is-reachable/
1165+
[lc2543py]: leetcode/check-if-point-is-reachable.py
1166+
[lc2543rs]: leetcode/check-if-point-is-reachable.rs
11631167

11641168
## CodeWars problems
11651169

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# 2543. Check if Point Is Reachable
2+
# 🔴 Hard
3+
#
4+
# https://leetcode.com/problems/check-if-point-is-reachable/
5+
#
6+
# Tags: Greedy - Dynamic Programming - Math
7+
8+
import timeit
9+
from math import gcd
10+
11+
12+
# Simulate the movements that are allowed but in reverse, starting at
13+
# the target point and trying to reach (1, 1).
14+
#
15+
# Time complexity: O(log(max(m, n))) - At each step we divide by 2
16+
# approximately, if one of the values is not divisible one loop, it will
17+
# became divisible in the next loop.
18+
# Space complexity: O(1) - We only store two integers and one tuple with
19+
# two elements.
20+
#
21+
# Runtime 33 ms Beats 100%
22+
# Memory 13.9 MB Beats 33.33%
23+
class GreedySimulation:
24+
def isReachable(self, targetX: int, targetY: int) -> bool:
25+
last, x, y = (-1, -1), targetX, targetY
26+
# While we make progress and have not matched the start.
27+
while (x, y) != last:
28+
if x == 1 and y == 1:
29+
return True
30+
last = (x, y)
31+
if x % 2 == 0:
32+
x //= 2
33+
if y % 2 == 0:
34+
y //= 2
35+
if x > y:
36+
x -= y
37+
if x < y:
38+
y -= x
39+
return False
40+
41+
42+
# Great solutions using the greater common divisor in the discuss
43+
# section. I liked one by lee215 in particular.
44+
# https://leetcode.com/problems/check-if-point-is-reachable/solutions/3082073
45+
#
46+
# Time complexity: O(log(m) + log(y))
47+
# Space complexity: O(1)
48+
#
49+
# Runtime 35 ms Beats 88.89%
50+
# Memory 13.8 MB Beats 44.44%
51+
class GCDPoT:
52+
def isReachable(self, targetX: int, targetY: int) -> bool:
53+
mcd = gcd(targetX, targetY)
54+
return mcd == mcd & -mcd
55+
56+
57+
def test():
58+
executors = [
59+
GreedySimulation,
60+
GCDPoT,
61+
]
62+
tests = [
63+
[6, 9, False],
64+
[4, 7, True],
65+
]
66+
for executor in executors:
67+
start = timeit.default_timer()
68+
for _ in range(1):
69+
for col, t in enumerate(tests):
70+
sol = executor()
71+
result = sol.isReachable(t[0], t[1])
72+
exp = t[2]
73+
assert result == exp, (
74+
f"\033[93m» {result} <> {exp}\033[91m for"
75+
+ f" test {col} using \033[1m{executor.__name__}"
76+
)
77+
stop = timeit.default_timer()
78+
used = str(round(stop - start, 5))
79+
cols = "{0:20}{1:10}{2:10}"
80+
res = cols.format(executor.__name__, used, "seconds")
81+
print(f"\033[92m» {res}\033[0m")
82+
83+
84+
test()
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// 2543. Check if Point Is Reachable
2+
// 🔴 Hard
3+
//
4+
// https://leetcode.com/problems/check-if-point-is-reachable/
5+
//
6+
// Tags: Greedy - Dynamic Programming - Math
7+
8+
struct Solution;
9+
impl Solution {
10+
// Simulate the movements that are allowed but in reverse, starting at
11+
// the target point and trying to reach (1, 1).
12+
//
13+
// Time complexity: O(log(max(m, n))) - At each step we divide by 2
14+
// approximately, if one of the values is not divisible one loop, it will
15+
// became divisible in the next loop.
16+
// Space complexity: O(1) - We only store two integers and one tuple with
17+
// two elements.
18+
//
19+
// Runtime 1 ms Beats 100%
20+
// Memory 2.2 MB Beats 100%
21+
pub fn is_reachable(target_x: i32, target_y: i32) -> bool {
22+
let mut last = (-1, -1);
23+
let mut x = target_x;
24+
let mut y = target_y;
25+
while (x, y) != last {
26+
if x == 1 && y == 1 {
27+
return true;
28+
}
29+
last = (x, y);
30+
while x % 2 == 0 {
31+
x /= 2;
32+
}
33+
while y % 2 == 0 {
34+
y /= 2;
35+
}
36+
if x > y {
37+
x -= y;
38+
}
39+
if y > x {
40+
y -= x
41+
}
42+
}
43+
false
44+
}
45+
}
46+
47+
// Tests.
48+
fn main() {
49+
assert_eq!(Solution::is_reachable(6, 9), false);
50+
assert_eq!(Solution::is_reachable(4, 7), true);
51+
println!("All tests passed!")
52+
}

0 commit comments

Comments
 (0)