n | def parse_class_definitions(code_block): | n | def extract_classes(code): |
| classes_info = {} | | result = {} |
| for line in code_block.splitlines(): | | for statement in code.splitlines(): |
| line = line.strip() | | statement = statement.strip() |
| if not line.startswith('class '): | | if not statement.startswith('class '): |
| continue | | continue |
n | name_end_pos = line.find('(') | n | class_name_end = statement.find('(') |
| if name_end_pos == -1: | | if class_name_end == -1: |
| name_end_pos = line.find(':') | | class_name_end = statement.find(':') |
| class_name = line[6:name_end_pos].strip() | | class_name = statement[6:class_name_end].strip() |
| if '(' in line: | | if '(' in statement: |
| parents_start_pos = line.find('(') + 1 | | parents_start = statement.find('(') + 1 |
| parents_end_pos = line.find(')') | | parents_end = statement.find(')') |
| parents = line[parents_start_pos:parents_end_pos].strip() | | parents = statement[parents_start:parents_end].strip() |
| parent_classes = [parent.strip() for parent in parents.split | | parents_list = [parent.strip() for parent in parents.split(' |
| (',')] if parents else [] | | ,')] if parents else [] |
| else: | | else: |
n | parent_classes = [] | n | parents_list = [] |
| classes_info[class_name] = parent_classes | | result[class_name] = parents_list |
| return classes_info | | return result |
| | | |
n | def check_class_hierarchy(classes_info): | n | def validate_hierarchy(classes): |
| | | |
n | def compute_mro(class_name, resolved_hierarchy, unresolved_classes): | n | def resolve_mro(class_name, resolved, unresolved): |
| if class_name in resolved_hierarchy: | | if class_name in resolved: |
| return resolved_hierarchy[class_name] | | return resolved[class_name] |
| if class_name in unresolved_classes: | | if class_name in unresolved: |
| raise ValueError('Circular inheritance detected') | | raise ValueError('Cyclic dependency detected') |
| unresolved_classes.add(class_name) | | unresolved.add(class_name) |
| parent_classes = classes_info.get(class_name, []) | | bases = classes.get(class_name, []) |
| mro = [class_name] + merge_mros([compute_mro(parent, resolved_hi | | mro = [class_name] + combine_mros([resolve_mro(base, resolved, u |
| erarchy, unresolved_classes) for parent in parent_classes] + [parent_cla | | nresolved) for base in bases] + [bases]) |
| sses]) | | |
| resolved_hierarchy[class_name] = mro | | resolved[class_name] = mro |
| unresolved_classes.remove(class_name) | | unresolved.remove(class_name) |
| return mro | | return mro |
| | | |
n | def merge_mros(mro_sequences): | n | def combine_mros(sequences): |
| merged_result = [] | | result = [] |
| while any(mro_sequences): | | while any(sequences): |
| for seq in mro_sequences: | | for seq in sequences: |
| if not seq: | | if not seq: |
| continue | | continue |
n | candidate_class = seq[0] | n | candidate = seq[0] |
| if all((candidate_class not in s[1:] for s in mro_sequen | | if all((candidate not in s[1:] for s in sequences)): |
| ces)): | | |
| merged_result.append(candidate_class) | | result.append(candidate) |
| for s in mro_sequences: | | for s in sequences: |
| if s and s[0] == candidate_class: | | if s and s[0] == candidate: |
| s.pop(0) | | s.pop(0) |
| break | | break |
| else: | | else: |
n | raise ValueError('Invalid MRO structure') | n | raise ValueError('Invalid MRO') |
| return merged_result | | return result |
| resolved_hierarchy = {} | | resolved = {} |
| for class_name in classes_info: | | for class_name in classes: |
| compute_mro(class_name, resolved_hierarchy, set()) | | resolve_mro(class_name, resolved, set()) |
| return True | | return True |
n | input_program = '' | n | input_code = '' |
| while (user_input := input().strip()): | | while (line := input().strip()): |
| input_program += user_input + '\n' | | input_code += line + '\n' |
| try: | | try: |
t | class_data = parse_class_definitions(input_program) | t | class_structure = extract_classes(input_code) |
| print('Yes' if check_class_hierarchy(class_data) else 'No') | | print('Yes' if validate_hierarchy(class_structure) else 'No') |
| except ValueError: | | except ValueError: |
| print('No') | | print('No') |