소스 검색

recipe ratios

raylu 1 개월 전
부모
커밋
9296b602c3
5개의 변경된 파일과 414개의 추가작업 그리고 22개의 파일을 삭제
  1. 48 22
      py/prepare.py
  2. 1 0
      rawData/aug26-recipe-ratios.json
  3. 213 0
      rawData/jul26-recipe-ratios.json
  4. 1 0
      rawData/jun26-recipe-ratios.json
  5. 151 0
      rawData/may26-recipe-ratios.json

+ 48 - 22
py/prepare.py

@@ -109,41 +109,56 @@ def calc_consumption_profit(month: str, prices: typing.Mapping[str, float],
 
 def get_consumption_ratios(month: str) -> typing.Mapping[str, typing.Mapping[str, float]]:
 	with open(f'rawData/{month}-recipes.json', 'r') as f:
-		raw_recipes: typing.Sequence[typing.Mapping] = json.load(f)
+		recipes: typing.Mapping[str, Recipe] = {recipe['RecipeName']: recipe for recipe in json.load(f)}
+	with open(f'rawData/{month}-recipe-ratios.json', 'r') as f:
+		recipe_ratios: dict[str, typing.Mapping[str, float]] = json.load(f)
 	with open('rawData/buildings.json', 'r') as f:
 		buildings: typing.Mapping[str, typing.Mapping] = {b['Ticker']: b for b in json.load(f)}
-	worker_daily_consumption = {
-		'Pioneers': [('COF', 0.5), ('DW', 4), ('RAT', 4), ('OVE', 0.5), ('PWO', 0.2)],
-		'Settlers': [('DW', 5), ('RAT', 6), ('KOM', 1), ('EXO', 0.5), ('REP', 0.2), ('PT', 0.5)],
-		'Technicians': [('DW', 7.5), ('RAT', 7), ('ALE', 1), ('MED', 0.5), ('SC', 0.1), ('HMS', 0.5), ('SCN', 0.1)],
-		'Engineers': [('DW', 10), ('MED', 0.5), ('GIN', 1), ('FIM', 7), ('VG', 0.2), ('HSS', 0.2), ('PDA', 0.1)],
-		'Scientists': [('DW', 10), ('MED', 0.5), ('WIN', 1), ('MEA', 7), ('NST', 0.1), ('LC', 0.2), ('WS', 0.05)],
-	}
 
 	outputs: dict[str, typing.Mapping[str, float]] = {}
-	duplicates = set()
-	for recipe in raw_recipes:
+	duplicates = set() # mats that can be produced by more than 1 recipe
+	for recipe in recipes.values():
 		for output in recipe['Outputs']:
 			output_ticker = output['Ticker']
 			if output_ticker in outputs:
 				duplicates.add(output_ticker)
 				continue
-			ratios = {
-				input['Ticker']: input['Amount'] / output['Amount'] for input in recipe['Inputs']
-			}
-			building = buildings[recipe['BuildingTicker']]
-			for worker, mats in worker_daily_consumption.items():
-				workers = building[worker]
-				for mat, per_100 in mats:
-					consumed_per_day = workers * per_100 / 100
-					# assume 160% efficiency
-					consumed_per_unit_output = consumed_per_day / output['Amount'] * (recipe['TimeMs'] / (24*60*60*1000) / 1.6)
-					ratios[mat] = ratios.get(mat, 0) + consumed_per_unit_output
+			ratios = consumption_ratio_for_recipe(recipe, output, buildings)
 			outputs[output_ticker] = ratios
 	for dupe in duplicates:
-		del outputs[dupe]
+		recipe_ratio = recipe_ratios.pop(dupe)
+		assert dupe == 'SIO' or abs(sum(recipe_ratio.values()) - 1.0) < 1e-6, f"recipe ratio for {dupe} doesn't sum to 1"
+		ratios = collections.defaultdict(float)
+		for recipe_name, weight in recipe_ratio.items():
+			recipe = recipes[recipe_name]
+			(output,) = (o for o in recipe['Outputs'] if o['Ticker'] == dupe)
+			for input_item, ratio in consumption_ratio_for_recipe(recipe, output, buildings).items():
+				ratios[input_item] += weight * ratio
+		outputs[dupe] = ratios
+	assert len(recipe_ratios) == 0, f'unused recipe ratios: {recipe_ratios.keys()}'
 	return outputs
 
+worker_daily_consumption = {
+	'Pioneers': [('COF', 0.5), ('DW', 4), ('RAT', 4), ('OVE', 0.5), ('PWO', 0.2)],
+	'Settlers': [('DW', 5), ('RAT', 6), ('KOM', 1), ('EXO', 0.5), ('REP', 0.2), ('PT', 0.5)],
+	'Technicians': [('DW', 7.5), ('RAT', 7), ('ALE', 1), ('MED', 0.5), ('SC', 0.1), ('HMS', 0.5), ('SCN', 0.1)],
+	'Engineers': [('DW', 10), ('MED', 0.5), ('GIN', 1), ('FIM', 7), ('VG', 0.2), ('HSS', 0.2), ('PDA', 0.1)],
+	'Scientists': [('DW', 10), ('MED', 0.5), ('WIN', 1), ('MEA', 7), ('NST', 0.1), ('LC', 0.2), ('WS', 0.05)],
+}
+def consumption_ratio_for_recipe(recipe: Recipe, output: RecipeMat, buildings: dict) -> typing.Mapping[str, float]:
+	ratios = {
+		input['Ticker']: input['Amount'] / output['Amount'] for input in recipe['Inputs']
+	}
+	building = buildings[recipe['BuildingTicker']]
+	for worker, mats in worker_daily_consumption.items():
+		workers = building[worker]
+		for mat, per_100 in mats:
+			consumed_per_day = workers * per_100 / 100
+			# assume 160% efficiency
+			consumed_per_unit_output = consumed_per_day / output['Amount'] * (recipe['TimeMs'] / (24*60*60*1000) / 1.6)
+			ratios[mat] = ratios.get(mat, 0) + consumed_per_unit_output
+	return ratios
+
 def write_data(month: str, data: dict[str, list[Row]],
 		prod_data: typing.Mapping[str, ProdData], company_data: CompanyData) -> None:
 	with open(f'www/data/prod-data-{month}.json', 'w') as f:
@@ -190,6 +205,17 @@ class Price(typing.TypedDict):
 	VWAP30D: float | None
 	Traded30D: int | None
 
+class Recipe(typing.TypedDict):
+	BuildingTicker: str
+	RecipeName: str
+	Inputs: typing.Sequence[RecipeMat]
+	Outputs: typing.Sequence[RecipeMat]
+	TimeMs: int
+
+class RecipeMat(typing.TypedDict):
+	Ticker: str
+	Amount: float
+
 class ProdData(typing.TypedDict):
 	amount: float
 	volume: float

+ 1 - 0
rawData/aug26-recipe-ratios.json

@@ -0,0 +1 @@
+jul26-recipe-ratios.json

+ 213 - 0
rawData/jul26-recipe-ratios.json

@@ -0,0 +1,213 @@
+{
+	"AHP": {
+		"8xAL 10xFET 1xHE=>4xAHP": 0.75,
+		"12xAL 4xWRH 1xHE=>4xAHP": 0.25
+	},
+	"AL": {
+		"6xALO 1xC 1xO=>3xAL": 0.43,
+		"6xALO 1xO 1xC 1xFLX=>4xAL": 0.56,
+		"2xBER=>1xBE 1xAL 1xSIO": 0.01
+	},
+	"BBH": {
+		"2xAL 1xLST=>1xBBH": 0.6,
+		"2xFE 1xLST=>1xBBH": 0.4
+	},
+	"BDE": {
+		"150xPE=>1xBDE": 0.7,
+		"40xPG=>1xBDE": 0.3
+	},
+	"BEA": {
+		"6xH2O=>4xBEA": 0.9,
+		"1xH2O=>2xBEA": 0.1
+	},
+	"BHP": {
+		"12xAL 1xSTL 1xHE=>4xBHP": 1,
+		"12xAL 1xRE 1xHE=>4xBHP": 0
+	},
+	"BLE": {
+		"10xNAB 3xS 2xO=>4xBLE": 0.9,
+		"1xNA 1xCL 1xO=>3xBLE": 0.1
+	},
+	"BSE": {
+		"1xAL 2xLST=>1xBSE": 0.6,
+		"1xFE 2xLST=>1xBSE": 0.4
+	},
+	"BTA": {
+		"1xFE 50xPE=>1xBTA": 0.7,
+		"1xGL 1xAL=>1xBTA": 0.3
+	},
+	"C": {
+		"4xHCP=>4xC": 0.2,
+		"4xMAI=>4xC": 0.2,
+		"4xGRN=>4xC": 0.2,
+		"4xHCP 2xMAI=>4xC": 0.15,
+		"4xHCP 2xGRN=>4xC": 0.15,
+		"4xHCP 2xGRN 2xMAI=>4xC": 0.1
+	},
+	"DRF": {
+		"50xNFI 1xDCS=>1xDRF": 0.95,
+		"6xAL 1xHE=>1xDRF": 0.05
+	},
+	"DW": {
+		"10xH2O=>7xDW": 0.8,
+		"10xH2O 1xPG=>10xDW": 0.2
+	},
+	"EXO": {
+		"10xOVE 1xAL 1xMFK=>10xEXO": 0.3,
+		"10xOVE 1xAL 1xSWF=>10xEXO": 0.4,
+		"10xOVE 1xAL=>10xEXO": 0.3
+	},
+	"FE": {
+		"6xFEO 1xC 1xO=>3xFE": 0.672,
+		"6xFEO 1xC 1xO 1xFLX=>4xFE": 0.326,
+		"2xTAI=>1xTA 1xFE": 0.001,
+		"2xTAI 4xNA=>1xTA 1xFE": 0.001
+	},
+	"GL": {
+		"2xSIO 1xNA=>10xGL": 0.4,
+		"2xSIO 1xNA 1xSEN=>10xGL": 0.3,
+		"2xSIO 1xNA 1xFLX=>12xGL": 0.3
+	},
+	"GRA": {
+		"30xH2O 1xDDT 3xSOI=>6xGRA": 0.9,
+		"40xH2O 1xDDT=>5xGRA": 0.1
+	},
+	"GRN": {
+		"4xH2O=>4xGRN": 0.9,
+		"1xH2O=>4xGRN": 0.1
+	},
+	"HCB": {
+		"600xWAL 100xMFK=>1xHCB": 1,
+		"500xWRH 100xMFK=>1xHCB": 0
+	},
+	"HCP": {
+		"14xH2O 1xNS=>8xHCP": 0.8,
+		"2xH2O=>4xHCP": 0.2
+	},
+	"HHP": {
+		"12xAL 4xALR 1xHE=>4xHHP": 0.3,
+		"12xAL 4xAST 1xHE=>4xHHP": 0.7
+	},
+	"HOP": {
+		"40xH2O 2xDDT 4xSOI=>18xHOP": 0.85,
+		"60xH2O 2xDDT=>15xHOP": 0.15
+	},
+	"LCB": {
+		"200xAST 20xMFK=>1xLCB": 1,
+		"100xWRH 20xMFK=>1xLCB": 0
+	},
+	"MAI": {
+		"20xH2O 2xNS=>12xMAI": 0.8,
+		"4xH2O=>12xMAI": 0.2
+	},
+	"MCB": {
+		"100xAST 16xMFK=>1xMCB": 1,
+		"48xWRH 16xMFK=>1xMCB": 0
+	},
+	"MUS": {
+		"4xNS=>12xMUS": 0.8,
+		"1xNS=>4xMUS": 0.2
+	},
+	"OVE": {
+		"100xPE 25xPG=>20xOVE": 0.2,
+		"1xRCO 50xPE=>20xOVE": 0.8,
+		"1xCOT 10xPG=>30xOVE": 0
+	},
+	"PIB": {
+		"20xH2O 1xDDT 2xSOI=>12xPIB": 0.9,
+		"30xH2O 1xDDT=>10xPIB": 0.1
+	},
+	"PPA": {
+		"2xBEA 1xH2O=>4xPPA": 0.1,
+		"1xALG 1xH2O 1xBEA=>6xPPA": 0.7,
+		"2xALG 1xH2O=>4xPPA": 0.2
+	},
+	"PT": {
+		"1xSTL 1xTRN=>7xPT": 0.7,
+		"1xSTL=>5xPT": 0.05,
+		"1xSTL 1xW=>15xPT": 0.05,
+		"1xSTL 2xSFK=>6xPT": 0.2
+	},
+	"RAT": {
+		"1xGRN 1xALG 1xVEG=>10xRAT": 0.1,
+		"1xGRN 1xALG 1xNUT=>10xRAT": 0.08,
+		"1xMUS 1xVEG 1xGRN=>10xRAT": 0.1,
+		"1xMAI 1xALG 1xVEG=>10xRAT": 0.08,
+		"1xMUS 1xVEG 1xMAI=>10xRAT": 0.08,
+		"1xMUS 1xNUT 1xGRN=>10xRAT": 0.08,
+		"1xMAI 1xBEA 1xNUT=>10xRAT": 0.08,
+		"1xMAI 1xBEA 1xVEG=>10xRAT": 0.08,
+		"1xMUS 1xNUT 1xMAI=>10xRAT": 0.08,
+		"1xGRN 1xBEA 1xNUT=>10xRAT": 0.08,
+		"1xMAI 1xALG 1xNUT=>10xRAT": 0.08,
+		"1xGRN 1xBEA 1xVEG=>10xRAT": 0.08
+	},
+	"RCO": {
+		"10xH2O 4xNS=>2xRCO": 0.7,
+		"2xH2O=>1xRCO": 0.1,
+		"2xH2O 4xNS=>2xRCO": 0.2
+	},
+	"RE": {
+		"8xREO 1xC 1xO 1xFLX=>5xRE": 0.88,
+		"8xREO 1xC 1xO=>4xRE": 0.12
+	},
+	"RG": {
+		"10xGL 15xPG=>10xRG": 0.45,
+		"10xGL 15xPG 1xSEN=>10xRG": 0.55
+	},
+	"RHP": {
+		"12xAL 4xTI 1xHE=>4xRHP": 0.95,
+		"12xAL 4xRE 1xHE=>4xRHP": 0.05
+	},
+	"SCB": {
+		"50xFAL 12xMFK=>1xSCB": 1,
+		"36xALR 12xMFK=>1xSCB": 0
+	},
+	"SF": {
+		"1xAMM 2xGAL 3xH=>100xSF": 0.8,
+		"1xAMM 5xNAB=>150xSF": 0.2
+	},
+	"SI": {
+		"3xSIO 1xC 1xO 1xFLX=>1xSI": 0.2,
+		"3xSIO 1xC 1xO=>1xSI": 0.1,
+		"3xSIO 1xAL=>1xSI": 0.7,
+		"4xTS 1xO 1xAL=>1xSI": 0
+	},
+	"SIO": {
+		"2xZIR=>1xZR 2xSIO": 0.01,
+		"2xBER=>1xBE 1xAL 1xSIO": 0.01,
+		"2xZIR 4xNA=>1xZR 2xSIO": 0.01
+	},
+	"TA": {
+		"2xTAI=>1xTA 1xFE": 0.3,
+		"2xTAI 4xNA=>1xTA 1xFE": 0.7
+	},
+	"TCB": {
+		"20xFE 4xMFK=>1xTCB": 1,
+		"12xRE 4xMFK=>1xTCB": 0
+	},
+	"TI": {
+		"4xTIO 1xC 1xO 1xNA=>2xTI": 0.8,
+		"4xTIO 1xC 1xO=>2xTI": 0.2
+	},
+	"VCB": {
+		"200xFET 20xMFK=>1xVCB": 1,
+		"100xWRH 20xMFK=>1xVCB": 0
+	},
+	"VEG": {
+		"16xH2O 1xNS=>6xVEG": 0.7,
+		"3xH2O=>4xVEG": 0.3
+	},
+	"VSC": {
+		"35xFE 8xMFK=>1xVSC": 1,
+		"20xRE 8xMFK=>1xVSC": 0
+	},
+	"WCB": {
+		"100xAST 100xFET 20xMFK=>1xWCB": 1,
+		"70xALR 70xWRH 20xMFK=>1xWCB": 0
+	},
+	"ZR": {
+		"2xZIR=>1xZR 2xSIO": 0.2,
+		"2xZIR 4xNA=>1xZR 2xSIO": 0.8
+	}
+}

+ 1 - 0
rawData/jun26-recipe-ratios.json

@@ -0,0 +1 @@
+may26-recipe-ratios.json

+ 151 - 0
rawData/may26-recipe-ratios.json

@@ -0,0 +1,151 @@
+{
+	"AL": {
+		"6xALO 1xC 1xO=>3xAL": 0.43,
+		"6xALO 1xO 1xC 1xFLX=>4xAL": 0.56,
+		"2xBER=>1xBE 1xAL 1xSIO": 0.01
+	},
+	"BBH": {
+		"2xAL 1xLST=>1xBBH": 0.6,
+		"2xFE 1xLST=>1xBBH": 0.4
+	},
+	"BDE": {
+		"150xPE=>1xBDE": 0.7,
+		"40xPG=>1xBDE": 0.3
+	},
+	"BEA": {
+		"6xH2O=>4xBEA": 0.9,
+		"1xH2O=>2xBEA": 0.1
+	},
+	"BLE": {
+		"10xNAB 3xS 2xO=>4xBLE": 0.9,
+		"1xNA 1xCL 1xO=>3xBLE": 0.1
+	},
+	"BSE": {
+		"1xAL 2xLST=>1xBSE": 0.6,
+		"1xFE 2xLST=>1xBSE": 0.4
+	},
+	"BTA": {
+		"1xFE 50xPE=>1xBTA": 0.7,
+		"1xGL 1xAL=>1xBTA": 0.3
+	},
+	"C": {
+		"4xHCP=>4xC": 0.2,
+		"4xMAI=>4xC": 0.2,
+		"4xGRN=>4xC": 0.2,
+		"4xHCP 2xMAI=>4xC": 0.15,
+		"4xHCP 2xGRN=>4xC": 0.15,
+		"4xHCP 2xGRN 2xMAI=>4xC": 0.1
+	},
+	"DRF": {
+		"50xNFI 1xDCS=>1xDRF": 0.95,
+		"6xAL 1xHE=>1xDRF": 0.05
+	},
+	"DW": {
+		"10xH2O=>7xDW": 0.8,
+		"10xH2O 1xPG=>10xDW": 0.2
+	},
+	"EXO": {
+		"10xOVE 1xAL 1xMFK=>10xEXO": 0.3,
+		"10xOVE 1xAL 1xSWF=>10xEXO": 0.4,
+		"10xOVE 1xAL=>10xEXO": 0.3
+	},
+	"FE": {
+		"6xFEO 1xC 1xO=>3xFE": 0.672,
+		"6xFEO 1xC 1xO 1xFLX=>4xFE": 0.326,
+		"2xTAI=>1xTA 1xFE": 0.002
+	},
+	"GL": {
+		"2xSIO 1xNA=>10xGL": 0.4,
+		"2xSIO 1xNA 1xSEN=>10xGL": 0.3,
+		"2xSIO 1xNA 1xFLX=>12xGL": 0.3
+	},
+	"GRA": {
+		"30xH2O 1xDDT 3xSOI=>6xGRA": 0.9,
+		"40xH2O 1xDDT=>5xGRA": 0.1
+	},
+	"GRN": {
+		"4xH2O=>4xGRN": 0.9,
+		"1xH2O=>4xGRN": 0.1
+	},
+	"HCP": {
+		"14xH2O 1xNS=>8xHCP": 0.8,
+		"2xH2O=>4xHCP": 0.2
+	},
+	"HOP": {
+		"40xH2O 2xDDT 4xSOI=>18xHOP": 0.85,
+		"60xH2O 2xDDT=>15xHOP": 0.15
+	},
+	"MAI": {
+		"20xH2O 2xNS=>12xMAI": 0.8,
+		"4xH2O=>12xMAI": 0.2
+	},
+	"MUS": {
+		"4xNS=>12xMUS": 0.8,
+		"1xNS=>4xMUS": 0.2
+	},
+	"OVE": {
+		"100xPE 25xPG=>20xOVE": 0.2,
+		"1xRCO 50xPE=>20xOVE": 0.8,
+		"1xCOT 10xPG=>30xOVE": 0
+	},
+	"PIB": {
+		"20xH2O 1xDDT 2xSOI=>12xPIB": 0.9,
+		"30xH2O 1xDDT=>10xPIB": 0.1
+	},
+	"PPA": {
+		"2xBEA 1xH2O=>4xPPA": 0.1,
+		"1xALG 1xH2O 1xBEA=>6xPPA": 0.7,
+		"2xALG 1xH2O=>4xPPA": 0.2
+	},
+	"PT": {
+		"1xSTL 1xTRN=>7xPT": 0.7,
+		"1xSTL=>5xPT": 0.05,
+		"1xSTL 1xW=>15xPT": 0.05,
+		"1xSTL 2xSFK=>6xPT": 0.2
+	},
+	"RAT": {
+		"1xGRN 1xALG 1xVEG=>10xRAT": 0.1,
+		"1xGRN 1xALG 1xNUT=>10xRAT": 0.08,
+		"1xMUS 1xVEG 1xGRN=>10xRAT": 0.1,
+		"1xMAI 1xALG 1xVEG=>10xRAT": 0.08,
+		"1xMUS 1xVEG 1xMAI=>10xRAT": 0.08,
+		"1xMUS 1xNUT 1xGRN=>10xRAT": 0.08,
+		"1xMAI 1xBEA 1xNUT=>10xRAT": 0.08,
+		"1xMAI 1xBEA 1xVEG=>10xRAT": 0.08,
+		"1xMUS 1xNUT 1xMAI=>10xRAT": 0.08,
+		"1xGRN 1xBEA 1xNUT=>10xRAT": 0.08,
+		"1xMAI 1xALG 1xNUT=>10xRAT": 0.08,
+		"1xGRN 1xBEA 1xVEG=>10xRAT": 0.08
+	},
+	"RCO": {
+		"10xH2O 4xNS=>2xRCO": 0.7,
+		"2xH2O=>1xRCO": 0.1,
+		"2xH2O 4xNS=>2xRCO": 0.2
+	},
+	"RE": {
+		"8xREO 1xC 1xO 1xFLX=>5xRE": 0.88,
+		"8xREO 1xC 1xO=>4xRE": 0.12
+	},
+	"RG": {
+		"10xGL 15xPG=>10xRG": 0.45,
+		"10xGL 15xPG 1xSEN=>10xRG": 0.55
+	},
+	"SF": {
+		"1xAMM 2xGAL 3xH=>100xSF": 0.8,
+		"1xAMM 5xNAB=>150xSF": 0.2
+	},
+	"SI": {
+		"3xSIO 1xC 1xO 1xFLX=>1xSI": 0.2,
+		"3xSIO 1xC 1xO=>1xSI": 0.1,
+		"3xSIO 1xAL=>1xSI": 0.7,
+		"4xTS 1xO 1xAL=>1xSI": 0
+	},
+	"SIO": {
+		"2xZIR=>1xZR 2xSIO": 0.01,
+		"2xBER=>1xBE 1xAL 1xSIO": 0.01
+	},
+	"VEG": {
+		"16xH2O 1xNS=>6xVEG": 0.7,
+		"3xH2O=>4xVEG": 0.3
+	}
+}