2 changed files with 132 additions and 58 deletions
-
9input
-
181total_cost.py
@ -0,0 +1,9 @@ |
|||
1 |
|||
bunch of screws |
|||
tiny silver nugget |
|||
end |
|||
1 |
|||
tiny iron nugget *2 |
|||
end |
|||
0 |
|||
0 |
|||
@ -1,60 +1,125 @@ |
|||
import sys |
|||
import re |
|||
compound = {} |
|||
base_comp = set() |
|||
|
|||
def get_input(comp): |
|||
ret = {} |
|||
ret['type'] = input('type: ').lower() |
|||
ret['parents'] = set() |
|||
if type == 'compound': |
|||
ret['sub'] = {} |
|||
first = True |
|||
while True: |
|||
i = input('sub: ' if first else '>').lower() |
|||
if i == 'end': |
|||
break |
|||
if i != '' |
|||
s = re.split(r' *\* ',i) |
|||
if len(s) == 2: |
|||
name,count = s |
|||
ITEMS = {} |
|||
################################################################################################################################ |
|||
# file operations # |
|||
# this section is dedicated to operations that save, load, and parse data stored to disk # |
|||
# || || || || || || || || || || || # |
|||
# \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ # |
|||
################################################################################################################################ |
|||
|
|||
################################################################################################################################ |
|||
# user input # |
|||
# this section is dedicated to operations that will not have any other purpose other than collecting data # |
|||
# || || || || || || || || || || || # |
|||
# \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ # |
|||
################################################################################################################################ |
|||
class user_input: |
|||
def __init__(self,comp_name): |
|||
valid = ('raw','compound') |
|||
error = True |
|||
while not error: |
|||
try: |
|||
type = int(input("~{}~\ntype (0. {} | 1. {}): ".format(comp_name,*valid))) |
|||
error = False |
|||
except ValueError: |
|||
pass |
|||
self.type = valid[type] |
|||
if self.type == 'compound': |
|||
self.subs = {} |
|||
i = 1 |
|||
while True: |
|||
inp = input('sub #{} ({{comp_name}} * {{count}}): '.format(i)) |
|||
if inp == 'end': |
|||
break |
|||
sr = re.split(r' *\* *',inp) |
|||
name = sr[0] |
|||
if len(sr) == 1: |
|||
count = 1 |
|||
else: |
|||
name = s[0] |
|||
count = 0 |
|||
ret[name] = int(count) |
|||
first = False |
|||
return ret |
|||
|
|||
def get_sub(comp): |
|||
# either not base component or not entered yet |
|||
if comp not in base_comp: |
|||
try: |
|||
# check to see if it is already entered |
|||
subs = compound[comp] |
|||
except KeyError: |
|||
# entry |
|||
subs = get_input(comp) |
|||
|
|||
if subs['type'] == 'base': |
|||
base_comp.add(comp) |
|||
else: |
|||
compound[comp] = subs |
|||
return subs |
|||
|
|||
|
|||
def __inner__(comp,count,bases,components,prev = None): |
|||
component_data = get_sub(comp) |
|||
if prev: |
|||
component_data['parents'].add(prev) |
|||
# not a compound component |
|||
if component_data is None: |
|||
prev = bases.get(comp,0) |
|||
bases[comp] = prev + count |
|||
else: |
|||
prev = components.get(comp,0) |
|||
components[comp] = prev + count |
|||
for sub,count in component_data['sub']: |
|||
__inner__(sub,count,bases,components,comp) |
|||
|
|||
def get_overall_usage(comp): |
|||
ret_bases = {} |
|||
ret_components = {} |
|||
count = int(sr[1]) |
|||
self.subs[name] = count |
|||
i += 1 |
|||
|
|||
def recursive_fill_in(comp_name): |
|||
global ITEMS |
|||
if not comp_name in ITEMS.keys(): |
|||
res = user_input(comp_name) |
|||
if res.type == 'raw': |
|||
ITEMS[comp_name] = raw_material(comp_name) |
|||
else: |
|||
ITEMS[comp_name] = complex_item(comp_name,res.subs) |
|||
for sub in res.subs.keys(): |
|||
recursive_fill_in(sub) |
|||
|
|||
|
|||
|
|||
################################################################################################################################ |
|||
# complexity # |
|||
# this section is dedicated to operations that involve all processing and understanding of the input data # |
|||
# || || || || || || || || || || || # |
|||
# \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ # |
|||
################################################################################################################################ |
|||
class item: |
|||
def __init__(self,name): |
|||
self.name = name |
|||
global ITEMS |
|||
ITEMS[name] = self |
|||
class raw_material(item): |
|||
def __init__(self,name): |
|||
super().__init__(name) |
|||
self.complexity = 0 |
|||
class complex_item(item): |
|||
def __init__(self,name,sub_components): |
|||
super().__init__(name) |
|||
self.sub_components = sub_components |
|||
self.naive_complexity = True |
|||
self.all_sub = set(self.sub_components.keys()) |
|||
|
|||
def recalculate_total_completixy(self): |
|||
for name in self.sub_components.keys(): |
|||
component = ITEMS[name] |
|||
if isinstance(component,complex_item): |
|||
if component.naive_complexity: |
|||
component.recalculate_total_completixy() |
|||
component.naive_complexity = False |
|||
self.all_sub.update(component.all_sub) |
|||
|
|||
@property |
|||
def complexity(self): |
|||
if self.naive_complexity: |
|||
self.recalculate_total_completixy() |
|||
self.naive_complexity = False |
|||
return len(self.all_sub) |
|||
|
|||
def get_raw_material_cost(self,ret = {}): |
|||
for name,count in self.sub_components.items(): |
|||
component = ITEMS[name] |
|||
if isinstance(component,raw_material): |
|||
prev = ret.get(name,0) |
|||
ret[name] = prev + count |
|||
elif isinstance(component,complex_item): |
|||
component.get_raw_material_cost(ret) |
|||
return ret |
|||
|
|||
def get_component_cost(self,ret = {}): |
|||
for name,count in self.sub_components.items(): |
|||
component = ITEMS[name] |
|||
if isinstance(component,complex_item): |
|||
prev = ret.get(name,0) |
|||
ret[name] = prev + count |
|||
component.get_component_cost(ret) |
|||
return ret |
|||
|
|||
def get_build_info(self): |
|||
component_view = self.get_raw_material_cost() |
|||
material_view = self.get_component_cost() |
|||
build_order = component_view.items() |
|||
build_order = sorted(build_order,key = lambda item: ITEMS[item[0]].complexity) |
|||
return material_view,build_order |
|||
def main(): |
|||
name = sys.argv[1] |
|||
recursive_fill_in(name) |
|||
print(ITEMS[name].get_build_info()) |
|||
if __name__ == "__main__": |
|||
main() |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue