Skip to content
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

feat(2024): day 7 - Bridge Repair #16

Merged
merged 1 commit into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 56 additions & 2 deletions 2024/Day07/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,57 @@
# --- Day 0: Template ---
# --- Day 7: Bridge Repair ---

To be used as template for the other days.
The Historians take you to a familiar rope bridge over a river in the middle of a jungle. The Chief isn't on this side of the bridge, though; maybe he's on the other side?

When you go to cross the bridge, you notice a group of engineers trying to repair it. (Apparently, it breaks pretty frequently.) You won't be able to cross until it's fixed.

You ask how long it'll take; the engineers tell you that it only needs final calibrations, but some young elephants were playing nearby and stole all the operators from their calibration equations! They could finish the calibrations if only someone could determine which test values could possibly be produced by placing any combination of operators into their calibration equations (your puzzle input).

For example:

```txt
190: 10 19
3267: 81 40 27
83: 17 5
156: 15 6
7290: 6 8 6 15
161011: 16 10 13
192: 17 8 14
21037: 9 7 18 13
292: 11 6 16 20
```

Each line represents a single equation. The test value appears before the colon on each line; it is your job to determine whether the remaining numbers can be combined with operators to produce the test value.

Operators are always evaluated **left-to-right**, not according to precedence rules. Furthermore, numbers in the equations cannot be rearranged. Glancing into the jungle, you can see elephants holding two different types of operators: add `(+)` and multiply `(*).`

Only three of the above equations can be made true by inserting operators:

- `190: 10 19` has only one position that accepts an operator: between `10` and `19`. Choosing `+` would give `29`, but choosing `*` would give the test value `(10 * 19 = 190)`.
- `3267: 81 40 27` has two positions for operators. Of the four possible configurations of the operators, two cause the right side to match the test value: `81 + 40 * 27` and `81 * 40 + 27` both equal `3267` (when evaluated left-to-right)!
- `292: 11 6 16 20` can be solved in exactly one way: `11 + 6 * 16 + 20`.

The engineers just need the total calibration result, which is the sum of the test values from just the equations that could possibly be true. In the above example, the sum of the test values for the three equations listed above is `3749`.

Determine which equations could possibly be true. What is their total calibration result?

> Your puzzle answer was `2664460013123`.

## --- Part Two ---

The engineers seem concerned; the total calibration result you gave them is nowhere close to being within safety tolerances. Just then, you spot your mistake: some well-hidden elephants are holding a third type of operator.

The concatenation operator `(||)` combines the digits from its left and right inputs into a single number. For example, `12 || 345` would become `12345`. All operators are still evaluated **left-to-right**.

Now, apart from the three equations that could be made true using only addition and multiplication, the above example has three more equations that can be made true by inserting operators:

- `156: 15 6` can be made true through a single concatenation: `15 || 6 = 156`.
- `7290: 6 8 6 15` can be made true using `6 * 8 || 6 * 15`.
- `192: 17 8 14` can be made true using `17 || 8 + 14`.

Adding up all six test values (the three that could be made before using only `+` and `*` plus the new three that can now be made by also using `||`) produces the new total calibration result of `11387`.

Using your new knowledge of elephant hiding spots, determine which equations could possibly be true. What is their total calibration result?

> Your puzzle answer was `426214131924213`.

Both parts of this puzzle are complete! They provide two gold stars: `**`
37 changes: 37 additions & 0 deletions 2024/Day07/bridge_repair.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class BridgeRepair:
def __init__(self, lines: list[str]):
self.equations = [
(int(parts[0]), list(map(int, parts[1].split())))
for parts in (line.split(": ") for line in lines)
]

def is_valid_equation(
self,
equation: tuple[int, list[int]],
idx: int,
result: int,
concat: bool,
) -> bool:
if idx >= len(equation[1]):
return equation[0] == result
next_val = equation[1][idx]
return (
self.is_valid_equation(equation, idx + 1, result + next_val, concat)
or self.is_valid_equation(equation, idx + 1, result * next_val, concat)
or (
concat
and self.is_valid_equation(
equation,
idx + 1,
int(f"{result}{next_val}"),
concat,
)
)
)

def get_total_calibration(self, concat=False) -> int:
return sum(
target
for target, numbers in self.equations
if self.is_valid_equation((target, numbers), 1, numbers[0], concat)
)
Loading
Loading