Skip to content

Instantly share code, notes, and snippets.

@madhadron
Created December 24, 2020 06:19
Show Gist options
  • Save madhadron/7766541163aeeb26544512068b582673 to your computer and use it in GitHub Desktop.
Save madhadron/7766541163aeeb26544512068b582673 to your computer and use it in GitHub Desktop.
import sets
import tables
type
Direction = enum E, W, NE, NW, SE, SW
Point = tuple[q, r: int]
proc go(p: Point, d: Direction): Point =
var (q, r) = p
return case d
of E: (q + 1, r)
of W: (q - 1, r)
of NE: (q+1, r-1)
of NW: (q, r-1)
of SE: (q, r+1)
of SW: (q-1, r+1)
proc parsePath(s: string): seq[Direction] =
var ds: seq[Direction]
var i = 0
while i < len(s):
if s[i] == 'e':
ds.add(E)
i += 1
elif s[i] == 'w':
ds.add(W)
i += 1
elif i == len(s)-1:
echo "Expected two element direction, found: ", s[i]
quit(1)
elif s[i] == 'n':
if s[i+1] == 'e':
ds.add(NE)
elif s[i+1] == 'w':
ds.add(NW)
else:
echo "Invalid character following 'n' at position ", i+1, ": ", s[i+1]
quit(1)
i += 2
elif s[i] == 's':
if s[i+1] == 'e':
ds.add(SE)
elif s[i+1] == 'w':
ds.add(SW)
else:
echo "Invalid character following 's' at position ", i+1, ": ", s[i+1]
quit(1)
i += 2
else:
echo "Invalid direction character at position ", i, ": ", s[i]
return ds
proc toggle[T](s: var HashSet[T], v: T) =
if s.contains(v):
s.excl(v)
else:
s.incl(v)
var flipped: HashSet[Point]
for line in lines "input.txt":
var path = parsePath(line)
var p: Point = (0, 0)
for d in path:
p = p.go(d)
flipped.toggle(p)
echo "Initial state: ", len(flipped)
const dirs: seq[Direction] = @[E, W, NE, NW, SE, SW]
proc smear(blacks: HashSet[Point]): Table[Point, int] =
var smeared: Table[Point, int]
for point in blacks:
for d in dirs:
var p1 = point.go(d)
if smeared.hasKeyOrPut(p1, 1):
smeared[p1] += 1
return smeared
proc squash(blacks: HashSet[Point], smear: Table[Point, int]): HashSet[Point] =
var black1: HashSet[Point]
for p, n in smear.pairs():
var wasBlack = blacks.contains(p)
if wasBlack and (n == 1 or n == 2):
black1.incl(p)
elif (not wasBlack) and n == 2:
black1.incl(p)
return black1
var blacks: HashSet[Point] = flipped
for i in 1..100:
blacks = squash(blacks, smear(blacks))
echo "Day ", i, ": ", len(blacks)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment