Number of unique optimal assignments (up to reordering) (according to AI-written optimizer implementing my manually found tax calculation): 1 Minimum total tax: 212 (err thats 21gp 2 sp)
Solution 1: Member 1: C=1, D=1, L=0, U=0, Z=4, Tax=0 Member 2: C=1, D=1, L=0, U=1, Z=1, Tax=0 Member 3: C=1, D=1, L=0, U=1, Z=1, Tax=0 Member 4: C=1, D=1, L=5, U=5, Z=2, Tax=212
Tax calculation:
1. Add up the base values: 6 for C, 14 for D, 10 for L, 7 for U, 2 for Z 2. If only L and Z, just take the total base and exit. 3. Otherwise, set a tier as follows: tier 0 if 0 < base < 30, tier 1 if 30 ⇐ base < 60, tier 2 if 60 ⇐ base < 100, tier 3 if base >= 100. 4. If U >= 5, then use the max tier regardless (but a 2x discount is also triggered later). 5. If D >=2, then increase the base as if the extra dragons beyond 1 are doubled. This doesn’t change the tier. 6. multiply the base value by tier + 2 7. If U >= 5, divide by 2 8. Discount by 60*Ceiling(C/2) (can’t go below 0)
Rounding is needed if U is an odd number >=5. To determine if you round up or down, add up the numbers for C,L and Z, add to (U-1)/2, plus 1 if there is at least one D. Then round down if that number is odd and up if it is even. (Presumably this arises in some more natural way in the actual calculation used, but this calculation gives 0 residuals, so...). Todo: find a more natural way for this to happen.
Post-hoc rationalization of optimal solution found: giving everyone a C helps get everyone an up to 60 tax credit. Spreading the D’s out also prevents D doubling. The C and D add up to a base value of 20. We can fit up to 9 more base value without going to the next tax bracket; this is done using 4Z (8 base value) or 1U 1Z (9 base value). The last member has to pay tax at the highest bracket but U=5 also gives the factor of 2 discount so it’s not so bad. They get everything they have to take in order to not push the others above 29 base, but no more.
This seemed relatively straightforward conceptually to solve (more a matter of tweaking implementation details like D doubling and so on - I expect many things are conceptualized differently in the actual calculation though). I went from the easiest parts (L and Z), then added U, then looked at D since it initially looked less intimidating than C, then switched to C, solved that, and finally D). It would have been much harder if it were not deterministic, or if there wasn’t data within simpler subsets (like L and Z only) for a starting point.
The ultimate solution found is 12 sp better than the best solutions available using only rows that actually occur in the data (also found using AI-written script).
Tools used: AI for writing scripts to manipulate CSV files and finding optimal solutions, etc. LibreOfficeCalc for actually looking at the data and figuring out the tax calculation.
Additional todo: look at the distributions of part numbers to try to find out how the dataset was generated.
edited to add: my optimizer used brute(ish) force, unlike DrJones’. It uses double meet-in-the-middle (split two ways, then split again) with memoization and symmetry reduction using lexicographical ordering (symmetry reduction and memoization was optimization added by AI after I complained to it about the time an initial version, also written by AI, was taking).
P. S. I used GPT-4.1 in Windsurf for the AI aspects. They’re running a promotion where it costs 0 credits until, IIRC, April 21.
Thanks aphyer. Solution:
Number of unique optimal assignments (up to reordering) (according to AI-written optimizer implementing my manually found tax calculation): 1
Minimum total tax: 212 (err thats 21gp 2 sp)
Solution 1:
Member 1: C=1, D=1, L=0, U=0, Z=4, Tax=0
Member 2: C=1, D=1, L=0, U=1, Z=1, Tax=0
Member 3: C=1, D=1, L=0, U=1, Z=1, Tax=0
Member 4: C=1, D=1, L=5, U=5, Z=2, Tax=212
Tax calculation:
1. Add up the base values: 6 for C, 14 for D, 10 for L, 7 for U, 2 for Z
2. If only L and Z, just take the total base and exit.
3. Otherwise, set a tier as follows: tier 0 if 0 < base < 30, tier 1 if 30 ⇐ base < 60, tier 2 if 60 ⇐ base < 100, tier 3 if base >= 100.
4. If U >= 5, then use the max tier regardless (but a 2x discount is also triggered later).
5. If D >=2, then increase the base as if the extra dragons beyond 1 are doubled. This doesn’t change the tier.
6. multiply the base value by tier + 2
7. If U >= 5, divide by 2
8. Discount by 60*Ceiling(C/2) (can’t go below 0)
Rounding is needed if U is an odd number >=5. To determine if you round up or down, add up the numbers for C,L and Z, add to (U-1)/2, plus 1 if there is at least one D. Then round down if that number is odd and up if it is even. (Presumably this arises in some more natural way in the actual calculation used, but this calculation gives 0 residuals, so...). Todo: find a more natural way for this to happen.
Post-hoc rationalization of optimal solution found: giving everyone a C helps get everyone an up to 60 tax credit. Spreading the D’s out also prevents D doubling. The C and D add up to a base value of 20. We can fit up to 9 more base value without going to the next tax bracket; this is done using 4Z (8 base value) or 1U 1Z (9 base value). The last member has to pay tax at the highest bracket but U=5 also gives the factor of 2 discount so it’s not so bad. They get everything they have to take in order to not push the others above 29 base, but no more.
This seemed relatively straightforward conceptually to solve (more a matter of tweaking implementation details like D doubling and so on - I expect many things are conceptualized differently in the actual calculation though). I went from the easiest parts (L and Z), then added U, then looked at D since it initially looked less intimidating than C, then switched to C, solved that, and finally D). It would have been much harder if it were not deterministic, or if there wasn’t data within simpler subsets (like L and Z only) for a starting point.
The ultimate solution found is 12 sp better than the best solutions available using only rows that actually occur in the data (also found using AI-written script).
Tools used: AI for writing scripts to manipulate CSV files and finding optimal solutions, etc. LibreOfficeCalc for actually looking at the data and figuring out the tax calculation.
Additional todo: look at the distributions of part numbers to try to find out how the dataset was generated.
edited to add: my optimizer used brute(ish) force, unlike DrJones’. It uses double meet-in-the-middle (split two ways, then split again) with memoization and symmetry reduction using lexicographical ordering (symmetry reduction and memoization was optimization added by AI after I complained to it about the time an initial version, also written by AI, was taking).
P. S. I used GPT-4.1 in Windsurf for the AI aspects. They’re running a promotion where it costs 0 credits until, IIRC, April 21.