diff --git a/bonemarketsolver/objects/bone_market_model.py b/bonemarketsolver/objects/bone_market_model.py index 232bd19..6981082 100644 --- a/bonemarketsolver/objects/bone_market_model.py +++ b/bonemarketsolver/objects/bone_market_model.py @@ -33,24 +33,6 @@ Each parameter is interpreted as a BoundedLinearExpression, and a layer of indir super().AddDivisionEquality(intermediate_target, intermediate_num, intermediate_denom) return (target_constraint, num_constraint, denom_constraint) - def AddDivisionMultiplicationEquality(self, target, num, denom, multiple = None): - """Adds `target == (num // denom) * multiple`. - -Each parameter is interpreted as a BoundedLinearExpression, and a layer of indirection is applied such that each Constraint in the returned tuple can accept an enforcement literal. - -`multiple` defaults to the same value as `denom` if unspecified.""" - quotient = self.NewIntVar(f'{repr(target)} == ({repr(num)} // {repr(denom)}) * {repr(multiple)}: quotient') - intermediate_num, num_constraint = self.NewIntermediateIntVar(num, f'{repr(target)} == ({repr(num)} // {repr(denom)}) * {repr(multiple)}: num', lb = 0) - intermediate_denom, denom_constraint = self.NewIntermediateIntVar(denom, f'{repr(target)} == ({repr(num)} // {repr(denom)}) * {repr(multiple)}: denom', lb = 1) - intermediate_target, target_constraint = self.NewIntermediateIntVar(target, f'{repr(target)} == ({repr(num)} // {repr(denom)}) * {repr(multiple)}: target') - if multiple: - intermediate_multiple, multiple_constraint = self.NewIntermediateIntVar(multiple, f'{repr(target)} == ({repr(num)} // {repr(denom)}) * {repr(multiple)}: multiple') - - super().AddDivisionEquality(quotient, intermediate_num, intermediate_denom) - super().AddMultiplicationEquality(intermediate_target, (quotient, intermediate_multiple if multiple else intermediate_denom)) - - return (num_constraint, denom_constraint, target_constraint, *((multiple_constraint,) if multiple else ())) - def AddIf(self, variable, *constraints): """Add constraints to the model, only enforced if the specified variable is true. diff --git a/bonemarketsolver/solve.py b/bonemarketsolver/solve.py index a76ce26..2145190 100644 --- a/bonemarketsolver/solve.py +++ b/bonemarketsolver/solve.py @@ -538,7 +538,10 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non model.AddIf(actions[Buyer.A_NAIVE_COLLECTOR], skeleton_in_progress >= 100, - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue, value + zoological_mania_bonus, 250), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue, + (250, partialmethod(BoneMarketModel.AddDivisionEquality, num=value + zoological_mania_bonus, denom=250)), + ), secondary_revenue == 0, difficulty_level == 25*implausibility, added_exhaustion == 0, @@ -547,7 +550,10 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non model.AddIf(actions[Buyer.A_FAMILIAR_BOHEMIAN_SCULPTRESS], skeleton_in_progress >= 100, antiquity == 0, - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue - 1000, value + zoological_mania_bonus, 250), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue - 1000, + (250, partialmethod(BoneMarketModel.AddDivisionEquality, num=value + zoological_mania_bonus, denom=250)), + ), secondary_revenue == 250*counter_church, difficulty_level == 50*implausibility, added_exhaustion == 0, @@ -556,7 +562,10 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non model.AddIf(actions[Buyer.A_PEDAGOGICALLY_INCLINED_GRANDMOTHER], skeleton_in_progress >= 100, menace == 0, - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue - 1000, value + zoological_mania_bonus, 50), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue - 1000, + (50, partialmethod(BoneMarketModel.AddDivisionEquality, num=value + zoological_mania_bonus, denom=50)), + ), secondary_revenue == 0, difficulty_level == 50*implausibility, added_exhaustion == 0, @@ -565,7 +574,10 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non model.AddIf(actions[Buyer.A_THEOLOGIAN_OF_THE_OLD_SCHOOL], skeleton_in_progress >= 100, amalgamy == 0, - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue - 1000, value + zoological_mania_bonus, 250), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue - 1000, + (250, partialmethod(BoneMarketModel.AddDivisionEquality, num=value + zoological_mania_bonus, denom=250)), + ), secondary_revenue == 0, difficulty_level == 50*implausibility, added_exhaustion == 0, @@ -574,7 +586,10 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non model.AddIf(actions[Buyer.AN_ENTHUSIAST_OF_THE_ANCIENT_WORLD], skeleton_in_progress >= 100, antiquity > 0, - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue, value + zoological_mania_bonus, 50), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue, + (50, partialmethod(BoneMarketModel.AddDivisionEquality, num=value + zoological_mania_bonus, denom=50)), + ), secondary_revenue == 250*(antiquity + (1 if bone_market_fluctuations == Fluctuation.ANTIQUITY else 0)), difficulty_level == 45*implausibility, added_exhaustion == 0, @@ -583,7 +598,10 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non model.AddIf(actions[Buyer.MRS_PLENTY], skeleton_in_progress >= 100, menace > 0, - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue, value + zoological_mania_bonus, 50), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue, + (50, partialmethod(BoneMarketModel.AddDivisionEquality, num=value + zoological_mania_bonus, denom=50)), + ), secondary_revenue == 250*menace, difficulty_level == 45*implausibility, added_exhaustion == 0, @@ -592,7 +610,10 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non model.AddIf(actions[Buyer.A_TENTACLED_SERVANT], skeleton_in_progress >= 100, amalgamy > 0, - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue - 250, value + zoological_mania_bonus, 50), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue - 250, + (50, partialmethod(BoneMarketModel.AddDivisionEquality, num=value + zoological_mania_bonus, denom=50)), + ), secondary_revenue == 250*(amalgamy + (1 if bone_market_fluctuations == Fluctuation.AMALGAMY else 0)), difficulty_level == 45*implausibility, added_exhaustion == 0, @@ -813,7 +834,10 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non model.AddIf(actions[Buyer.A_CONSTABLE], cp_model.BoundedLinearExpression(skeleton_in_progress, (110, 119)), - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue - 1000, value, 50), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue - 1000, + (50, partialmethod(BoneMarketModel.AddDivisionEquality, num=value, denom=50)), + ), secondary_revenue == 0, difficulty_level == 50*implausibility, added_exhaustion == 0, @@ -846,7 +870,10 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non cp_model.BoundedLinearExpression(skeleton_in_progress, (110, 299)), amalgamy == 0, counter_church == 0, - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue - 300, value + zoological_mania_bonus, 3), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue - 300, + (3, partialmethod(BoneMarketModel.AddDivisionEquality, num=value + zoological_mania_bonus, denom=3)), + ), secondary_revenue == 250, difficulty_level == 100*implausibility, added_exhaustion == 0, @@ -857,7 +884,10 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non skeleton_in_progress >= 100, implausibility >= 2, attribute >= 4, - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue - 100, value + zoological_mania_bonus, 50), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue - 100, + (50, partialmethod(BoneMarketModel.AddDivisionEquality, num=value + zoological_mania_bonus, denom=50)), + ), partialmethod(BoneMarketModel.AddMultiplicationEquality, secondary_revenue - 250, (250, attribute, implausibility)), difficulty_level == 0, partialmethod(BoneMarketModel.AddDivisionEquality, added_exhaustion, secondary_revenue, 5000), @@ -926,7 +956,10 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non model.AddIf(actions[Buyer.THE_DUMBWAITER_OF_BALMORAL], cp_model.BoundedLinearExpression(skeleton_in_progress, (180, 189)), value >= 250, - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue, value, 250), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue, + (250, partialmethod(BoneMarketModel.AddDivisionEquality, num=value, denom=250)), + ), secondary_revenue == 0, difficulty_level == 200, added_exhaustion == 0, @@ -946,7 +979,10 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non model.AddIf(actions[getattr(DiplomatFascination, str(attribute).upper()).value], skeleton_in_progress >= 100, attribute >= 5, - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue - 50, value, 50), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue - 50, + (50, partialmethod(BoneMarketModel.AddDivisionEquality, num=value, denom=50)), + ), partialmethod(BoneMarketModel.AddMultiplicationEquality, secondary_revenue, (50, attribute, attribute)), difficulty_level == 0, partialmethod(BoneMarketModel.AddDivisionEquality, added_exhaustion, secondary_revenue, 5000), @@ -959,19 +995,20 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non { model.AddIf(actions[getattr(DiplomatFascination, fascination).value], *criteria, - partialmethod(BoneMarketModel.AddDivisionMultiplicationEquality, primary_revenue - 50, value, 50), + partialmethod(BoneMarketModel.AddMultiplicationEquality, + primary_revenue - 50, + (50, partialmethod(BoneMarketModel.AddDivisionEquality, num=value, denom=50)), + ), partialmethod(BoneMarketModel.AddMultiplicationEquality, secondary_revenue, - (50, - partialmethod(BoneMarketModel.AddApproximateExponentiationEquality, - var = partialmethod(BoneMarketModel.AddDivisionEquality, - num = cp_model.LinearExpr.Sum((amalgamy, antiquity, menace)), - denom = 3 - ), - exp = 2.2, - upto = MAXIMUM_ATTRIBUTE - ) - ) + ( + 50, + partialmethod(BoneMarketModel.AddApproximateExponentiationEquality, + var=partialmethod(BoneMarketModel.AddDivisionEquality, num = amalgamy+antiquity+menace, denom=3), + exp=2.2, + upto=MAXIMUM_ATTRIBUTE, + ), + ), ), difficulty_level == 0, partialmethod(BoneMarketModel.AddDivisionEquality, added_exhaustion, secondary_revenue, 5000),