This commit is contained in:
2024-12-08 21:36:04 +01:00
parent 9ef0275a61
commit 0ba1f371ed
18 changed files with 1016 additions and 115 deletions

26
2024/02/findings.md Normal file
View File

@@ -0,0 +1,26 @@
# Day 2
In part two i got stuck because I wanted to be smart. Don't be smart, unless you really are, unlike me.
So [the challenge](https://adventofcode.com/2024/day/2) was to allow one possible error in a _report_
Given the level `1 3 2 4 5`, which fails because the 2 decreases, instead of increasing, i though it would be neat to only try removing one of each numbers.
In this case either the `3` or the `2`. I did not want to brute force through the array. What was i missing?
I then quickly found out, as the brute force variant is trivial to implement (on error, just retry every combination with one missing, breaking at the first _safe_ combination). The output was correct with the brute force variant, but my "smart™" solution was off by very little, so what were the few edge cases?
These 4 are safe with the _Problem Dampener_, but were not detected by my "smart™" algorithm.
```
[55, 52, 53, 54, 56, 57]
[17, 15, 16, 19, 20, 23, 25]
[56, 57, 56, 55, 54, 51, 50, 49]
[81, 84, 81, 80, 77, 75, 72, 69]
```
Why? well the issue was, that the error always occurred when the wrong number was the first one, giving a bad prediction for the "direction", basically whether the numbers would increase or decrease. Since the issue was always the third number with index `2`, removing either the second or third element was not enough, as the root cause was that the first items was already wrong, but only detected to late.
## Possible solutions
In my head, another way to visualise it, was to think in differences, where the first element would be always 0, and the next ones the diff to the previous one. In that case we could check for steady increase/decrease by making sure that all the subsequent numbers are all positive or negative.
Basically like a drawn line, with one outlier.

80
2024/02/main.py Normal file
View File

@@ -0,0 +1,80 @@
def is_safe_1(numbers, tolerance=0) -> bool:
if len(numbers) < 2:
return True
down = numbers[0] > numbers[1]
cur = numbers[0]
for i in range(1, len(numbers)):
x = numbers[i]
diff = x - cur
if down:
diff *= -1
if 3 < diff or diff < 1:
if tolerance == 0:
return False
else:
found = set()
for j in range(len(numbers)):
tmp = numbers[:]
del tmp[j]
if is_safe_1(tmp, tolerance - 1):
found.add(tuple(tmp))
# print("adding", tuple(tmp))
return True
break
else:
# return False
pass
# print(len(found))
first_removed = numbers[:]
del first_removed[i - 1]
if is_safe_1(first_removed, tolerance - 1):
return True
second_removed = numbers[:]
del second_removed[i]
if is_safe_1(second_removed, tolerance - 1):
return True
if len(found) > 0:
print(numbers, i, x)
print(first_removed, second_removed)
print(numbers, found)
return False
cur = x
return True
def is_safe_2(numbers, tolerance=0):
# Convert to differences
diffs = [0] # First element is zero, as there is no predecessor
for i in range(1, len(numbers)):
diffs.append(numbers[i] - numbers[i - 1])
print(numbers, diffs)
def solve(raw: str) -> int:
# Part 1
part1 = 0
part2 = 0
for line in raw.splitlines():
numbers = [int(x) for x in line.split(" ")]
if is_safe_2(numbers):
part1 += 1
if is_safe_2(numbers, 1):
part2 += 1
return (part1, part2)
# Test
with open("./2024/02/test.txt", "r") as f:
result = solve(f.read().strip())
print(result)
# Input
# with open("./2024/02/input.txt", "r") as f:
# result = solve(f.read().strip())
# print(result)