WIP part 2
This commit is contained in:
parent
496031e9c1
commit
43b7187371
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue