This commit is contained in:
akp 2024-12-08 12:33:49 +00:00
parent 4902fa69c4
commit 1656243727
No known key found for this signature in database
GPG key ID: CF8D58F3DEB20755
6 changed files with 111 additions and 2 deletions

View file

@ -0,0 +1,6 @@
# [Day 8: Resonant Collinearity](https://adventofcode.com/2024/day/8)
Part 1 is:
* less than 298
This is not a fully generic solution as, in a situation where the differences between x and y dimensions of pairs of coordinates are not coprime, this implementation would skip steps.

View file

@ -0,0 +1,74 @@
import sys
from gridutil import grid, coord
from collections import defaultdict
import itertools
from fractions import Fraction
def parse(instr: str) -> tuple[dict[str, list[coord.Coordinate]], tuple[int, int]]:
g = grid.parse(instr)
antenna_by_type = defaultdict(list)
for key in g:
if g[key] == ".":
continue
antenna_by_type[g[key]].append(key)
return antenna_by_type, (grid.get_max_x(g), grid.get_max_y(g))
def one(instr: str):
(antenna_by_type, (max_x, max_y)) = parse(instr)
pos = set()
for antenna_type in antenna_by_type:
for (a, b) in itertools.permutations(antenna_by_type[antenna_type], 2):
diff = coord.sub(b, a)
c = coord.add(a, coord.mult(diff, 2))
if 0 <= c.x <= max_x and 0 <= c.y <= max_y:
pos.add(c)
return len(pos)
def two(instr: str):
(antenna_by_type, (max_x, max_y)) = parse(instr)
pos = set()
for antenna_type in antenna_by_type:
for (a, b) in itertools.permutations(antenna_by_type[antenna_type], 2):
if (
a.x > b.x
): # filter out (most) duplicate pairs eg ((1, 2), (2, 1)) will only be calculated as ((2, 1), (1, 2)) will be filtered. This also prevents diff.x from being negative (useful for the mod operation)
continue
diff = coord.sub(b, a)
m = Fraction(
diff.y, diff.x
) # equiv of diff.y / diff.x but without the 26.9999999999996 issue
c = a.y - (m * a.x)
x_cursor = a.x % diff.x
y_cursor = int((x_cursor * m) + c)
while x_cursor <= max_x:
if 0 <= y_cursor <= max_y:
pos.add((x_cursor, y_cursor))
x_cursor += diff.x
y_cursor += diff.y
return len(pos)
def _debug(*args, **kwargs):
kwargs["file"] = sys.stderr
print(*args, **kwargs)
if __name__ == "__main__":
if len(sys.argv) < 2 or sys.argv[1] not in ["1", "2"]:
print("Missing day argument", file=sys.stderr)
sys.exit(1)
inp = sys.stdin.read().strip()
if sys.argv[1] == "1":
print(one(inp))
else:
print(two(inp))

View file

@ -0,0 +1,26 @@
{
"1": [
{
"is": "14",
"input": "............\n........0...\n.....0......\n.......0....\n....0.......\n......A.....\n............\n............\n........A...\n.........A..\n............\n............\n\n"
},
{
"is": "2",
"input": "..........\n..........\n..........\n....a.....\n..........\n.....a....\n..........\n..........\n..........\n..........\n\n"
},
{
"is": "4",
"input": "..........\n..........\n..........\n....a.....\n........a.\n.....a....\n..........\n..........\n..........\n..........\n"
}
],
"2": [
{
"is": "34",
"input": "............\n........0...\n.....0......\n.......0....\n....0.......\n......A.....\n............\n............\n........A...\n.........A..\n............\n............\n\n"
},
{
"is": "9",
"input": "T.........\n...T......\n.T........\n..........\n..........\n..........\n..........\n..........\n..........\n..........\n"
}
]
}

View file

@ -4,7 +4,7 @@ Solutions to the [2024 Advent of Code](https://adventofcode.com/2024)!
---
Total stars: **14 ★**
Total stars: **16 ★**
![Benchmark graph](./benchmark-graph.png)
@ -20,4 +20,5 @@ A day denoted with an asterisk means it has a visualisation.
| 04* - Ceres Search | ★ ★ | Python | When it says a cross, it does not mean a plus. |
| 05 - Print Queue | ★ ★ | Python | Before you dismiss and idea as being "too simple", make sure you check that it doesn't work. |
| 06 - Guard Gallivant | ★ ★ | Python | oh dear runtime (also I knew what I wanted to do for so long it just took me 3 hours to implement it properly) |
| 07 - Bridge Repair | ★ ★ | Python | Maths? Backwards?? |
| 07 - Bridge Repair | ★ ★ | Python | Maths? Backwards?? |
| 08 - Resonant Collinearity | ★ ★ | Python | `Fraction` saving us all from the curse of a computer's inability to do floating point arithmetic |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Before After
Before After

View file

@ -12,3 +12,5 @@
{"day": 6, "part": 2, "runner": "py", "min": 15.881408452987671, "max": 17.086341857910156, "avg": 16.64130985736847, "n": 6}
{"day": 7, "part": 1, "runner": "py", "min": 0.025098562240600586, "max": 0.04218649864196777, "avg": 0.027579346656799317, "n": 500}
{"day": 7, "part": 2, "runner": "py", "min": 0.03137779235839844, "max": 0.04896378517150879, "avg": 0.03503713369369507, "n": 500}
{"day": 8, "part": 1, "runner": "py", "min": 0.025803089141845703, "max": 0.036757469177246094, "avg": 0.02743640899658203, "n": 200}
{"day": 8, "part": 2, "runner": "py", "min": 0.027710437774658203, "max": 0.035851240158081055, "avg": 0.029560294151306152, "n": 200}