WIP part 2

This commit is contained in:
Daniel Flanagan 2020-12-11 01:49:49 -06:00
parent 496031e9c1
commit 43b7187371
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4

View file

@ -1,29 +1,11 @@
import streams, sequtils, strutils import streams, sequtils
type type
Seat = enum Floor, Empty, Occupied Seat = enum Floor, Empty, Occupied
Grid = seq[seq[Seat]] Grid[T] = seq[seq[T]]
doAssert @[@[Occupied, Empty], @[Floor, Empty]] == @[@[Occupied, Empty], @[Floor, Empty]] proc row[T](g: Grid[T], y: int): seq[T] = g[y]
proc at[T](g: Grid[T], x: int, y: int): T = g.row(y)[x]
proc gridSummary(g: Grid): (int, int) =
## Used during debugging
var o, v = 0
for y in 0..<g.len:
for x in 0..<g[y].len:
case g[y][x]:
of Empty: inc v
of Occupied: inc o
else: discard
(o, v)
proc `$`(s: Seat): string =
case s
of Empty: "L"
of Occupied: "#"
else: "."
proc gridLine(l: seq[Seat]): string = join(l.mapIt($it))
proc toSeat(c: char): Seat = proc toSeat(c: char): Seat =
case c case c
@ -31,23 +13,21 @@ proc toSeat(c: char): Seat =
of '#': Occupied of '#': Occupied
else: Floor else: Floor
proc asGrid(s: Stream): Grid = proc asGrid(s: Stream): Grid[Seat] =
for l in s.lines: result.add l.map toSeat for l in s.lines: result.add l.map toSeat
proc getAdjacent(g: Grid, x: int, y: int): seq[Seat] = proc getAdjacent(g: Grid[Seat], x: int, y: int): seq[Seat] =
for sy in y-1..y+1: for sy in y-1..y+1:
for sx in x-1..x+1: for sx in x-1..x+1:
if sy >= 0 and sx >= 0 and sy < g.len and sx < g[sy].len: if sy >= 0 and sx >= 0 and sy < g.len and sx < g.row(sy).len:
result.add g[sy][sx] result.add g.at(sx, sy)
proc stepGrid(g: Grid): Grid = proc stepGrid(g: Grid[Seat]): Grid[Seat] =
#echo "Step"
for y in 0..<g.len: for y in 0..<g.len:
#echo g[y].gridLine
result.add @[] result.add @[]
for x in 0..<g[y].len: for x in 0..<g.row(y).len:
let adj = getAdjacent(g, x, y) let adj = getAdjacent(g, x, y)
result[y].add case g[y][x] result[y].add case g.at(x, y)
of Floor: Floor of Floor: Floor
of Empty: of Empty:
if adj.countIt(it == Occupied) == 0: if adj.countIt(it == Occupied) == 0:
@ -59,17 +39,75 @@ proc stepGrid(g: Grid): Grid =
Empty Empty
else: else:
Occupied Occupied
#echo (x, y, g[y][x], gridSummary(@[adj]), adj.gridLine, result[y][x])
proc part1*(s: Stream): int = proc part1*(s: Stream): int =
# TODO: part1 has tons of allocating - needs cleaning up
return 0
var g = s.asGrid var g = s.asGrid
var ng: Grid var ng: Grid[Seat]
while g != ng: while g != ng:
echo "\n\nGrid:\n", g.gridSummary
ng = g ng = g
g = g.stepGrid g = g.stepGrid
g.foldl(a.concat b).countIt(it == Occupied) g.foldl(a.concat b).countIt(it == Occupied)
type
SightSeat = (Seat, seq[tuple[x: int, y: int]])
SightGrid = seq[seq[SightSeat]]
proc inBounds(g: Grid, x: int, y: int): bool =
x >= 0 and y >= 0 and y < g.len and x < g.row(y).len
proc toSightSeat(g: Grid[Seat], x: int, y: int): SightSeat =
echo "toSightSeat"
result[0] = g.at(x, y)
for vy in -1..1:
for vx in -1..1:
if vy == 0 and vx == 0: continue
var tx = x + vx
var ty = y + vy
while g.inBounds(tx, ty) and g.at(tx, ty) == Floor:
echo "Still...", tx, ty
tx += vx
ty += vy
if g.inBounds(tx, ty): result[1].add (x: tx, y: ty)
proc asSightGrid(s: Stream): SightGrid =
let g = s.asGrid
for y in 0..<g.len:
result.add @[]
for x in 0..<g.row(y).len:
result[y].add g.toSightSeat(x, y)
proc getSightAdjacent(g: Grid[SightSeat], x: int, y: int): seq[Seat] =
for (tx, ty) in g.at(x, y)[1]:
result.add g.at(tx, ty)[0]
proc stepSightGrid(g: Grid[SightSeat]): Grid[SightSeat] =
echo "Step..."
for y in 0..<g.len:
result.add @[]
for x in 0..<g.row(y).len:
let adj = getSightAdjacent(g, x, y)
let (s, sights) = g.at(x, y)
let newSeat = case s
of Floor: Floor
of Empty:
if adj.countIt(it == Occupied) == 0:
Occupied
else:
Empty
of Occupied:
if adj.countIt(it == Occupied) >= 6:
Empty
else:
Occupied
result[y].add (newSeat, sights)
proc part2*(s: Stream): int = proc part2*(s: Stream): int =
0 # TODO: part2 has tons of allocating - needs cleaning up
var g = s.asSightGrid
var ng: Grid[SightSeat]
while g != ng:
ng = g
g = g.stepSightGrid
g.foldl(a.concat b).countIt(it[0] == Occupied)