-
Notifications
You must be signed in to change notification settings - Fork 4
aoc tips #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
aoc tips #8
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # Using modulo for circular wrapping | ||
|
|
||
| Clean way to handle circular/wrapping behavior in #Python 👇 | ||
|
|
||
| Instead of complex if-else logic to wrap around, use the modulo operator: | ||
|
|
||
| ```python | ||
| DIAL_SIZE = 100 | ||
|
|
||
| def step(pos: int, rotation: str, amount: int) -> int: | ||
| """Move position on a circular dial.""" | ||
| delta = amount if rotation == "R" else -amount | ||
| return (pos + delta) % DIAL_SIZE | ||
|
|
||
| # Example usage: | ||
| pos = 95 | ||
| pos = step(pos, "R", 10) # 95 + 10 = 105 % 100 = 5 | ||
| print(pos) # 5 | ||
|
|
||
| pos = 3 | ||
| pos = step(pos, "L", 5) # 3 + (-5) = -2 % 100 = 98 | ||
| print(pos) # 98 | ||
| ``` | ||
|
|
||
| Works for both positive and negative deltas - Python's modulo handles negatives correctly! | ||
|
|
||
| Perfect for: game boards, circular buffers, rotating arrays, clock arithmetic. | ||
|
|
||
| #algorithms #modulo |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Detecting repeated patterns with string multiplication | ||
|
|
||
| Clever trick to check if a string is made of repeated chunks in #Python 👇 | ||
|
|
||
| ```python | ||
| def has_repeated_chunks(s: str) -> bool: | ||
| """Check if string is composed of a repeating pattern.""" | ||
| n = len(s) | ||
| for size in range(1, n // 2 + 1): | ||
| # Skip if size doesn't divide evenly | ||
| if n % size != 0: | ||
| continue | ||
|
|
||
| chunk = s[:size] | ||
| # Multiply chunk and compare to original | ||
| if chunk * (n // size) == s: | ||
| return True | ||
|
|
||
| return False | ||
|
|
||
| # Examples: | ||
| print(has_repeated_chunks("abcabc")) # True (abc repeated 2 times) | ||
| print(has_repeated_chunks("123123123")) # True (123 repeated 3 times) | ||
| print(has_repeated_chunks("abcdef")) # False | ||
| print(has_repeated_chunks("aaaaaa")) # True (a repeated 6 times) | ||
| ``` | ||
|
|
||
| String multiplication (`chunk * count`) creates a repeated pattern - compare it to the original to detect repetition! | ||
|
|
||
| #strings #patterns |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Monotonic stack for finding largest K-digit number | ||
|
|
||
| Powerful algorithm to find the largest K-digit number by removing digits in #Python 👇 | ||
|
|
||
| ```python | ||
| def find_largest_k_digit_number(digits: str, k: int) -> str: | ||
| """Find largest K-digit number by removing digits.""" | ||
|
bbelderbos marked this conversation as resolved.
|
||
| num_drops = len(digits) - k | ||
| stack = [] | ||
|
|
||
| for digit in digits: | ||
| # Remove smaller digits from stack while we can | ||
| while num_drops and stack and stack[-1] < digit: | ||
| stack.pop() | ||
| num_drops -= 1 | ||
| stack.append(digit) | ||
|
|
||
| return "".join(stack[:k]) | ||
|
|
||
| # Examples: | ||
| print(find_largest_k_digit_number("1432219", 3)) # "439" | ||
| print(find_largest_k_digit_number("10200", 2)) # "22" | ||
| print(find_largest_k_digit_number("54321", 2)) # "54" | ||
| ``` | ||
|
|
||
| The stack maintains potential candidates. Greedily remove smaller digits when we see a larger one. | ||
|
|
||
| Time complexity: O(n). Great for competitive programming! | ||
|
|
||
| #algorithms #stack | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # Using NamedTuple for grid coordinates | ||
|
|
||
| Clean, memory-efficient way to represent positions in #Python 👇 | ||
|
|
||
| ```python | ||
| from typing import NamedTuple | ||
|
|
||
| class Position(NamedTuple): | ||
| x: int | ||
| y: int | ||
|
|
||
| # 8 directions for grid navigation | ||
| DIRECTIONS = [ | ||
| Position(-1, -1), Position(0, -1), Position(1, -1), | ||
| Position(-1, 0), Position(1, 0), | ||
| Position(-1, 1), Position(0, 1), Position(1, 1), | ||
| ] | ||
|
|
||
| def get_neighbors(pos: Position) -> list[Position]: | ||
| """Get all 8 neighbors of a position.""" | ||
| return [Position(pos.x + d.x, pos.y + d.y) for d in DIRECTIONS] | ||
|
|
||
| # Usage: | ||
| current = Position(5, 5) | ||
| neighbors = get_neighbors(current) | ||
|
|
||
| # NamedTuple benefits: | ||
| # ✓ Immutable (hashable - works in sets/dict keys) | ||
| # ✓ Memory efficient (uses __slots__) | ||
| # ✓ Named access (pos.x, pos.y) | ||
| # ✓ Tuple unpacking (x, y = pos) | ||
| ``` | ||
|
|
||
| #datastructures #grids |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Parsing with tuple and map | ||
|
|
||
| Concise pattern for parsing structured data in #Python 👇 | ||
|
|
||
| ```python | ||
| # Parse ranges from strings | ||
| def parse_ranges(text: str) -> list[tuple[int, int]]: | ||
| """Parse lines like '10-20' into tuples of integers.""" | ||
| return [tuple(map(int, line.split("-"))) for line in text.splitlines()] | ||
|
|
||
| # Example usage: | ||
| data = """10-20 | ||
| 30-45 | ||
| 100-150""" | ||
|
|
||
| ranges = parse_ranges(data) | ||
| print(ranges) | ||
| # [(10, 20), (30, 45), (100, 150)] | ||
|
|
||
| # Check if value is in any range: | ||
| def in_range(value: int, ranges: list[tuple[int, int]]) -> bool: | ||
| return any(start <= value <= end for start, end in ranges) | ||
|
|
||
| print(in_range(15, ranges)) # True (in 10-20) | ||
| print(in_range(25, ranges)) # False | ||
| ``` | ||
|
|
||
| `tuple(map(int, ...))` is more memory efficient than list comprehension for fixed-size sequences. | ||
|
|
||
| #parsing #idioms |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # Matrix transposition with zip | ||
|
|
||
| Elegant way to transpose a matrix (swap rows/columns) in #Python 👇 | ||
|
|
||
| ```python | ||
| from math import prod | ||
|
|
||
| # Original grid (rows) | ||
| grid = [ | ||
| [1, 2, 3, 4], | ||
| [5, 6, 7, 8], | ||
| [9, 10, 11, 12] | ||
| ] | ||
|
|
||
| # Transpose: rows become columns | ||
| transposed = list(zip(*grid)) | ||
| print(transposed) | ||
| # [(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)] | ||
|
|
||
| # Practical example: column operations | ||
| ops = ["*", "+", "*", "+"] | ||
|
|
||
| # Process each column with its operation | ||
| result = sum( | ||
| prod(col) if op == "*" else sum(col) | ||
| for op, col in zip(ops, transposed) | ||
| ) | ||
| print(result) # (1*5*9) + (2+6+10) + (3*7*11) + (4+8+12) = 45 + 18 + 231 + 24 | ||
|
|
||
| # Remember: zip(*matrix) unpacks rows as arguments to zip | ||
| # which pairs up elements at same index = columns! | ||
| ``` | ||
|
|
||
| #matrix #zip |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.