Skip to content

Commit 47e6163

Browse files
committed
add exercise
1 parent 0508e6c commit 47e6163

File tree

6 files changed

+163
-11
lines changed

6 files changed

+163
-11
lines changed

assets/.DS_Store

6 KB
Binary file not shown.
Loading
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import 'dart:math';
2+
3+
import 'package:leetcode/models/list_node.dart';
4+
5+
/// https://leetcode.com/problems/check-if-the-rectangle-corner-is-reachable/
6+
/// You are given two positive integers xCorner and yCorner, and a 2D array circles, where circles[i] = [xi, yi, ri] denotes a circle with center at (xi, yi) and radius ri.
7+
///
8+
/// There is a rectangle in the coordinate plane with its bottom left corner at the origin and top right corner at the coordinate (xCorner, yCorner). You need to check whether there is a path from the bottom left corner to the top right corner /// such that the entire path lies inside the rectangle, does not touch or lie inside any circle, and touches the rectangle only at the two corners.
9+
///
10+
/// Return true if such a path exists, and false otherwise.
11+
///
12+
///
13+
///
14+
/// Example 1:
15+
///
16+
/// Input: xCorner = 3, yCorner = 4, circles = [[2,1,1]]
17+
/// Output: true
18+
/// [assets/check_if_rectangle_corner_is_reachable/example2circle1.png]
19+
/// The black curve shows a possible path between (0, 0) and (3, 4).
20+
///
21+
/// Example 2:
22+
///
23+
/// Input: xCorner = 3, yCorner = 3, circles = [[1,1,2]]
24+
/// Ouput: false
25+
/// [assets/check_if_rectangle_corner_is_reachable/example1circle.png]
26+
/// No path exists from (0, 0) to (3, 3).
27+
///
28+
/// Example 3:
29+
/// Input: xCorner = 3, yCorner = 3, circles = [[2,1,1],[1,2,1]]
30+
/// Output: false
31+
/// [assets/check_if_rectangle_corner_is_reachable/example0circle.png]
32+
/// No path exists from (0, 0) to (3, 3).
33+
class CheckIfRectangleCornerIsReachable {
34+
List<bool> visited = [];
35+
List<List<int>> circles = [];
36+
int xCorner = 0, yCorner = 0;
37+
38+
bool canReachCorner(int xCorner, int yCorner, List<List<int>> circles) {
39+
// Initialize variables
40+
int n = circles.length;
41+
this.circles = circles;
42+
this.xCorner = xCorner;
43+
this.yCorner = yCorner;
44+
visited = List.generate(n, (i) => false);
45+
46+
// for every circle
47+
for (int i = 0; i < n; i++) {
48+
final circle = circles[i];
49+
int x = circle[0], y = circle[1], r = circle[2];
50+
// Check whether the circle is inside the origin (0,0) and the corner (xCorner, yCorner)
51+
if (_inCircle(0, 0, x, y, r) || _inCircle(xCorner, yCorner, x, y, r)) {
52+
return false;
53+
}
54+
if (!visited[i] && _crossLeftTop(x, y, r) && _dfs(i)) {
55+
return false;
56+
}
57+
}
58+
return true;
59+
}
60+
61+
/// This function checks whether the vertex (x,y)
62+
/// is inside the circle with origin (circleX, circleY) with radius r
63+
bool _inCircle(int x, int y, int circleX, int circleY, int r) {
64+
return pow((x - circleX), 2) + pow((y - circleY), 2) <= pow(r, 2);
65+
}
66+
67+
/// This function checks whether the circle with origin (circleX, circleY)
68+
/// with radius r is crossing the left or top side of the square
69+
bool _crossLeftTop(int circleX, int circleY, int r) {
70+
final bool a = circleX.abs() <= r && (circleY >= 0 && circleY <= yCorner);
71+
final bool b =
72+
(circleY - yCorner).abs() <= r && (circleX >= 0 && circleX <= xCorner);
73+
return a || b;
74+
}
75+
76+
/// This function checks whether the circle with origin (ci
77+
bool _crossRightBottom(int circleX, int circleY, int r) {
78+
final bool a =
79+
(circleX - xCorner).abs() <= r && (circleY >= 0 && circleY <= yCorner);
80+
final bool b = circleY.abs() <= r && (circleX >= 0 && circleX <= xCorner);
81+
return a || b;
82+
}
83+
84+
bool _dfs(int i) {
85+
final circle = circles[i];
86+
int x1 = circle[0], y1 = circle[1], r1 = circle[2];
87+
if (_crossRightBottom(x1, y1, r1)) {
88+
return true;
89+
}
90+
visited[i] = true;
91+
for (int j = 0; j < circles.length; j++) {
92+
final circle2 = circles[j];
93+
int x2 = circle2[0], y2 = circle2[1], r2 = circle2[2];
94+
if (visited[j]) {
95+
continue;
96+
}
97+
if (pow((x1 - x2), 2) + pow((y1 - y2), 2) > pow(r1 + r2, 2)) {
98+
continue;
99+
}
100+
if (x1 * r2 + x2 * r1 < (r1 + r2) * xCorner &&
101+
y1 * r2 + y2 * r1 < (r1 + r2) * yCorner &&
102+
_dfs(j)) {
103+
return true;
104+
}
105+
}
106+
return false;
107+
}
108+
}

