Try an interactive version of this dialog: Sign up at solve.it.com, click Upload, and pass this URL.

Code: 60 ()

from aocd import get_data
inp = get_data(year=2025, day=4)
len(inp), len(inp.splitlines()), len(inp.splitlines()[0]), inp[:100]

Output: 117

(18359,
 135,
 135,
 '@.@@...@@.@@@@.@..@@@.@@..@@@@@..@@@@@.@@.@@@@@....@@@.@..@@@@@.@.@@@@@..@...@@.@@.@.@.@.@@.@.@.@@..')

Code: 94 ()

samp = """..@@.@@@@.
@@@.@.@.@@
@@@@@.@.@@
@.@@@@..@.
@@.@@@@.@@
.@@@@@@@.@
.@.@.@.@@@
@.@@@.@@@@
.@@@@@@@@.
@.@.@@@.@."""

Note: 48

A roll can be accessed if it has fewer than four rolls of paper in the eight adjacent positions.

How many rolls of paper can be accessed by a forklift?

Code: 3 ()

import torch

Code: 34 ()

grid = torch.tensor([[int(c=='@') for c in line] for line in samp.splitlines()])
grid

Output: 480

tensor([[0, 0, 1, 1, 0, 1, 1, 1, 1, 0],
        [1, 1, 1, 0, 1, 0, 1, 0, 1, 1],
        [1, 1, 1, 1, 1, 0, 1, 0, 1, 1],
        [1, 0, 1, 1, 1, 1, 0, 0, 1, 0],
        [1, 1, 0, 1, 1, 1, 1, 0, 1, 1],
        [0, 1, 1, 1, 1, 1, 1, 1, 0, 1],
        [0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
        [1, 0, 1, 1, 1, 0, 1, 1, 1, 1],
        [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
        [1, 0, 1, 0, 1, 1, 1, 0, 1, 0]])

Code: 16 ()

kernel = torch.ones((3, 3))
kernel

Output: 64

tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])

Code: 61 ()

nsums = torch.nn.functional.conv2d(grid.unsqueeze(0).unsqueeze(0).float(), 
                           kernel.unsqueeze(0).unsqueeze(0), 
                           padding=1)
nsums

Output: 499

tensor([[[[2., 4., 4., 4., 3., 4., 4., 5., 4., 3.],
          [4., 7., 7., 7., 5., 6., 5., 7., 6., 5.],
          [5., 8., 7., 8., 6., 6., 3., 5., 5., 5.],
          [5., 7., 7., 8., 8., 7., 4., 5., 5., 5.],
          [4., 6., 7., 8., 9., 8., 6., 5., 5., 4.],
          [4., 5., 7., 6., 8., 7., 7., 6., 7., 5.],
          [3., 5., 7., 7., 7., 6., 7., 7., 8., 5.],
          [3., 5., 7., 7., 7., 6., 7., 8., 8., 5.],
          [3., 6., 6., 8., 7., 8., 7., 8., 6., 4.],
          [2., 4., 4., 5., 5., 6., 5., 5., 3., 2.]]]])

Code: 30 ()

torch.where((nsums[0][0] < 5) & (grid==1))

Output: 135

(tensor([0, 0, 0, 0, 0, 1, 2, 4, 4, 7, 9, 9, 9]),
 tensor([2, 3, 5, 6, 8, 0, 6, 0, 9, 0, 0, 2, 8]))

Code: 39 ()

torch.where((nsums[0][0] < 5) & (grid==1))[0].shape[0]

Output: 16

13

Prompt: 25

Wrap this in a solvea function and run it on the samp and inp

Assistant: 174

Copied!
def solvea(s):
    grid = torch.tensor([[int(c=='@') for c in line] for line in s.splitlines()])
    kernel = torch.ones((3, 3))
    nsums = torch.nn.functional.conv2d(grid.unsqueeze(0).unsqueeze(0).float(), kernel.unsqueeze(0).unsqueeze(0), padding=1)
    return torch.where((nsums[0][0] < 5) & (grid==1))[0].shape[0]

solvea(samp), solvea(inp)

Code: 168 ()

def solvea(s):
    grid = torch.tensor([[int(c=='@') for c in line] for line in s.splitlines()])
    kernel = torch.ones((3, 3))
    nsums = torch.nn.functional.conv2d(grid.unsqueeze(0).unsqueeze(0).float(), kernel.unsqueeze(0).unsqueeze(0), padding=1)
    return torch.where((nsums[0][0] < 5) & (grid==1))[0].shape[0]

solvea(samp), solvea(inp)

Output: 22

(13, 1437)

Note: 36

Part 2

How many can we remove if we remove the ones that are removeable and then re-compute

Code: 222 ()

def solveb(s):
    total = 0
    grid = torch.tensor([[int(c=='@') for c in line] for line in s.splitlines()])
    while True:
        nsums = torch.nn.functional.conv2d(grid.unsqueeze(0).unsqueeze(0).float(), kernel.unsqueeze(0).unsqueeze(0), padding=1)
        locs = torch.where((nsums[0][0] < 5) & (grid==1))
        grid[locs] = 0
        total += locs[0].shape[0]
        if locs[0].shape[0]==0: break
    return total

solveb(samp), solveb(inp)

Output: 22

(43, 8765)