Quest 7: Namegraph
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
Link to participate: https://everybody.codes/


Python
# pairwise helps picking consecutive values easier # [A,B,C,D] -> [AB, BC, CD] from itertools import pairwise # returns names and dict[str, set[str]] of allowed transitions def parse_data(data: str): transition_map = {} lines = data.splitlines() for rule_str in lines[2:]: before, after = rule_str.split(" > ") transition_map[before] = set(after.split(',')) names = lines[0].split(',') return names, transition_map # checks if name is valid according to transition_map def is_name_valid(transition_map: dict[str, set[str]], name: str) -> bool: for a, b in pairwise(name): if a not in transition_map or b not in transition_map[a]: return False return True def part1(data: str): names, transition_map = parse_data(data) for name in names: if is_name_valid(transition_map, name): return name # <assert snipped> def part2(data: str): ans = 0 names, transition_map = parse_data(data) for i, name in enumerate(names): if is_name_valid(transition_map, name): ans += i + 1 return ans # <assert snipped> def part3(data: str): prefixes, transition_map = parse_data(data) # remove prefixes that are sub-prefixes of others # to avoid double counting superset_prefixes = [] for i, p1 in enumerate(prefixes): for j, p2 in enumerate(prefixes): if i != j and p1.startswith(p2): break else: # no break -> p1 is not a sub-prefix superset_prefixes.append(p1) variants = 0 for prefix in superset_prefixes: if not is_name_valid(transition_map, prefix): continue # DFS to count all valid name extensions stack = [(prefix[-1], len(prefix))] while stack: prev, name_len = stack.pop() if name_len >= 7: variants += 1 if name_len == 11: continue for next_letter in transition_map.get(prev, []): stack.append((next_letter, name_len + 1)) return variants # <assert snipped>