-
Notifications
You must be signed in to change notification settings - Fork 1
/
day07_recurse.py
94 lines (69 loc) · 2.79 KB
/
day07_recurse.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
"""Advent of Code 2017 -- Day 7
http://adventofcode.com/2017/day/7
"""
from typing import Dict, List, Set, Tuple
SUBPROGRAM_FLAG = '-> '
INPUT = '07_input.txt'
TEST_INPUT = '07_test_input.txt'
# SivjiNote: Solved Part 1 in a very inefficient way
#
# def get_all_programs_and_subprograms(file: str) -> Tuple[List[str], List[str]]:
# with open(file, 'r') as f:
# all_programs = []
# all_subprograms = []
# for line in f.readlines():
# program, subprogram = (
# current_programs_and_subprograms(line.strip()))
# all_programs.append(program)
# all_subprograms.extend(subprogram)
# return all_programs, all_subprograms
# def get_bottom_program(program: List[str], subprograms: List[str]) -> Set:
# return set(programs) - set(subprograms)
def current_programs_and_subprograms(stack: str) -> Tuple[str, List[str]]:
curr_program = stack.split()[0]
subprograms: List[str] = []
if stack.find(SUBPROGRAM_FLAG) > 0:
subprograms = stack.split(SUBPROGRAM_FLAG)[1].split(', ')
return (curr_program, subprograms)
def parse_call_stack(prog_info: str) -> Tuple[Dict, Dict, List]:
weights = {}
subprograms = {}
all_subprograms = []
with open(prog_info, 'r') as f:
for line in f.readlines():
name, tower = current_programs_and_subprograms(line.strip())
weight = int(line[line.find('(') + 1: line.find(')')])
weights[name] = weight
if tower:
subprograms[name] = tower
all_subprograms.extend(tower)
return weights, subprograms, all_subprograms
def get_weight(node):
"""Recursively get weight
As a side effect, let's answer the question
"""
# if leaf
if node in leaves:
return weights[node]
tower_weights = []
additional_info = {}
for subprogram in subprograms[node]:
subprogram_weight = get_weight(subprogram)
additional_info[subprogram] = get_weight(subprogram)
tower_weights.append(subprogram_weight)
total_weight = sum(tower_weights) + weights[node]
if len(set(tower_weights)) > 1:
print(additional_info, set(tower_weights))
return total_weight
if __name__ == "__main__":
# programs, subprograms = get_all_programs_and_subprograms(TEST_INPUT)
# assert get_bottom_program(programs, subprograms) == {'tknk'}
# programs, subprograms = get_all_programs_and_subprograms(INPUT)
# print(get_bottom_program(programs, subprograms))
weights, subprograms, all_subprograms = parse_call_stack(INPUT)
root = (set(weights.keys()) - set(all_subprograms)).pop()
print(f'Bottom Program: {root}')
# get the weight of the leaves in
leaves = set(weights.keys()) - set(subprograms.keys())
get_weight(root)
print('fin.')