diff --git a/2015/d19/ex2/ex2.py b/2015/d19/ex2/ex2.py new file mode 100755 index 0000000..4195e9b --- /dev/null +++ b/2015/d19/ex2/ex2.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +import collections +import sys + + +def solve(input: str) -> int: + def parse(input: str) -> tuple[dict[str, list[str]], str]: + raw_replacements, molecule = input.strip().split("\n\n") + res: dict[str, list[str]] = collections.defaultdict(list) + for start, end in ( + line.split(" => ") for line in raw_replacements.splitlines() + ): + res[start].append(end) + return res, molecule + + def inverse(input: dict[str, list[str]]) -> dict[str, str]: + res: dict[str, str] = {} + for key, vals in input.items(): + for val in vals: + res[val] = key + assert len(res) == sum(map(len, input.values())) # Sanity check + return res + + def build(replacements: dict[str, list[str]], molecule: str) -> int: + # We will be "building down" to the electron, so inverse the replacement mapping + inversed_replacements = inverse(replacements) + # Order the replacement needles to try the longest ones first + needles = sorted(inversed_replacements.keys(), key=len, reverse=True) + res = 0 + while molecule != "e": + for needle in needles: + if needle not in molecule: + continue + res += 1 + molecule = molecule.replace(needle, inversed_replacements[needle], 1) + return res + + replacements, molecule = parse(input) + return build(replacements, molecule) + + +def main() -> None: + input = sys.stdin.read() + print(solve(input)) + + +if __name__ == "__main__": + main()