# Enigmatic Code

Programming Enigma Puzzles

## Enigma 1156: The tax process

From New Scientist #2312, 13th October 2001 [link]

The people on the island of Fairshare have their own tax process. If A is the average income for the people on the island then only people earning more than A pay tax. If a person earns P, which is more than A, then that person pays tax (P−A)²/P.

When all the tax has been collected, then it is shared between the people earning less than A, in proportion to the amounts their incomes fall short of A.

There are 10 people on the island, C, D, E, F, G, H, I, J, K and L. Their final incomes after the tax process were:

C = F£117,
D = F£112,
E = F£103-58,
F = F£90,
G = F£60-47,
H = F£53-52,
I = F£51-15,
J = F£46-57,
K = F£44-20,
L = F£41-99 (that is to say 41 Fairshare pounds and 99 pence, where there are 116 pence to the Fairshare pound).

What were the original incomes of E, H and K?

[enigma1156]

### 2 responses to “Enigma 1156: The tax process”

1. Jim Randell 1 August 2016 at 8:26 am

This Python program runs in 200ms.

```from fractions import Fraction as F
from enigma import subsets, irange, join, printf

# "after" amounts
after = (
117,
112,
103 + F(58, 116),
90,
60 + F(47, 116),
53 + F(52, 116),
51 + F(15, 116),
46 + F(57, 116),
44 + F(20, 116),
41 + F(99, 116),
)

# number of residents
n = len(after)

# since the money is redistributed the average "before" earnings
# are the same as the average "after" amounts
A = F(sum(after), n)

# calculate "before" values
# ts = tax payers
def calculate(ts):

# go though the payers and calculate the "before" amounts and total
# tax collected
tax = 0
before = [None] * n
for i in ts:
before[i] = F(A * A, 2 * A - after[i])
# "before" amounts for tax payers must be >= A
if before[i] < A: return None
tax += before[i] - after[i]

# go through the recipients and calculate the sum of their "after"
# amounts, less the total amount of tax raised, which gives us the
# sum of their "before" amounts
t = sum(after[i] for (i, b) in enumerate(before) if b is None) - tax

# the total number of "shares" in tax to be distributed is...
T = (n - len(ts)) * A - t

# if T = tax then everyone would have an "after" income of A
# and we cannot determine the "before" incomes
if T == tax: return None

# calculate the "before" amounts for the beneficiaries
for (i, b) in enumerate(before):
if b is not None: continue
before[i] = F(T * after[i] - A * tax, T - tax)
# "before" amounts for beneficiaries must be below average
if before[i] < 0 or before[i] > A: return None

return before

def amount(x):
(a, b) = divmod(x, 1)
return str(a) + '-' + str(int(116 * b))

# choose the tax payers
for ts in subsets(irange(0, n - 1)):
before = calculate(ts)
if before is None: continue

printf("ts={ts}, before=[{before}]", before=join((amount(x) for x in before), sep=", "))
```

Solution: The original income for E was F£128. The original income for H was F£32. The original income for K was F£12.

The full list of incomes before tax is as follows:

C = F£192 (pays F£75-00 tax, net income F£117-00)
D = F£162 (pays F£50-00 tax, net income F£112-00)
E = F£128 (pays F£24-58 tax, net income F£103-58)
F = F£96 (pays F£6-00 tax, net income F£90-00)
(average income = F£72)
G = F£47 (receives F£13-41, net income F£60-41)
H = F£32 (receives F£21-52, net income F£53-52)
I = F£27 (receives F£24-15, net income F£51-15)
J = F£17 (receives F£29-57, net income F£46-57)
K = F£12 (receives F£32-20, net income F£44-20)
L = F£7 (receives F£34-99, net income F£41-99)

We can improve the efficiency of the program with some additional analysis. For example, the formula for the amount of tax paid means that for people earning more than A before tax the net earnings after tax are still more than A, so the only potential tax payers are C, D, E, and F.

2. Brian Gladman 1 August 2016 at 11:11 pm
```from fractions import Fraction

# convert pounds and pence into fractions of a pound
def RF(x, y):
return x + Fraction(y, 116)

# the incomes after tax
incomes = [ RF(117, 0), RF(112, 0), RF(103, 58), RF(90,  0), RF(60, 47),
RF(53, 52), RF(51, 15), RF( 46, 57), RF(44, 20), RF(41, 99) ]

# calculate the average income (which is the same before and after tax)
A = sum(incomes) / 10

# for tax payers income = earned - (earned - A)^2 / earned, giving
# earned = A / (2 - income / A) -- note that when 'income' is more
# (less) than A, 'earned' is also more (less) than A
earned, taxes = [], 0
for i, income in enumerate(incomes):
e = A / (2 - income / A)
# tax is only paid on above average incomes
if e <= A:
break
earned.append(e)
taxes += (e - income)

# for N people receiving tax, the sum of their earned incomes is the
# sum of their incomes less the total tax collected; the total of the
# amounts by which their earned incomes are below the average income
# is hence N.A - (sum(income) - taxes).
deficit = (10 - i) * A - (sum(incomes[i:]) - taxes)

# for non tax payers, income = earned + (A - earned).taxes / deficit
# which gives earned = (income.deficit - A.taxes)  / (deficit - taxes)
for income in incomes[i:]:
e = (income * deficit - A * taxes)  / (deficit - taxes)
earned += [e]

# output the earned incomes for the ten people
f, s, l = ', '.join('{}'.format(e) for e in earned).rpartition(', ')
print('The pre-tax incomes of C..L (in F\xa3) are {} and {}.'.format(f, l))
```