Question. Are there Sets of minimum length? The same code could find them?
]]>Football()
]] helper class from the enigma.py library to solve this puzzle.
The following Python program runs in 64ms.
Run: [ @repl.it ]
from enigma import Football, irange, update, multiset, printf # scoring system football = Football(games='wdl', points=dict(w=3, d=1)) # labels for the teams (U, H, C, D) = (0, 1, 2, 3) # digits digits = set(irange(0, 9)) # accumulate results rs = multiset() # solve the table for (matches, d) in football.substituted_table(dict(w='A???', d='T??M', l='???A', points='?E?H')): # create the tables and check the points are in order tU = football.table([matches[(U, H)], matches[(U, C)], matches[(U, D)]], [0, 0, 0]) tH = football.table([matches[(U, H)], matches[(H, C)], matches[(H, D)]], [1, 0, 0]) tC = football.table([matches[(U, C)], matches[(H, C)], matches[(C, D)]], [1, 1, 0]) tD = football.table([matches[(U, D)], matches[(H, D)], matches[(C, D)]], [1, 1, 1]) if not(tU.points >= tH.points >= tC.points >= tD.points): continue # H and D must score at least one goal in each winning match # and concede at least one goal in each losing match if d['T'] < tH.w or d['H'] < tH.l or d['T'] < tD.w: continue # choose a value for C for v in digits: if v < tD.l or v in d.values(): continue d_ = update(d, [('C', v)]) # find possible scorelines for H and D for scores in football.substituted_table_goals('?T?T', '?H?C', matches, d=d_, teams=[H, D]): # output the matches football.output_matches(matches, scores, teams='UHCD', d=d_) rs.add(tuple(matches[k] for k in sorted(matches.keys()))) # output solutions for (ms, n) in rs.most_common(): (UH, UC, UD, HC, HD, CD) = ms printf("UvH={UH} UvC={UC} UvD={UD} HvC={HC} HvD={HD} CvD={CD} [{n} solutions]")
Solution: The outcomes of the matches are: U v H = match drawn; U v C = win for U; U v D = win for U; H v C = win for C; H v D = win for H; C v D = win for D.
We can determine some, but not all, of the scores in the matches:
U v H = (d) 0 – 0
U v C = (w) x – y
U v D = (w) z – 0
H v C = (l) 0 – 3
H v D = (w) 1 – 0
C v D = (l) 0 – 1
Where x > y and z = 4 .. 8.
]]>This makes the top row: 3, ?, ?, 0.
And the bottom row: ?, 4, 1, ?.
And the cards we have to fill out the blanks are: 2, 6, 1, 0.
If we use the 2 and the 1 in the top row we get: 3, 2, 1, 0. Which seems like a reasonable sequence for the top row.
This leaves us with 6 and 0 to fit into the bottom row. Pairing up the zeros we have:
3 → 6
2 → 4
1 → 1
0 → 0
Which doesn’t quite make nice mapping. The transformation x → 2x works, except at 1.
Also the transformation x → x² works, except at 3.
But if we invert the “6” card, we get a “9” card which makes the x → x² mapping work.
Solution: The completed grid is:
]]>from enigma import subsets, irange, printf # choose a set of 12 numbers for ns in subsets(irange(1, 30), size=12): # is there a set of 3 in arithmetic progression if any(b - a == c - b for (a, b, c) in subsets(ns, size=3)): continue # output the solution printf("{ns}") break
Solution: The 12 numbers are: 1, 3, 4, 8, 9, 11, 20, 22, 23, 27, 28, 30.
However, here is a recursive program that is a little longer, and a lot faster (it runs in 365ms).
Run: [ @repl.it ]
from enigma import irange, printf # find a k length set with no 3AP subset # k = length of sequence to find # ss = set so far (must be 3AP free) # M = max number allowed def seq(k, ss, M): # are we done? if len(ss) == k: yield ss else: # try to add another number in for n in irange(max(ss) + 1, M): # does n form a 3AP subset? if not any(2 * x - n in ss for x in ss): yield from seq(k, ss.union([n]), M) # find k length subsets with no 3AP sequence for numbers from 1 to M def solve(k, M): # consider possible initial term for n in irange(1, M): yield from seq(k, set([n]), M) # we want a 12 length subset of 1 to 30 for ss in solve(12, 30): printf("{ss}", ss=sorted(ss)) break
See also:
It runs in 56ms.
Run: [ @repl.it ]
from enigma import subsets, join, printf # labels for the candidates candidates = ("Matt", "Mark", "Luke", "John", "Pete") # choose the 2 candidates that get firsts for first in subsets(candidates, size=2): # none of them are completely accurate: # Matt: "Mark and I will both get seconds" if "Mark" not in first and "Matt" not in first: continue # Luke: "Mark and I will both get firsts" if "Mark" in first and "Luke" in first: continue # John: "Luke and I will both get seconds" if "Luke" not in first and "John" not in first: continue # Pete: "John will get a first and I will get a second" if "John" in first and "Pete" not in first: continue printf("first = {first}", first=join(first, sep=", "))
Solution: Matthew and Luke got firsts.
]]>@Rob: A very thorough investigation (which will probably turn out to be more detailed than the published solution).
(I also fixed up your link, so it should be right now).
]]>@arthur: Thanks for that. I thought there must be some data somewhere that would shed some light on the distribution.
]]>This Python program uses the [[ SubstitutedExpression()
]] solver from the enigma.py library to find the fractions that satisfy the conditions. Then it selects the appropriate values for a glypth and a glipth and calculates the tax on the given amount.
Run: [ @repl.it ]
from fractions import Fraction as F from enigma import SubstitutedExpression, irange, intc, printf # find candidates fractions using the SubstitutedExpression solver exprs = [ # AB / CD is a proper fraction "A < C", "gcd(AB, CD) = 1", # the digits (in some order) are consecutive "max(A, B, C, D) - min(A, B, C, D) = 3", # AB + CD is a perfect square "is_square(AB + CD)", ] p = SubstitutedExpression(exprs, digits=irange(1, 9), answer="(AB, CD)") # collect candidates fs = list() for (_, (AB, CD)) in p.solve(verbose=0): fs.append(F(AB, CD)) glypth = min(fs, key=lambda f: f.numerator) glipth = max(fs, key=lambda f: f.denominator) printf("[glypth = {glypth}, glipth = {glipth}]") # calculate tax on an amount def tax(x): t1 = intc(x * glypth) t2 = intc((x - t1) * glipth) return t1 + t2 x = 140524 t = tax(140524) printf("tax({x}) = {t}")
Solution: Aleph pays tax of 111,198 talents.
There are 7 fractions that satisfy the given conditions:
21/43, 23/41, 45/76, 46/75, 35/46, 54/67, 57/64
So a glypth = 21/43, and a glipth = 45/76.
Making the overall tax rate about 1293/1634, or roughly 79%.
]]>I missed the nice analytical result where age gaps must be multiples of nine, and instead calculated the age gaps by ‘brute’ force. After reading the discussion above I expect that the published answer will indeed be (2/9)*90 = 20.
However I did attempt to account for a more likely age distribution, and also the probability that the fathers survived to an age where the reverse birthdays actually occurred. Considering this my result is suprisingly close, at 19.0158.
My solution in Mathematica: [ https://www.wolframcloud.com/obj/ferguson_rob/Published/2020Puzzle65.nb ].
]]>@Hugh: Yes, you are quite right. I fell into the same trap on Puzzle #61.
Assuming the child is not born on the parent’s birthday, there is a period when the parent’s age is (n + k + 1) and the child is still only k. So the situation will occur when the parent’s age is a multiple of 9 before the child’s first birthday. So effectively if their age is a multiple of 9 or one less than a multiple of 9. Which does indeed give a 2/9 chance of it occurring.
Here’s a program to confirm:
Run: [ @repl.it ]
from enigma import irange, nreverse, printf # consider fathers age at birth of child for n in irange(16, 60): # now look for years where: nreverse(n + k) = k ks = list() for k in irange(10, 60): if nreverse(n + k) == k or nreverse(n + k + 1) == k: ks.append(k) if ks: printf("n={n} ks={ks}")]]>
And in 11 years time both digits of her age will have advanced by 1 (to 25) and both digits of her dads age will have advanced by one (to 52), so it will happen again, and 11 years after that and so on.
For two digit ages:
child = AB = 10A + B
parent = BA = 10B + A
the difference in ages is:
BA – AB = (10B + A) – (10A + B) = 9(B – A)
So it will happen when the child is born in a year where the parent’s age is divisible by 9 (i.e aged 18, 27, 36, 45, 54, …)
18 → 13, 24, 35, …
27 → 14, 25, 36, …
36 → 15, 26, 37, …
45 → 16, 27, 38, …
54 → 17, 28, 39
If we suppose births are uniformly distributed (which seems unlikely), then we would expect this to happen 1/9 of the time.
So she might expect 10 out of her 90 Facebook friends to be in the same situation.
[And another 10, to make 20 in total – see below].
]]>Also the teams are listed in points order, and we know that there must be at least as many goals scored as there are games won, and at least as many goals conceded as games lost.
We can express all these constraints as alphametic expressions and feed them to the [[ SubstituedExpression()
]] solver from the enigma.py library.
The following run file executes in 107ms.
Run: [ @repl.it ]
#!/usr/bin/env python -m enigma -r SubstitutedExpression # each team has played the same number of matches "S + E + E == H + O + W" "S + E + E == M + A + N" "S + E + E == T + E + A" # and the teams are in order of points "3 * S + E > 3 * H + O" "3 * H + O > 3 * M + A" "3 * M + A > 3 * T + E" # each win corresponds to at least one goal scored "Y > M" "M > T" # each loss corresponds to at least one goal conceded "S > A" # each team plays each other team --answer="S + E + E + 1" # suppress verbose output --template=""
Solution: There are 14 teams in the league.
]]>After game 23, the champion has played white 12 times and black 11 times, and the challenger has played black 12 times and white 11 times. (In the final match the champion plays black).
This Python 3 program considers possible values for the 12 champion/white vs challenger/black and 11 champion/black vs challenger/white games that comprise the first 23 games that lead to the described scenario.
It runs in 62ms.
Run: [ @repl.it ]
from enigma import irange, printf # decompose t into k numbers def decompose(t, k, s=[]): if k == 1: yield s + [t] else: for x in irange(0, t): yield from decompose(t - x, k - 1, s + [x]) # consider the first 23 games: # case 1: final game is drawn def check1(w1, d1, b1, w2, d2, b2): # total black wins = 9 if not(b1 + b2 == 9): return False # total draws = challenger wins with white if not(d1 + d2 + 1 == w2): return False # this is a viable scenario return True # case 2: final game is won by champion (black) def check2(w1, d1, b1, w2, d2, b2): # total black wins = 9 if not(b1 + b2 == 8): return False # total draws = challenger wins with white if not(d1 + d2 == w2): return False # this is a viable scenario return True # partition the 11 champion = black vs challenger = white matches # into (white wins, draw, black wins) for (w2, d2, b2) in decompose(11, 3): # 9 wins with black if b2 > 9: continue # draws = challenger wins with white if d2 > w2: continue # partition the 12 champion = white vs challenger = black matches # into (white wins, draw, black wins) for (w1, d1, b1) in decompose(12, 3): # calculate the number of half-points for the champion and the challenger R = 2 * (w1 + b2) + (d1 + d2) C = 2 * (b1 + w2) + (d1 + d2) # case 1: final game is drawn if (R, C) == (23, 23) and check1(w1, d1, b1, w2, d2, b2): printf("game 24 = draw [w1={w1} d1={d1} b1={b1}; w2={w2} d2={d2} b2={b2}]") # case 2: final game is win for champion (black) if (R, C) == (22, 24) and check2(w1, d1, b1, w2, d2, b2): printf("game 24 = champion wins [w1={w1} d1={d1} b1={b1}; w2={w2} d2={d2} b2={b2}]")
Solution: The challenger loses in the final game.
In the first 23 games, in the 12 champion/white vs challenger/black games there were: 3 wins for champion/white; 3 wins for challenger/black; 6 draws. In the 11 champion/black vs challenger/white games there were: 5 wins for champion/black; 6 wins for challenger/white; 0 draws.
So at the end of the 23 games the results were: champion = 11 points, challenger = 12 points.
The champion/black wins the final game to give a result of: champion = 12 points, challenger = 12 points. So the incumbent retains his title.
The total number of wins with black is: 3 challenger/black + 6 champion/black = 9 wins.
The total number of draws is: 6 + 0 = 6 draws.
And the number of challenger/white wins is: 6 wins.
]]>The trick works as follows:
1. Choose a number n.
2. Look in box n and write B[n] on the blackboard.
3. Look in box B[n] and subtract B[B[n]] from 6n.
4. This gives the same as the number on the blackboard
And the trick works for any box.
So: 6n – B[B[n]] = B[n], or:
B[n] + B[B[n]] = 6n
B[B[n]] = 6n – B[n]
So, given a value for B[n], we can work out values for B[B[n]], B[B[B[n]]], B[B[B[B[n]]]], ….
Let’s consider the case when n = 1, we have:
B[1] + B[B[1]] = 6
Each box has at least one coin in it, so the 2 boxes (B[1], B[B[1]]) have one of the following combinations: (1, 5), (2, 4), (3, 3), (4, 2), (5, 1).
Case (1): B[1] = 1, B[1] = 5, an immediate contradiction.
Case (2): B[1] = 2, B[2] = 4:
B[B[2]] = 6×2 – B[2]
B[4] = 12 – 4 = 8B[B[4]] = 6×4 – B[4]
B[8] = 24 – 8 = 16…
In general, for n = 2^k we have:
B[n] = 2n
Case (3): B[1] = 3, B[3] = 3:
B[B[3]] = 6×3 – B[3]
B[3] = 18 – 3 = 15
A contradiction.
Case (4): B[1] = 4, B[4] = 2:
B[B[4]] = 6×4 – B[4]
B[2] = 24 – 2 = 12B[B[2]] = 6×2 – B[2]
B[12] = 12 – 12 = 0
But this violates the condition that each box contains a positive number of coins.
Case (5): B[1] = 5, B[5] = 1:
B[B[5]] = 6×5 – B[5]
B[1] = 30 – 1 = 29
A contradiction.
So the only viable combination is Case (2), and we have:
B[n] = 2n
for n = 2^k.
If we suppose this formula also holds for other values of n then if we choose any value for n we see:
B[n] + B[B[n]] = 2n + B[2n] = 2n + 4n = 6n
as required.
Solution: Box 1990 contains 3980 coins.
If we allow zero and negative amounts of coins the trick can be extended to all integers, and even to all rational numbers (if we also allow fractional coins).
It could also potentially be extended to all real numbers, but we would not be able to arrange the boxes into a line.
]]>D = πR² − πr² = π(R² − r²)
So we don’t need to know the individual radii to calculate the area, just the value of (R² − r²).
By drawing in appropriate radii of the two circles we can construct a right-angled triangle, with hypotenuse R, another side with radius r, and the remaining side is half the distance measured by Fernando.
So, by Pythagoras Theorem:
r² + (x/2)² = R²
R² − r² = (x/2)²
And we are told that x = 10, hence:
(x/2)² = 5² = 25
So the area of carpet required is 25π (approximately 78.54) sq m.
Solution: The area of carpet required is 25π sq. m.
]]>This Python program runs in 58ms.
Run: [ @repl.it ]
from enigma import seq_all_same as all_same, printf # potential divisors ps = [ 2, 3, 5, 7, 11, 13, 17 ] # potential Xs Xs = [ 2730, 4290, 5610, 6006, 6630, 10010, 13090, 14586, 15015, 15470, 24310, 34034, 36465, 39270, 46410, 255255, 510510 ] # check no smaller set of ds give a unique answer to the embedded puzzle def check(p, ds): # miss out one of the divisors for (i, _) in enumerate(ds): ss = ds[:i] + ds[i + 1:] X = list(x for x in Xs if all(x % d == 0 for d in ss)) if all_same(x % p == 0 for x in X): # we don't need to check the missing divisor printf("[check: {p} -> {ss} -> {X}]") return False # we need to check all divisors return True # choose the value in the final box for (i, p) in enumerate(ps): # so the remaining divisors are... ds = ps[:i] + ps[i + 1:] # find numbers that are divisible by all divisors in ds X = list(x for x in Xs if all(x % d == 0 for d in ds)) # all candidates should give the same answer to the puzzle if not all_same(x % p == 0 for x in X): continue # but no smaller set of divisors should give a unique answer if not check(p, ds): continue # output solution, and the answer to the embedded puzzle printf("p={p} -> X={X}; {p} | {X} = {t}", t=(X[0] % p == 0))
Solution: The final box should contain 7.
The answer to the embedded puzzle-within-a-puzzle is “Yes”.
X is 510510, which is divisible by 2, 3, 5, 7, 11, 13, 17. (In fact this is a complete factorisation).
Four of the factors can be removed and still give a viable puzzle:
(2, 5, 7, 11, 13, 17) → 510510; divisible by 3
(2, 3, 7, 11, 13, 17) → 510510; divisible by 5
(2, 3, 5, 11, 13, 17) → 510510; divisible by 7
(2, 3, 5, 7, 11, 13) → 510510; divisible by 17
But now, if we think about solving the embedded puzzle in each of these cases:
In the case where 3 is in the final box, if we check the divisors: 5, 7, 11, 13, 17, we narrow the candidates down to 2 possibilities: 255255 and 510510. Both of which are divisible by 3. So we don’t need to check the divisibility by 2 in order to say the answer to the embedded puzzle is “Yes”. (Because the embedded puzzle doesn’t ask us for the value of X).
In order to solve the Enigma we have to come up with an embedded puzzle where all the divisibility conditions have to be checked. So putting 3 in the final box doesn’t doesn’t give us the required puzzle.
In the case where 5 is in the final box, if we check the divisors: 2, 3, 7, 11, 17, we narrow the candidates down to 2 possibilities: 39270 and 510510, both of which are divisible by 5. So putting 5 in the final box doesn’t give us the required puzzle.
In the case where 17 is in the final box, if we check the divisors: 2, 3, 5, 7, 11, we narrow the candidates down to 2 possibilities: 39270 and 510510, both of which are divisible by 17. So putting 17 in the final box doesn’t give us the required puzzle.
However, if the case where 7 is in the final box we have to check all the divisors to narrow the candidate numbers down to a set of possibilities which have the same residue modulo 7. This leaves only one candidate number: 510510, and it is divisible by 7.
So the solution to the Enigma puzzle is to put 7 in the final box. The solution to the embedded puzzle is “Yes”, and the only possible value for X is 510510 (although neither the Enigma nor the embedded puzzle ask for that).
]]>So, if the jelly costs x, a teddy costs 2x, and a cake costs 4x.
The four amounts mentioned are therefore:
A: 2× jelly + 1× teddy + 1× cake = 8x
B: 1× jelly + 1× teddy = 3x
C: 1× jelly + 1× cake = 5x
D: 1× jelly = x
A and C bought the cakes.
The pairwise differences between these amounts being: 2x, 3x, 4x, 5x, 7x.
And one of these differences corresponds to 95p.
If we assume that the prices are whole numbers of pence, then 95p corresponds to the 5x difference, i.e. the difference (8x – 3x), and x = 19.
So A is Marmaduke (152p), B is Clarence (57p), C is Jasper (95p), D is Algernon (19p).
Hence:
Solution: Marmaduke and Jasper bought cakes.
The jelly costs 19p. A teddy costs 38p. A cake costs 76p.
However the ½p coin was in circulation in 1975, so the 95p could also correspond to a 2x difference, and x = 47.5.
So the jelly would cost 47½p. A teddy costs 95p. A cake costs 190p.
We find there are two further solutions:
A is Jasper (380p), B is Clarence (142½p), C is Marmaduke (237½p), D is Algernon (47½p).
A is Jasper (380p), B is Marmaduke (142½p), C is Algernon (237½p), D is Clarence (47½p).
And in these solutions: Jasper and Marmaduke; Algernon and Jasper are the ones who bought the cakes.
Here is a Python program that investigates the possibilities. It runs in 58ms.
Run: [ @repl.it ]
from fractions import Fraction as F from enigma import subsets, join, printf # assign multiples to the names for (A, C, J, M) in subsets([1, 3, 5, 8], size=len, select="P"): # A spent less than J if not(A < J): continue # M spent 95p more than C x = F(95, M - C) if x < 0 or x.denominator > 2: continue cakes = list(n for (n, x) in zip("ACJM", [A, C, J, M]) if x in (5, 8)) printf("A={A} C={C} J={J} M={M}; x={x:g}; cakes={cakes}", x=float(x), cakes=join(cakes, sep=","))]]>