Skip to main content

2021 - Day 5

🎄 Advent of Code in Zef 🎄

https://adventofcode.com/2021/day/5

data = """  
0,9 -> 5,9
8,0 -> 0,8
9,4 -> 3,4
2,2 -> 2,1
7,0 -> 7,4
6,4 -> 2,0
0,9 -> 2,9
3,4 -> 1,4
0,0 -> 8,8
5,5 -> 8,2
"""


def parse_line(s: str)->tuple:
return (s
| split[' -> ']
| map[split[','] | map[int]]
| collect
)


def to_points(rs):
r1, r2 = rs
f = lambda a, b: a|repeat if a==b else range(min(a,b), max(a,b)+1)
return (f(r1[0], r2[0]), f(r1[1], r2[1])) | zip | collect


result = (data
| split['\n']
| trim['']
| map[parse_line] # convert each line to e.g. [ [0, 9], [5, 9] ]
| filter[unpack[lambda r1, r2: r1[0] == r2[0] or r1[1] == r2[1]]] # only non-diagonal lines for now
| map[to_points] # given the end points, return a list of all points in between the ends
| concat
| frequencies # count how often a point occurs here
| values
| filter[greater_than[1]] # how many points have overlapping lines
| length
| collect
)