advent-of-code

advent of code attempts
git clone git://bvnf.space/advent-of-code.git
Log | Files | Refs

a.lua (2026B)


      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
local dbg = require("debugger")
local f
if (arg[1]) then
    f = assert(io.open(arg[1], "r"))
else
    f = io.stdin
end

WIDTH = 10000

local nodes = {}
local minx, miny, maxx, maxy

function printgrid()
    for y=miny-5,maxy do
        for x=minx,maxx do
            i = nodes[x *WIDTH + y]
            io.write(i == 1 and "#" or i == 2 and "+" or i == 3 and "@" or ".")
        end
        io.write("\n")
    end
end

for line in f:lines() do
    local prev = nil
    for x,y in line:gmatch("(%d+),(%d+)") do
        x = tonumber(x)
        y = tonumber(y)
        minx = math.min(x, minx and minx or x)
        maxx = math.max(x, maxx and maxx or x)
        miny = math.min(y, miny and miny or y)
        maxy = math.max(y, maxy and maxy or y)

        if (prev) then
            for i = prev.x,x,(prev.x < x and 1 or -1) do
                for j = prev.y,y,(prev.y < y and 1 or -1) do
                    nodes[i*WIDTH + j] = 1
                end
            end
        end
        nodes[x *WIDTH + y] = 1
        prev = {x=x,y=y};
    end
end

function isempty(x, y)
    return (not nodes[x*WIDTH + y] and y < maxy+2) and {x,y} or false
end

local cntr = 0
local x,y = 500,0
while 1 do -- new grains coming in

    --local x, y = 500, 0
    x, y = 500, 0

    while 1 do -- path of each grain
        local xy = isempty(x, y+1) or isempty(x-1, y+1) or isempty(x+1, y+1) or nil
        if xy == nil then break end
        x, y = xy[1], xy[2]
        if y > maxy then break end
    end
    nodes[x *WIDTH + y] = 2
    if y > maxy then
        break
    end
    cntr = cntr + 1
end

print(cntr)

-- don't reset cntr or reset nodes.

while 1 do
    x, y = 500, 0
    while 1 do
        local xy = isempty(x, y+1) or isempty(x-1, y+1) or isempty(x+1, y+1) or nil
        if xy == nil then break end
        x, y = xy[1], xy[2]
        if y == 0 and x == 500 then break end
    end
    nodes[x *WIDTH + y] = 2
    if y == 0 and x == 500 then break end
    cntr = cntr + 1
end

print(cntr+2) -- +2 for the two we missed after