Skip to content

Instantly share code, notes, and snippets.

@dan-passaro
Last active December 8, 2018 01:58
Show Gist options
  • Save dan-passaro/17577d8e670cfbe73dbe783250097ee4 to your computer and use it in GitHub Desktop.
Save dan-passaro/17577d8e670cfbe73dbe783250097ee4 to your computer and use it in GitHub Desktop.
Advent of Code 2018 Day 5 Part 1 broken solution
import sys
import time
from polymer import Polymer
class NullStatusDisplayer(object):
def show_status(self):
pass
class StatusDisplayer(object):
def __init__(self, polymer):
self.polymer = polymer
self.last_update = -1
def show_status(self):
now = time.clock()
secs_since_last = now - self.last_update
if secs_since_last >= 1:
print('Reacting... size:', len(self.polymer), file=sys.stderr)
self.last_update = now
def main(original, show_status=False):
polymer = Polymer(original)
if show_status:
display = StatusDisplayer(polymer)
else:
display = NullStatusDisplayer()
while not polymer.is_stable:
display.show_status()
polymer.react()
return polymer
if __name__ == '__main__':
with open(sys.argv[1]) as infile:
print(main(infile.read().strip(), show_status=True))
import itertools
class NonAlphaSymbolError(object):
pass
class Unit(object):
"""An element of a Polymer."""
# Polarities
UPPER = object()
LOWER = object()
def __init__(self, symbol):
try:
# Allow so that Unit(Unit('b')) == Unit('b')
self.symbol = symbol.symbol
except AttributeError:
self.symbol = symbol
if not self.symbol.isalpha():
raise NonAlphaSymbolError(self.symbol)
def __repr__(self):
return 'Unit({!r})'.format(self.symbol)
def __str__(self):
return str(self.symbol)
def __eq__(self, other):
try:
return self.symbol == other.symbol
except Exception:
try:
return self.symbol == other
except Exception:
return False
@property
def type(self):
return self.symbol.lower()
@property
def polarity(self):
return self.UPPER if self.symbol.isupper() else self.LOWER
def reacts_with(self, other_unit):
return (self.polarity is not other_unit.polarity
and self.type == other_unit.type)
class Polymer(object):
def __init__(self, data):
self.__units = [Unit(symbol) for symbol in data]
self.__cached = None
def __eq__(self, other):
try:
return self.__units == other.__units
except Exception:
try:
return all(a == b for a, b in zip(self.__units, other))
except Exception:
return False
def __str__(self):
return ''.join(map(str, self.__units))
def __repr__(self):
return 'Polymer({!r})'.format(str(self))
def __len__(self):
return len(self.__units)
@property
def __first_reaction(self):
if self.__cached:
return self.__cached
adjacent_units = itertools.islice(self.__units, 1, None)
unit_pairs = zip(self.__units, adjacent_units)
for n, (unit_a, unit_b) in enumerate(unit_pairs):
if unit_a.reacts_with(unit_b):
self.__cached = n
return self.__cached
def react(self):
"""Get a Polymer without the first pair of adjacent reacting units."""
n = self.__first_reaction
if n is None:
return
del self.__units[n:n+2]
self.__cached = None
@property
def is_stable(self):
return self.__first_reaction is None
def stabilize(self):
while not self.is_stable:
self.react()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment