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 |
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: |
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