test/leetcode_test.dart

+55-11
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
11
import 'package:leetcode/exercises/add_two_numbers.dart';
2+
import 'package:leetcode/exercises/check_if_rectangle_corner_is_reachable.dart';
23
import 'package:leetcode/models/list_node.dart';
34
import 'package:test/test.dart';
45

56
void main() {
6-
group("Other Exercises", (){
7-
exercise();
7+
group("Other Exercises", () {
8+
group("Medium", () {
9+
_mediumExercises();
10+
});
11+
group("Hard", () {
12+
_hardExercises();
13+
});
814
});
915
}
1016

11-
void exercise() {
17+
// region Medium
18+
19+
void _mediumExercises() {
20+
_addTwoNumbers();
21+
}
22+
23+
void _addTwoNumbers() {
1224
test("add two numbers", () {
1325
final addTwoNumbers = AddTwoNumbers();
1426
expect(
@@ -23,9 +35,9 @@ void exercise() {
2335
expect(
2436
addTwoNumbers
2537
.addTwoNumbers(
26-
ListNode.generateFromList([1, 2, 3]),
27-
ListNode.generateFromList([1, 2, 7, 4]),
28-
)
38+
ListNode.generateFromList([1, 2, 3]),
39+
ListNode.generateFromList([1, 2, 7, 4]),
40+
)
2941
?.toList(),
3042
[2, 4, 0, 5],
3143
);
@@ -45,17 +57,49 @@ void exercise() {
4557
ListNode.generateFromList([9, 9, 9, 9]),
4658
)
4759
?.toList(),
48-
[8, 9, 9, 9, 0, 0, 0, 1],
60+
[8, 9, 9, 9, 0, 0, 0, 1]
4961
);
5062
expect(
5163
addTwoNumbers
5264
.addTwoNumbers(
53-
ListNode.generateFromList([1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]),
54-
ListNode.generateFromList([5,6,4]),
55-
)
65+
ListNode.generateFromList([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]),
66+
ListNode.generateFromList([5, 6, 4]))
5667
?.toList(),
57-
[6,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
68+
[6, 6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
5869
);
70+
});
71+
}
72+
73+
// endregion
5974

75+
// region Hard
76+
77+
void _hardExercises() {
78+
_checkIfRectangleCornerIsReachable();
79+
}
80+
81+
void _checkIfRectangleCornerIsReachable() {
82+
test("check if rectangle corner is reachable", () {
83+
final checkIfRectangleCornerIsReachable =
84+
CheckIfRectangleCornerIsReachable();
85+
expect(
86+
checkIfRectangleCornerIsReachable.canReachCorner(3, 4, [
87+
[2, 1, 1]
88+
]),
89+
true);
90+
expect(
91+
checkIfRectangleCornerIsReachable.canReachCorner(3, 3, [
92+
[2, 1, 1],
93+
[1, 2, 1]
94+
]),
95+
false);
96+
expect(
97+
checkIfRectangleCornerIsReachable.canReachCorner(4, 4, [
98+
[5, 5, 1]
99+
]),
100+
true);
101+
expect(checkIfRectangleCornerIsReachable.canReachCorner(3, 3, [[2, 1000, 997], [1000,2,997]]), true);
60102
});
61103
}
104+
105+
// endregion

0 commit comments

Comments
 (0)