From ec1b5c09218cb049a610330387d0b7396f0fb3dc Mon Sep 17 00:00:00 2001 From: paxtonfitzpatrick Date: Sun, 7 Jul 2024 01:13:22 +0000 Subject: [PATCH 1/4] Update README with LeetCode Daily Challenge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9235302..82d5141 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Each day (ideally) we'll attempt the daily [leetcode](https://leetcode.com) prob | July 4, 2024 | [2181](https://leetcode.com/problems/merge-nodes-in-between-zeros/) | [Click here](https://github.com/ContextLab/leetcode-solutions/tree/main/problems/2181) | 🟡 Medium | | July 5, 2024 | [2058](https://leetcode.com/problems/find-the-minimum-and-maximum-number-of-nodes-between-critical-points/) | [Click here](https://github.com/ContextLab/leetcode-solutions/tree/main/problems/2058) | 🟡 Medium | | July 6, 2024 | [2582](https://leetcode.com/problems/pass-the-pillow) | [Click here](https://github.com/ContextLab/leetcode-solutions/tree/main/problems/2582) | 🟢 Easy | +| July 7, 2024 | [1518](https://leetcode.com/problems/water-bottles) | [Click here](https://github.com/ContextLab/leetcode-solutions/tree/main/problems/1518) | 🟢 Easy | # Join our discussion! From 7552ee6dc02a32a60541221b62bf80aed9308d7b Mon Sep 17 00:00:00 2001 From: paxtonfitzpatrick Date: Sun, 7 Jul 2024 17:49:52 +0000 Subject: [PATCH 2/4] Creating a template for paxtonfitzpatrick's solution to problem 1518 --- problems/1518/paxtonfitzpatrick.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 problems/1518/paxtonfitzpatrick.md diff --git a/problems/1518/paxtonfitzpatrick.md b/problems/1518/paxtonfitzpatrick.md new file mode 100644 index 0000000..d0e1621 --- /dev/null +++ b/problems/1518/paxtonfitzpatrick.md @@ -0,0 +1,11 @@ +# [Problem 1518: Water Bottles](https://leetcode.com/problems/water-bottles) + +## Initial thoughts (stream-of-consciousness) + +## Refining the problem, round 2 thoughts + +## Attempted solution(s) +```python +class Solution: # paste your code here! + ... +``` From 228c567c137f4eaaf3a265aa331ae0eb5176fae4 Mon Sep 17 00:00:00 2001 From: paxtonfitzpatrick Date: Sun, 7 Jul 2024 16:24:35 -0400 Subject: [PATCH 3/4] solutions and notes for problem 1518 --- problems/1518/paxtonfitzpatrick.md | 47 ++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/problems/1518/paxtonfitzpatrick.md b/problems/1518/paxtonfitzpatrick.md index d0e1621..500554c 100644 --- a/problems/1518/paxtonfitzpatrick.md +++ b/problems/1518/paxtonfitzpatrick.md @@ -2,10 +2,53 @@ ## Initial thoughts (stream-of-consciousness) +- seems pretty simple... +- when exchanging empties for fulls, will need to use floor division to figure out how many fulls we can get and also modulo to figure out how many empties couldn't be echanged +- also need to keep track of unexchanged empties in case we can accumulate enough for another full (`numExchange`) +- stop when we have no more fulls and not enough empties to exchange for a full +- I think I'll structure this as a `while` loop where each time through the loop we can drink fulls and/or exchange empties + - There's probably a more efficient way to do this without looping, where we calculate everything from the initial values (so, $O(1)$), but this seems like an easier place to start. + - I bet there's also a way to set this up recursively, which could be interesting, but unlikely to be optimal + ## Refining the problem, round 2 thoughts +- Version 2: I noticed some small tweaks I could make to the logic that I think would speed up the `while` loop version slightly + - note: key to not having to modify `n_empties` twice each iteration is updating `n_fulls` and `n_empties` simultaneously. New values for both variables depend on the old value of the other, so updating both on the same line ensures both calculations use the "old" values. Could also have stored `n_empties + n_fulls` in a temporary variable, but that would've taken a teeny bit more time & memory. + ## Attempted solution(s) + +Version 1: + +```python +class Solution: + def numWaterBottles(self, numBottles: int, numExchange: int) -> int: + n_fulls = numBottles + n_empties = 0 + n_drank = 0 + while True: + n_drank += n_fulls + n_empties += n_fulls + if n_empties < numExchange: + return n_drank + n_fulls = n_empties // numExchange + n_empties = n_empties % numExchange +``` + +![Version 1 results](https://github.com/paxtonfitzpatrick/leetcode-solutions/assets/26118297/08d502ae-a947-49fc-89a9-fb578ea937a6) + +Version 2: + ```python -class Solution: # paste your code here! - ... +class Solution: + def numWaterBottles(self, numBottles: int, numExchange: int) -> int: + n_drank = numBottles + n_fulls = numBottles // numExchange + n_empties = numBottles % numExchange + while n_fulls > 0: + n_drank += n_fulls + n_fulls, n_empties = (n_empties + n_fulls) // numExchange, (n_empties + n_fulls) % numExchange + return n_drank ``` + +![Version 2 results](https://github.com/paxtonfitzpatrick/leetcode-solutions/assets/26118297/ba0ca272-8761-4cc5-9c2f-9deb12d40361) +Appears to be slower than version 1, but probably just due to random variation runtime of the test cases. Pretty confident that in reality, version 2 is marginally faster. From c179524ad6dbcd13aaa29f4d5ca16ab3c95a25b5 Mon Sep 17 00:00:00 2001 From: paxtonfitzpatrick Date: Sun, 7 Jul 2024 17:42:59 -0400 Subject: [PATCH 4/4] solutions and notes for problem 1550 --- problems/1550/paxtonfitzpatrick.md | 54 ++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 problems/1550/paxtonfitzpatrick.md diff --git a/problems/1550/paxtonfitzpatrick.md b/problems/1550/paxtonfitzpatrick.md new file mode 100644 index 0000000..5a67c69 --- /dev/null +++ b/problems/1550/paxtonfitzpatrick.md @@ -0,0 +1,54 @@ +# [Problem 1550: Three Consecutive Odds](https://leetcode.com/problems/three-consecutive-odds/description/) + +## Initial thoughts (stream-of-consciousness) + +- seems like a pretty easy one +- need to track the number of consecutive odds + - if counter ever reaches 3, return True + - if we encounter an even number, reset counter to 0 + +## Refining the problem + +- I bet this will ultimately be slower, but I can think of a kinda fun, roundabout way solve this: + - convert `arr` to a string + - use regular expression to search for 3 consecutive occurrences of values that end in 1, 3, 5, 7, or 9, separated by a command and space + - we know that all values are <= 1000, and 1000 is an even number, so all odd numbers will have 1, 2, or 3 digits -- so for each number we need to match 0, 1, or 2 digits of any value, followed by an odd digit: `[0-9]{0,2}[13579]` + - base pattern would be `(?:[0-9]{0,2}[13579], ){3}` but: + - this would fail for the last 3 values in the list because there's no trailing comma. So instead use `(?:[0-9]{0,2}[13579], ){2}[0-9]{0,2}[13579]` + - Also for the first of the 3 odd numbers, we should only try to match the final digit rather than all digits, otherwise the search will be slower because the pattern will initially match all values in the list and waste a bunch of time backtracking. So instead use `[13579], [0-9]{0,2}[13579], [0-9]{0,2}[13579]` or `[13579](?:, [0-9]{0,2}[13579]){2}` + + - `re.search` returns a `Match` object as soon as it encounters the first match, and `None` if no match is found. So we should be able to just `bool()` the result and return it. + - I wonder if compiling the pattern upfront would be faster than using using the module-level functions... depends on how leetcode runs the test cases, I guess. If I compile the expression in the class body outside the method definition, and all test case runs reuse the same instance of the class, then it should save time. Otherwise, it probably wouldn't. Maybe I'll just compile it in the global namespace and see. + +## Attempted solution(s) + +```python +class Solution: + def threeConsecutiveOdds(self, arr: List[int]) -> bool: + if len(arr) < 3: + return False + + consec_odds = 0 + for val in arr: + if val % 2: + if consec_odds == 2: + return True + consec_odds += 1 + else: + consec_odds = 0 + return False +``` + +![](https://github.com/paxtonfitzpatrick/leetcode-solutions/assets/26118297/c45d108c-b23b-48d8-bc14-13a2cdc0cc06) + +```python +from re import compile + +pattern = compile(r"[13579](?:, [0-9]{0,2}[13579]){2}") + +class Solution: + def threeConsecutiveOdds(self, arr: List[int]) -> bool: + return bool(pattern.search(str(arr))) +``` + +![](https://github.com/paxtonfitzpatrick/leetcode-solutions/assets/26118297/88d07bb2-f252-4797-81e4-33793acaeae4)