Skip to content

Update 15.md #14

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
48 changes: 46 additions & 2 deletions aoc/2022/15.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,60 @@ A very much faster solution starts from
> the fact that any beacon will be adjacent to the perimeter of the region, so there are 4 straight lines that it could possibly pass through. Generate all the equations, and then the beacon will be at one of the intersections.

```q
`Sx`Sy`Bx`By set' flip {get @[x;where not x in "-0123456789";:;" "]}each inp;
`Sx`Sy`Bx`By set' flip {get @[x;where not x in "-0123456789";:;" "]}each read0 `15.txt;
m: sum abs (Sx-Bx;Sy-By) / manhattan dists
/ part 1
count except[;Bx where By=Y] distinct raze {$[y<0;();x-y-til 1+2*y]}'[Sx;m-abs Sy-Y]
count except[;Bx where By=Y] distinct raze {$[y<0;();x-y-til 1+2*y]}'[Sx;m-abs Sy-Y:2000000]
/ part 2
peri: raze 1 1 -1 -1,''(Sy-Sx+m+1; Sy-Sx-m+1; Sy+Sx+m+1; Sy+Sx-m+1)
int: distinct raze peri {r:0-1%(%/)x-y; (r; sum x*r,1)}\:/: peri
sum 4000000 1*floor first int where {all raze(x=floor x;0<=x;x<=LIM;m<sum abs(Sx;Sy)-x)} each int
```

## Part 1

Part 1 doesn't do anything clever (and ends up being slower than part 2!) but it is fast enough for the relatively small amount of data here.

`{$[y<0;();x-y-til 1+2*y]}` creates a region of size y around x

```
q)
{$[y<0;();x-y-til 1+2*y]}[5; 2]
3 4 5 6 7
```

`'[Sx;m-abs Sy-Y]` this function is then applied to each of the sensor x values, and the appropriate radius.

All that is left is to count the number of x values after removing any beacons.

## Part 2

Part 2 is more interesting:

We can use the fact that any undetected beacon must be adjacent to a detected region.

(This is true as there is only one possible location, so there can't be any 'space' around the beacon)

The line adjacent to a region's perimeter can be described as a simple linear equation.

As there are four possible adjacent lines, there are four different equations.

These are calculated with this line.
`peri: raze 1 1 -1 -1,''(Sy-Sx+m+1; Sy-Sx-m+1; Sy+Sx+m+1; Sy+Sx-m+1)`

Now, we can find the intersections between all pairs of lines.
`int: distinct raze peri {r:0-1%(%/)x-y; (r; sum x*r,1)}\:/: peri`

After checking that the intersections have the right properties:
`{all raze(x=floor x;0<=x;x<=LIM;m<sum abs(Sx;Sy)-x)}`

There will be only one left, which is the correct answer.

A visualisation in desmos with the sample data is below.

(Side note: desmos is a surprisingly good array language)

![image](https://user-images.githubusercontent.com/56049432/216835451-8e0dc9d8-47e1-4bab-ba3b-4a7fcc97f81a.png)


## Contributors
Expand Down