diff --git a/2021/d14/ex1/ex1.py b/2021/d14/ex1/ex1.py new file mode 100755 index 0000000..da06537 --- /dev/null +++ b/2021/d14/ex1/ex1.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +import itertools +import sys +from collections import Counter +from typing import Dict, Iterator, List, Tuple, TypeVar + +Rules = Dict[str, str] + +T = TypeVar("T") + + +def nth(iterable: Iterator[T], n: int) -> T: + return next(itertools.islice(iterable, n, None)) + + +def solve(input: List[str]) -> int: + def parse() -> Tuple[str, Rules]: + template = input[0] + rules = { + pair: insertion + for pair, insertion in map(lambda s: s.split(" -> "), input[2:]) + } + return template, rules + + def step(template: str, rules: Rules) -> str: + res: List[str] = [] + + # Look at all pairs + for a, b in zip(template, template[1:]): + res.append(a) + if (a + b) in rules: + res.append(rules[a + b]) + + # Add the last element + res.append(template[-1]) + return "".join(res) + + def polymerize(template: str, rules: Rules) -> Iterator[str]: + while True: + yield (template := step(template, rules)) + + def score(template: str) -> int: + counts = [n for __, n in Counter(template).most_common()] + return counts[0] - counts[-1] + + template, rules = parse() + return score(nth(polymerize(template, rules), 10 - 1)) + + +def main() -> None: + input = [line.strip() for line in sys.stdin.readlines()] + print(solve(input)) + + +if __name__ == "__main__": + main() diff --git a/2021/d14/ex1/input b/2021/d14/ex1/input new file mode 100644 index 0000000..bae5f8e --- /dev/null +++ b/2021/d14/ex1/input @@ -0,0 +1,102 @@ +NNSOFOCNHBVVNOBSBHCB + +HN -> S +FK -> N +CH -> P +VP -> P +VV -> C +PB -> H +CP -> F +KO -> P +KN -> V +NO -> K +NF -> N +CO -> P +HO -> H +VH -> V +OV -> C +VS -> F +PK -> H +OS -> S +BF -> S +SN -> P +NK -> N +SV -> O +KB -> O +ON -> O +FN -> H +FO -> N +KV -> S +CS -> C +VO -> O +SP -> O +VK -> H +KP -> S +SK -> N +NC -> B +PN -> N +HV -> O +HS -> C +CN -> N +OO -> V +FF -> B +VC -> V +HK -> K +CC -> H +BO -> H +SC -> O +HH -> C +BV -> P +OB -> O +FC -> H +PO -> C +FV -> C +BK -> F +HB -> B +NH -> P +KF -> N +BP -> H +KK -> O +OH -> K +CB -> H +CK -> C +OK -> H +NN -> F +VF -> N +SO -> K +OP -> F +NP -> B +FS -> S +SH -> O +FP -> O +SF -> V +HF -> N +KC -> K +SB -> V +FH -> N +SS -> C +BB -> C +NV -> K +OC -> S +CV -> N +HC -> P +BC -> N +OF -> K +BH -> N +NS -> K +BN -> F +PC -> C +CF -> N +HP -> F +BS -> O +PF -> S +PV -> B +KH -> K +VN -> V +NB -> N +PH -> V +KS -> B +PP -> V +PS -> C +VB -> N +FB -> N diff --git a/2021/d14/ex2/ex2.py b/2021/d14/ex2/ex2.py new file mode 100755 index 0000000..46a9e40 --- /dev/null +++ b/2021/d14/ex2/ex2.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python + +import itertools +import sys +from copy import deepcopy +from typing import Counter, Dict, Iterator, List, NamedTuple, Tuple, TypeVar + + +class Template(NamedTuple): + bigrams: Counter[str] + counts: Counter[str] + + +Rules = Dict[str, str] + +T = TypeVar("T") + + +def nth(iterable: Iterator[T], n: int) -> T: + return next(itertools.islice(iterable, n, None)) + + +def solve(input: List[str]) -> int: + def parse() -> Tuple[Template, Rules]: + bigrams = Counter(a + b for a, b in zip(input[0], input[0][1:])) + counts = Counter(input[0]) + rules = { + pair: insertion + for pair, insertion in map(lambda s: s.split(" -> "), input[2:]) + } + return Template(bigrams, counts), rules + + def step(template: Template, rules: Rules) -> Template: + bigrams: Counter[str] = Counter() + counts = deepcopy(template.counts) + for p, n in template.bigrams.items(): + if p in rules: + insertion = rules[p] + bigrams[p[0] + insertion] += n + bigrams[insertion + p[1]] += n + counts[insertion] += n + else: + # Counts are not changed in this case + bigrams[p] = n + return Template(bigrams, counts) + + def polymerize(template: Template, rules: Rules) -> Iterator[Template]: + while True: + yield (template := step(template, rules)) + + def score(template: Template) -> int: + nums = [n for __, n in template.counts.most_common()] + return nums[0] - nums[-1] + + template, rules = parse() + return score(nth(polymerize(template, rules), 40 - 1)) + + +def main() -> None: + input = [line.strip() for line in sys.stdin.readlines()] + print(solve(input)) + + +if __name__ == "__main__": + main() diff --git a/2021/d14/ex2/input b/2021/d14/ex2/input new file mode 100644 index 0000000..bae5f8e --- /dev/null +++ b/2021/d14/ex2/input @@ -0,0 +1,102 @@ +NNSOFOCNHBVVNOBSBHCB + +HN -> S +FK -> N +CH -> P +VP -> P +VV -> C +PB -> H +CP -> F +KO -> P +KN -> V +NO -> K +NF -> N +CO -> P +HO -> H +VH -> V +OV -> C +VS -> F +PK -> H +OS -> S +BF -> S +SN -> P +NK -> N +SV -> O +KB -> O +ON -> O +FN -> H +FO -> N +KV -> S +CS -> C +VO -> O +SP -> O +VK -> H +KP -> S +SK -> N +NC -> B +PN -> N +HV -> O +HS -> C +CN -> N +OO -> V +FF -> B +VC -> V +HK -> K +CC -> H +BO -> H +SC -> O +HH -> C +BV -> P +OB -> O +FC -> H +PO -> C +FV -> C +BK -> F +HB -> B +NH -> P +KF -> N +BP -> H +KK -> O +OH -> K +CB -> H +CK -> C +OK -> H +NN -> F +VF -> N +SO -> K +OP -> F +NP -> B +FS -> S +SH -> O +FP -> O +SF -> V +HF -> N +KC -> K +SB -> V +FH -> N +SS -> C +BB -> C +NV -> K +OC -> S +CV -> N +HC -> P +BC -> N +OF -> K +BH -> N +NS -> K +BN -> F +PC -> C +CF -> N +HP -> F +BS -> O +PF -> S +PV -> B +KH -> K +VN -> V +NB -> N +PH -> V +KS -> B +PP -> V +PS -> C +VB -> N +FB -> N