Skip to content

Commit ec7bf4d

Browse files
authored
Merge pull request #117 from BrianLusina/feat/rectangle-aread
feat(puzzles, math): rectangle area and max consecutive ones
2 parents 6b8bcc5 + bc0b23d commit ec7bf4d

File tree

7 files changed

+154
-13
lines changed

7 files changed

+154
-13
lines changed

DIRECTORY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,8 @@
704704
* [Test Pascals Triangle](https://github.com/BrianLusina/PythonSnips/blob/master/pymath/pascals_triangle/test_pascals_triangle.py)
705705
* Perfect Square
706706
* [Test Perfect Squares](https://github.com/BrianLusina/PythonSnips/blob/master/pymath/perfect_square/test_perfect_squares.py)
707+
* Rectangle Area
708+
* [Test Compute Area](https://github.com/BrianLusina/PythonSnips/blob/master/pymath/rectangle_area/test_compute_area.py)
707709
* Super Size
708710
* [Test Super Size](https://github.com/BrianLusina/PythonSnips/blob/master/pymath/super_size/test_super_size.py)
709711
* Triangles

puzzles/arrays/max_consecutive_ones/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ Explanation: [0,0,1,1,*1*,*1*,1,1,1,*1*,1,1,0,0,0,1,1,1,1]
1919
starred numbers were flipped from 0 to 1. The longest subarray is [1,1,1,1,1,1,1,1,1,1].
2020
```
2121

22+
## Max consecutive ones two
23+
24+
You are given a binary array nums (an array that contains only 0s and 1s). Your task is to find the maximum number of
25+
consecutive 1s in the array and return it.
26+
27+
### Constraints
28+
29+
- 1 ≤ `nums.length` ≤ 10^3
30+
- `nums[i` is either 0 or 1
31+
2232
## Related Topics
2333

2434
- Array

puzzles/arrays/max_consecutive_ones/__init__.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,36 @@ def longest_ones(nums: List[int], k: int) -> int:
2020
left += 1
2121

2222
return right - left + 1
23+
24+
def find_max_consecutive_ones(nums: List[int]) -> int:
25+
"""
26+
Finds the maximum consecutive ones in a binary array and returns it.
27+
28+
The most straightforward way to solve this is to use a single pass through the array, keeping track of two values
29+
as we go. First, we need a counter for the current streak of consecutive 1s we're seeing. Second, we need to
30+
remember the maximum streak we've encountered so far.
31+
32+
As we examine each element, if we see a 1, we increment our current streak counter. If we see a 0, that breaks our
33+
streak, so we reset the counter to 0. Importantly, every time we update our current streak, we check whether it's
34+
larger than our maximum and update the maximum if needed.
35+
36+
Time complexity is O(n) where n is the length of the input array
37+
Space complexity is O(1) as no extra space is required
38+
39+
Args:
40+
nums(list): a list of 1s and 0s.
41+
Returns:
42+
int: maximum number of consecutive 1s in the nums binary array
43+
"""
44+
if len(nums) == 0:
45+
return 0
46+
max_ones = 0
47+
current_consecutive = 0
48+
49+
for num in nums:
50+
if num == 1:
51+
current_consecutive += 1
52+
max_ones = max(max_ones, current_consecutive)
53+
else:
54+
current_consecutive = 0
55+
return max_ones

puzzles/arrays/max_consecutive_ones/test_max_consecutive_ones.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
import unittest
2-
3-
from . import longest_ones
2+
from typing import List
3+
from parameterized import parameterized
4+
from puzzles.arrays.max_consecutive_ones import longest_ones, find_max_consecutive_ones
45

56

67
class MaxConsecutiveOnesTestCase(unittest.TestCase):
7-
def test_one(self):
8-
"""should return 6 from nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2"""
9-
nums = [1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0]
10-
k = 2
11-
expected = 6
8+
9+
@parameterized.expand([
10+
([1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0], 2, 6),
11+
([0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1], 3, 10),
12+
])
13+
def test_longest_ones(self, nums: List[int], k: int, expected: int):
1214
actual = longest_ones(nums, k)
1315
self.assertEqual(expected, actual)
1416

15-
def test_two(self):
16-
"""should return 10 from nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], k = 3"""
17-
nums = [0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1]
18-
k = 3
19-
expected = 10
20-
actual = longest_ones(nums, k)
17+
@parameterized.expand([
18+
([1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0], 4),
19+
([0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1], 4),
20+
([1,1,0,0,1,1,1,0,0,1,0], 3),
21+
([1,1,0,0,1,1], 2),
22+
([1,1,1,0,1,1,1,1], 4),
23+
([0,0,0,0], 0),
24+
])
25+
def test_find_max_consecutive_ones(self, nums: List[int], expected: int):
26+
actual = find_max_consecutive_ones(nums)
2127
self.assertEqual(expected, actual)
2228

2329

pymath/rectangle_area/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Rectangle Area
2+
3+
You are given the coordinates of two axis-aligned rectangles in a 2D plane. Your task is to calculate the total area
4+
covered by both rectangles.
5+
6+
The first rectangle is specified by the coordinates of its bottom-left corner (ax1, ay1) and top-right corner (ay1, ay2).
7+
8+
Similarly, the second rectangle is defined by its bottom-left corner (bx1, by1) and top-right corner (bx2, by2).
9+
10+
> Note: The rectangles may overlap.
11+
12+
## Constraints
13+
14+
1. -10^4 ≤ ax1 ≤ ax2 ≤ 10^4
15+
2. −10^4 ≤ ay1 ≤ ay2 ≤ 10^4
16+
3. −10^4 ≤ bx1 ≤ bx2 ≤10^4
17+
4. −10^4 ≤ by1 ≤ by2 ≤ 10^4
18+
19+
## Examples
20+
21+
![Example 1](./images/examples/rectangle_area_example_1.png)
22+
![Example 2](./images/examples/rectangle_area_example_2.png)
23+
![Example 3](./images/examples/rectangle_area_example_3.png)
24+
![Example 4](./images/examples/rectangle_area_example_4.png)

pymath/rectangle_area/__init__.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
def compute_area(
2+
ax1: int, ay1: int, ax2: int, ay2: int, bx1: int, by1: int, bx2: int, by2: int
3+
):
4+
# 1. Calculate the area of each individual rectangle
5+
area_a = (ax2 - ax1) * (ay2 - ay1)
6+
area_b = (bx2 - bx1) * (by2 - by1)
7+
8+
# 2. Calculate the area of the overlap (A intersect B)
9+
10+
# Determine the coordinates of the overlap rectangle: (ix1, iy1) to (ix2, iy2)
11+
12+
# The left edge of the overlap is the max of the two left edges
13+
ix1 = max(ax1, bx1)
14+
# The right edge of the overlap is the min of the two right edges
15+
ix2 = min(ax2, bx2)
16+
17+
# The bottom edge of the overlap is the max of the two bottom edges
18+
iy1 = max(ay1, by1)
19+
# The top edge of the overlap is the min of the two top edges
20+
iy2 = min(ay2, by2)
21+
22+
# Calculate the width and height of the overlap
23+
overlap_width = max(0, ix2 - ix1)
24+
overlap_height = max(0, iy2 - iy1)
25+
26+
# The max(0, ...) ensures that if the rectangles do not overlap
27+
# (e.g., ix2 < ix1), the width/height is 0, and the overlap_area is 0.
28+
overlap_area = overlap_width * overlap_height
29+
30+
# 3. Apply the Inclusion-Exclusion Principle
31+
total_area = area_a + area_b - overlap_area
32+
33+
return total_area
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import unittest
2+
from parameterized import parameterized
3+
from pymath.rectangle_area import compute_area
4+
5+
6+
class RectangleAreaTestCase(unittest.TestCase):
7+
@parameterized.expand(
8+
[
9+
(0, 0, 1, 1, 2, 2, 3, 3, 2),
10+
(0, 0, 2, 2, 1, 1, 3, 3, 7),
11+
(-1, -1, 2, 2, 0, 0, 1, 1, 9),
12+
(0, 0, 0, 0, 1, 1, 2, 2, 1),
13+
(-8918, -419, -7715, 577, -8918, -419, -7715, 577, 1198188),
14+
]
15+
)
16+
def test_compute_area(
17+
self,
18+
ax1: int,
19+
ay1: int,
20+
ax2: int,
21+
ay2: int,
22+
bx1: int,
23+
by1: int,
24+
bx2: int,
25+
by2: int,
26+
expected,
27+
):
28+
actual = compute_area(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2)
29+
self.assertEqual(expected, actual)
30+
31+
32+
if __name__ == "__main__":
33+
unittest.main()

0 commit comments

Comments
 (0)