Brainteaser 1318: May I repeat?
From The Sunday Times, 6th December 1987 [link]
In this letters-for-digits puzzle, as usual, different letters consistently replace different digits. I have thought of a two-digit number and worked out a fraction (in its lowest form) involving my number. The recurring decimal which I get consists of infinite repeats, i.e.:
? / MY = 0. REPEAT REPEAT …
What is the value of PART?
[teaser1318]
Jim Randell 11:06 am on 30 May 2024 Permalink |
This solution uses the [[
farey()]] function from the enigma.py library, which generates co-prime pairs (i.e. the numerator and denominator of a fraction in its lowest terms), and then uses the [[recurring()]] function to determine the representation of the fraction as a recurring decimal.It runs in 131ms. (Internal runtime is 55ms).
Run: [ @replit ]
from enigma import (farey as coprime_pairs, recurring, format_recurring as fmt, printf) # consider fractions a/b for (a, b) in coprime_pairs(98): # b is 2 different digits if b < 10 or b % 11 == 0: continue # check repetend (i, nr, rr) = recurring(a, b) if nr or len(rr) != 6 or rr[1] != rr[3]: continue rs = set(rr) if len(rs) != 5 or rs.intersection(str(b)): continue # output solution PART = rr[2] + rr[4] + rr[0] + rr[5] printf("PART = {PART} [{a}/{b} = {f}]", f=fmt((i, nr, rr)))Solution: PART = 8015.
The required fraction is:
LikeLike
Jim Randell 8:56 pm on 30 May 2024 Permalink |
Here’s my solution based on the observation:
(Although I don’t assume k is a single digit number).
It runs in 66ms. (Internal runtime is 502µs).
Run: [ @replit ]
from enigma import (irange, divisor_pairs, gcd, nsplit, join, printf) # (MY / k) * REPEAT = 999999 # MY is a 2-digit divisor of 999999 for (MY, r) in divisor_pairs(999999): if MY < 10 or MY % 11 == 0: continue if MY > 99: break # REPEAT is some multiple of r for k in irange(1, MY - 1): if gcd(k, MY) > 1: continue REPEAT = k * r ds = nsplit(REPEAT, 6) if ds[1] != ds[3]: continue ss = set(ds) if len(ss) != 5 or ss.intersection(nsplit(MY)): continue # output solution PART = join(ds[i] for i in (2, 4, 0, 5)) printf("PART = {PART} [{k}/{MY} = 0.({REPEAT:06d})...]")LikeLike
Frits 11:27 am on 31 May 2024 Permalink |
Nice. Indeed, MY must be a divisor of 999999.
LikeLike
GeoffR 2:09 pm on 30 May 2024 Permalink |
% A Solution in MiniZinc include "globals.mzn"; var 1..9:R; var 0..9:E; var 0..9:P; var 0..9:A; var 0..9:T; var 1..9:X; var 1..9:M; var 0..9:Y; constraint all_different([R,E,P,A,T,M,Y]); var 10..99:MY == 10*M + Y; var 100000..999999:REPEAT == 100000*R + 10100*E + 1000*P + 10*A + T; var 1000..9999:PART == 1000*P + 100*A + 10*R + T; % function ex Hakan Kjellerstrand function var int: gcd(var int: x, var int: y) = let { int: p = min(ub(x),ub(y)); var 1..p: g; constraint exists(i in 1..p) ( x mod i = 0 /\ y mod i = 0 /\ forall(j in i+1..p) ( not(x mod j = 0 /\ y mod j = 0) ) /\ g = i); } in g; constraint gcd(X, MY) == 1; % As X/MY = 0.REPEATREPEAT.. % Multiplying both sides by 1,000,000 gives.. constraint 999999 * X == MY * REPEAT; solve satisfy; output ["PART = " ++ show(PART) ++ "\n" ++ "REPEAT = " ++ show(REPEAT) ++ "\n" ++ "X, MY =" ++ show([X, MY])]; % PART = 8015 % REPEAT = 128205 % X, MY =[5, 39] % ---------- % ==========LikeLike
Sunday Times Brainteaser 1318 | PuzzlingInPython 4:01 pm on 30 May 2024 Permalink |
[…] Published 6th December 1987 (link) […]
LikeLike
Frits 6:41 pm on 30 May 2024 Permalink |
Following GeoffR’s method.
from enigma import divisor_pairs # 999999 * X == MY * REPEAT for X in range(1, 10): LHS = 999999 * X # fraction X / MY is in its lowest form for MY, REPEAT in [(str(x), str(y)) for x, y in divisor_pairs(LHS) if 9 < x < 100 and (x % X or X == 1)]: # letter E if REPEAT[1] != REPEAT[3]: continue # different letters if len(set(MY + REPEAT)) != 7: continue print(f"answer: {REPEAT[2]}{REPEAT[4]}{REPEAT[0]}{REPEAT[5]}")LikeLike
Frits 11:15 am on 31 May 2024 Permalink |
I did assume a 1-digit question mark. Line 9 should have been:
if 9 < x < 100 and gcd(x, X) == 1]:
LikeLike
Ruud 6:33 am on 31 May 2024 Permalink |
Brute force with istr:
from istr import istr for r, e, p, a, t, m, y in istr.permutations(istr.digits(), 7): if (m | y) * (r | e | p | e | a | t) % 999999 == 0: print(f"{m|y} / {r|e|p|e|a|t}")LikeLike
Ruud 6:50 am on 31 May 2024 Permalink |
Improved prints:
from istr import istr for r, e, p, a, t, m, y in istr.permutations(istr.digits(), 7): if (m | y) * (r | e | p | e | a | t) % 999999 == 0: print(f"{(m | y) * (r | e | p | e | a | t) // 999999} / {m | y} = 0.{r | e | p | e | a | t}...") print(f"part = {p | a | r | t}")LikeLike
Jim Randell 8:40 am on 31 May 2024 Permalink |
@Ruud: How does this program ensure the fraction (?/MY) is in lowest terms?
LikeLiked by 1 person
Ruud van der Ham 10:26 am on 31 May 2024 Permalink |
Ok, no guarantee.
Better would be to do
for m, y, r, e, p, a, tin istr.permutations(istr.digits(), 7): if (m | y) * (r | e | p | e | a | t) % 999999 == 0: print(f"{(m | y) * (r | e | p | e | a | t) // 999999} / {m | y} = 0.{r | e | p | e | a | t}...") print(f"part = {p | a | r | t}") breakAlthough my original code also just result in one solution.
Alth
LikeLike