Updates from Jim Randell Toggle Comment Threads | Keyboard Shortcuts

  • Unknown's avatar

    Jim Randell 4:37 pm on 8 December 2023 Permalink | Reply
    Tags:   

    Teaser 3194: A proper lesson 

    From The Sunday Times, 10th December 2023 [link] [link]

    A maths teacher wrote a sequential list of numbers 1, 2, 3, 4, … on the blackboard and asked her pupils to find a pair of positive fractions adding up to 1. The pair was to have the two numerators and two denominators consisting of four different numbers from her list. They found all possible pairs.

    She then told them to group two of the pairs that used eight different numbers from her list, which was just long enough to enable them to do this. The class found all possible groups. One of the groups contained some fractions that were not used by any other group.

    Which of the teacher’s numbers were not used by that group?

    [teaser3194]

     
    • Jim Randell's avatar

      Jim Randell 4:56 pm on 8 December 2023 Permalink | Reply

      This Python program considers increasing maximum values written on the blackboard, and collects new pairs of fractions as they become available, until it is possible to form groups consisting of 2 pairs that use 8 different numbers in the fractions.

      It then examines the groups found to determine which of them contain fractions that only occur in that group, and these groups provide the answer.

      It runs in 53ms. (Internal runtime is 519µs).

      Run: [ @replit ]

      from enigma import (
        irange, inf, fraction, multiset, subsets, flatten, diff, chunk, join, sprintf as f, printf
      )
      
      # format a list of numbers as fraction sums
      fmt = lambda ns: join((f("{a}/{b} + {c}/{d} = 1") for (a, b, c, d) in chunk(ns, 4)), sep="; ")
      
      # collect possible pairs of fractions a/b + c/d = 1
      ps = list()
      # consider increasing 1..n values
      for n in irange(4, inf):
        np = len(ps)
        # add in a/b, c/n pairs
        for c in irange(1, n - 1):
          (a, b) = (p, q) = fraction(1, 1, -c, n)
          while b < n:
            ns = (a, b, c, n)
            if len(set(ns)) == 4:
              ps.append(ns)
            a += p
            b += q
        if n < 8 or len(ps) == np: continue
      
        # find possible groups, and count occurrences of fractions
        (gs, m) = (list(), multiset())
        for ns in subsets(ps, size=2, fn=flatten):
          if len(set(ns)) == 8:
            printf("[n={n}: {ns}]", ns=fmt(ns))
            gs.append(ns)
            m.update_from_seq(chunk(ns, 2))
        if not gs: continue
      
        # find groups that contain fractions that only occur in one group
        for ns in gs:
          if any(m.count(x) == 1 for x in chunk(ns, 2)):
            # output solution
            ans = diff(irange(1, n), ns)
            printf("unused = {ans} [{ns}]", ans=join(ans, sep=", ", enc="()"), ns=fmt(ns))
      
        # we only need the smallest n that forms groups
        break
      

      Solution: The unused numbers are 7 and 8.


      The teacher wrote the numbers 1 .. 10 on the board.

      This gives 17 possible pairs of fractions that sum to 1:

      1/2 + 3/6 = 1
      2/4 + 3/6 = 1
      1/3 + 4/6 = 1
      3/4 + 2/8 = 1
      1/2 + 4/8 = 1
      3/6 + 4/8 = 1
      1/4 + 6/8 = 1
      4/6 + 3/9 = 1
      1/3 + 6/9 = 1
      4/5 + 2/10 = 1
      3/5 + 4/10 = 1
      1/2 + 5/10 = 1
      2/4 + 5/10 = 1
      3/6 + 5/10 = 1
      4/8 + 5/10 = 1
      2/5 + 6/10 = 1
      1/5 + 8/10 = 1

      Note that fractions do not have to be in their lowest terms, so 1/2 and 3/6 are considered to be different fractions (with the same value).

      These can be formed into 9 groups that use 8 distinct numbers in the fractions:

      1/2 + 3/6 = 1; 4/8 + 5/10 = 1
      2/4 + 3/6 = 1; 1/5 + 8/10 = 1
      1/2 + 4/8 = 1; 3/6 + 5/10 = 1
      3/6 + 4/8 = 1; 1/2 + 5/10 = 1
      4/6 + 3/9 = 1; 1/2 + 5/10 = 1
      4/6 + 3/9 = 1; 1/5 + 8/10 = 1
      1/3 + 6/9 = 1; 4/5 + 2/10 = 1 [*]
      1/3 + 6/9 = 1; 2/4 + 5/10 = 1
      1/3 + 6/9 = 1; 4/8 + 5/10 = 1

      And it is not possible to form any groups using 1 .. 8 or 1 .. 9, so 1 .. 10 is the smallest set of initial numbers on the blackboard.

      Of the fractions used in these groups, only 4/5 and 2/10 appear in only one group [*], and this group is:

      1/3 + 6/9 = 1; 4/5 + 2/10 = 1

      And so the 2 numbers on the blackboard that are not used in any of these four fractions are 7 and 8.

      Like

    • Frits's avatar

      Frits 10:50 am on 9 December 2023 Permalink | Reply

       
      # numbers 1, 2, 3, ..., n, we need 2 groups with in total 8 different numbers
      n = 8   
      while True:
        # determine numbers (a, b, c, d) do that a/b + c/d = 1 with c > a
        abcd = set((a, b, c, d)
                   for a in range(1, n // 2 + n % 2)
                   for b in range(a + 1, n + 1)
                   for c in range(a + 1, n + 1)
                   if c != b and \
                   not (dm := divmod(b * c, b - a))[1] and \
                   c < (d := dm[0]) <= n and d != b)
        
        # find 2 groups of <abcd> entries that use 8 different numbers among them
        two_groups = [(s1[:2], s1[2:], s2[:2], s2[2:]) for s1 in abcd for s2 in abcd
                      if s1[0] < s2[0] and len(set(s1 + s2)) == 8]  
        
        if not two_groups: 
          n += 1   # try numbers 1, 2, 3, ..., n
          continue
        
        # one of the groups contained some fractions 
        # that were not used by any other group
        all_fractions = [f for g2 in two_groups for f in g2]
        unique_fractions = {f for f in all_fractions if all_fractions.count(f) == 1}
        
        for g2 in two_groups:
          # does a fraction in <g2> only occur in our <g2>?
          if any(f for f in g2 if f in unique_fractions):
            used = set(y for x in g2 for y in x)
            print(f"unused numbers: "
                  f"{[i for i in range(1, n + 1) if i not in used]}")
                  
        break  
      

      Like

      • Frits's avatar

        Frits 12:36 pm on 9 December 2023 Permalink | Reply

        Slower but more compact.

           
        from itertools import permutations
        n = 8 
        while True:
          # determine different numbers (a, b, c, d, e, f, g, h) so that 
          # a/b + c/d = 1 and e/f + g/h = 1 with c > a, g > e and a < e
          abcdefgh = [((a, b), (c, d), (e, f), (g, h)) 
                       for a, b, c, d, e, f, g, h in permutations(range(1, n + 1), 8)
                       if a < b and c < d and e < f and g < h and 
                       a < c and e < g and a < e and 
                       a * d + b * c == b * d and e * h + f * g == f * h]
          
          if not abcdefgh: 
            n += 1   # try numbers 1, 2, 3, ... for a higher n
            continue
          
          # one of the groups contained some fractions 
          # that were not used by any other group
          all_fractions = [fr for f4 in abcdefgh for fr in f4]
          unique_fractions = {f for f in all_fractions if all_fractions.count(f) == 1}
          
          for f4 in abcdefgh:
            # does a fraction in <f4> not occur in any other <abcdefg> entry?
            if any(f for f in f4 if f in unique_fractions):
              used = set(y for x in f4 for y in x)
              print(f"unused numbers: "
                    f"{[i for i in range(1, n + 1) if i not in used]}")
                    
          break  # we are done
        

        Like

  • Unknown's avatar

    Jim Randell 10:58 am on 5 December 2023 Permalink | Reply
    Tags:   

    Teaser 2657: Puzzling book 

    From The Sunday Times, 25th August 2013 [link] [link]

    George and Martha have a book of puzzles numbered from 1 to 30. The solutions are also numbered from 1 to 30, but a solution number is not necessarily the same as the number of the puzzle. George and Martha have solved some of the puzzles. If you look at the number of the puzzle and the number of the solution, then the sum of the two is a perfect power of the difference of the two. George has added up the numbers of the solved puzzles and got a three-figure total. Martha has added up the numbers of the solutions of the solved puzzles and got a higher three-figure total. In fact her total used the same nonzero digits as George’s, but in a different order.

    What (in increasing order) are the numbers of the solved puzzles?

    [teaser2657]

     
    • Jim Randell's avatar

      Jim Randell 10:59 am on 5 December 2023 Permalink | Reply

      This Python program generates possible (puzzle-number, solution-number) pairs, and then searches for a collection of these pairs that satisfies the requirements.

      It runs in 66ms. (Internal runtime is 11ms).

      Run: [ @replit ]

      from enigma import (irange, subsets, is_power_of, unpack, nsplit, printf)
      
      # find puzzles <ps>, solutions <ss> from <pairs>, sum(<ps>) = <tp>, sum(<ss>) = <ts>
      def solve(pairs, ps=[], ss=[], tp=0, ts=0):
        # is this a valid set of pairs?
        if 99 < tp < ts < 1000:
          (dp, ds) = (nsplit(tp), nsplit(ts))
          if not (0 in dp or 0 in ds or sorted(dp) != sorted(ds)):
            # output solution
            printf("G={tp} M={ts} -> ps={ps} ss={ss}")
        if pairs:
          # try adding in the next pair
          (p, s) = pairs[0]
          (tp_, ts_) = (tp + p, ts + s)
          if tp_ < 999 and ts_ < 1000 and p not in ps and s not in ss:
            solve(pairs[1:], ps + [p], ss + [s], tp_, ts_)
          # without the next pair
          solve(pairs[1:], ps, ss, tp, ts)
      
      # consider possible puzzle/solution numbers
      fn = unpack(lambda p, s: is_power_of(p + s, abs(p - s)) is not None)
      pairs = list(filter(fn, subsets(irange(1, 30), size=2, select='M')))
      solve(pairs)
      

      Solution: The solved puzzles are: 1, 3, 6, 7, 9, 10, 12, 15, 21, 28.

      The (puzzle-number, solution-number) pairs are:

      (1, 3) → 1 + 3 = 4 = (3 – 1)^2
      (3, 5) → 3 + 5 = 8 = (5 – 3)^3
      (6, 10) → 6 + 10 = 16 = (10 – 6)^2
      (7, 9) → 7 + 9 = 16 = (9 – 7)^4
      (9, 7) → 9 + 7 = 16 = (9 – 7)^4
      (10, 6) → 10 + 6 = 16 = (10 – 6)^2
      (12, 15) → 12 + 15 = 27 = (15 – 12)^3
      (15, 17) → 15 + 17 = 32 = (17 – 15)^5
      (21, 28) → 21 + 28 = 49 = (28 – 21)^2
      (28, 21) → 28 + 21 = 49 = (28 – 21)^2

      The sum of the puzzle numbers is 112 (George’s total).

      And the sum of the solution numbers is 121 (Martha’s total).

      Like

  • Unknown's avatar

    Jim Randell 4:48 pm on 1 December 2023 Permalink | Reply
    Tags:   

    Teaser 3193: Balanced education 

    From The Sunday Times, 3rd December 2023 [link] [link]

    George and Martha are headmaster and secretary of Millimix School.

    There are 1000 pupils divided into 37 classes of at least 27 pupils each; each class has at least 13 members of each sex. Thus with 27 × 37 = 999, one class has an extra pupil. The classes are numbered 1-37.

    Martha noted that, taking the class with the extra pupil, and adding its class number to the number of girls in that class and a power of two, she would arrive at the square of the class number. Furthermore, the class number equalled the number of classes in which the girls outnumbered the boys.

    How many boys are in the school?

    [teaser3193]

     
    • Jim Randell's avatar

      Jim Randell 5:00 pm on 1 December 2023 Permalink | Reply

      Each class has either 27 or 28 pupils.

      For 27 the boy/girl split is either (13, 14) or (14, 13).

      For 28 the split is one of: (14, 14) (13, 15) (15, 13).

      The following Python program runs in 59ms. (Internal runtime is 163µs).

      Run: [ @replit ]

      from enigma import (irange, sq, is_power_of, printf)
      
      # consider possible class numbers for the class with 28 pupils
      for n in irange(1, 37):
        # consider the number of girls in the class
        for f in [13, 14, 15]:
          # find the necessary power of 2
          p2 = sq(n) - n - f
          k = is_power_of(p2, 2)
          if k is None: continue
          # calculate total number of boys and girls in the school
          m = 28 - f
          n1 = (n - 1 if f > m else n)
          tm = m + n1 * 13 + (36 - n1) * 14
          tf = f + n1 * 14 + (36 - n1) * 13
          # output solution
          printf("n={n} f={f} -> p2=2^{k} => boys={tm} girls={tf}")
      

      Solution: There are 512 boys in the school.

      Class #6 has 28 pupils, it has 14 boys and 14 girls, and we have:

      6 + 14 + 2^4 = 6^2

      Of the remaining 36 classes, there are 6 with 14 girls and 13 boys, and 30 with 14 boys and 13 girls.

      So the total number of boys in the school is:

      14 + 6×13 + 30×14 = 512

      And the total number of girls is:

      14 + 6×14 + 30×13 = 488

      Like

      • Jim Randell's avatar

        Jim Randell 2:53 pm on 3 December 2023 Permalink | Reply

        An alternative version using the observation (made by GeoffR) that:

        n² − n = n(n − 1) = f + 2^k

        is the product of 2 consecutive integers, so must be even.

        The following Python program has an internal runtime of 56µs.

        Run: [ @replit ]

        from enigma import (irange, sqrtc, printf)
        
        # consider powers of 2
        for k in irange(0, 10):
          p = 2**k
          # consider number of girls in the largest class (such that f + p is even)
          for f in ([13, 15] if p % 2 else [14]):
            # calculate n, such that n(n - 1) = f + p
            x = f + p
            n = sqrtc(x)
            if n > 37: continue
            if n * (n - 1) == x:
              # calculate total number of boys and girls in the school
              m = 28 - f
              n1 = (n - 1 if f > m else n)
              tm = m + n1 * 13 + (36 - n1) * 14
              tf = f + n1 * 14 + (36 - n1) * 13
              # output solution
              printf("k={k} n={n} f={f} => boys={tm} girls={tf}")
        

        Like

    • GeoffR's avatar

      GeoffR 11:57 am on 2 December 2023 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
       
      var 13..15:g; % number of girls in class with extra pupil
      var 1..18:xg; % number of classes with more girls than boys
      var 13..540:tot_g; % total girls in the school - UB = 36*15
      var 13..540:tot_b; % total boys in the school
      var 1..37:c; % class number with extra pupil
      var 1..10:x; % a power of 2
      
      constraint c + g + pow(2,x) = c*c;
      constraint xg == c;
      constraint tot_g == g + xg*14 + (36 - xg)*13;
      constraint tot_b == 1000 - tot_g;
      
      solve satisfy;
      output ["Total boys in school = " ++ show(tot_b)];
      

      Like

    • GeoffR's avatar

      GeoffR 1:46 pm on 2 December 2023 Permalink | Reply

      
      for g in range(13, 16):   # girls in class with extra pupil
        for c in range(1, 38):  # class number with extra pupil
          for x in range(1, 11):
            # number of classes with more girls than boys
            #... equals class number with extra pupil
            if g + c + 2**x == c*c:
              tot_g = g + c*14 + (36 - c)*13
              tot_b = 1000 - tot_g
              print(f"Total boys in school = {tot_b}.")
      

      Like

      • Jim Randell's avatar

        Jim Randell 11:00 am on 3 December 2023 Permalink | Reply

        @GeoffR: Would this give the right answer if there were 15 girls in the largest class?

        Like

    • GeoffR's avatar

      GeoffR 12:10 pm on 3 December 2023 Permalink | Reply

      @JimR: I think the following logic shows that g must be even and of value 14, if my logic is OK.

      The teaser requirements can be expressed as:
      c + g + 2^x = c*c, which reduces to: c*(c – 1) = g + 2^x

      where:
      g = number of girls in class with extra pupil, and c = class number with extra pupil.
      Also x is an integer power of 2.

      Analysis:
      Looking at the equation, it can be seen that:
      1) c * (c-1) will always be of even parity for consecutive integers.
      2) 2^x will always be even , except for 2^0 = 1, which does not give a viable c value.
      3) The RHS of the equation must therefore be even to be of equal parity to the LHS.
      4) This means that both g and 2^x must both be even to maintain parity.
      5) g must be one of (13, 14 or 15), leading to g = 14

      Like

    • GeoffR's avatar

      GeoffR 9:10 am on 5 December 2023 Permalink | Reply

      Using girls = 14 for girls in class with extra pupil (see previous posting) for a one-liner,
      or a two-liner for better readability.

      
      print('Boys =',[1000 - (14 + c * 14 + (36 - c)* 13) for x in range(1, 10)
       for c in range(2, 37) if c * (c - 1) == 14 + 2**x].pop())
      

      Like

  • Unknown's avatar

    Jim Randell 9:18 am on 30 November 2023 Permalink | Reply
    Tags:   

    Brainteaser 1449: Magic! 

    From The Sunday Times, 17th June 1990 [link]

    This is a magic square containing all the numbers from 1 to 16 once each. As is always the case with magic squares, all rows, columns, and full-length diagonals add up to the same sum (but all our shorter diagonals add to less than that sum).

    Fill in the missing numbers.

    [teaser1449]

     
    • Jim Randell's avatar

      Jim Randell 9:19 am on 30 November 2023 Permalink | Reply

      If we consider the four rows that make up the square, each row sums to the magic constant k, and between all 4 rows each number is included exactly once. So:

      4k = sum(1 .. 16)
      ⇒ k = 34

      We can now use the [[ SubstitutedExpression ]] solver from the enigma.py library to fill out the remaining squares.

      The following run file executes in 96ms. (Internal runtime of the generated program is 853µs).

      Run: [ @replit ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      #  A B C D
      #  E F G H
      #  I J K L
      #  M N P Q
      
      # digits 1-16 are used:
      --base="17"
      --digits="1-16"
      
      # rows
      "A + B + C + D == 34"
      "E + F + G + H == 34"
      "I + J + K + L == 34"
      "M + N + P + Q == 34"
      
      # columns
      "A + E + I + M == 34"
      "B + F + J + N == 34"
      "C + G + K + P == 34"
      "D + H + L + Q == 34"
      
      # diagonals
      "A + F + K + Q == 34"
      "D + G + J + M == 34"
      
      # short diagonals
      "B + G + L < 34"
      "C + F + I < 34"
      "E + J + P < 34"
      "H + K + N < 34"
      
      # given values
      "A == 9"
      "J == 13"
      "N == 12"
      "Q == 14"
      
      --template=""
      --verbose="AT"
      

      Solution: Here is the completed square:

      Like

    • NigelR's avatar

      NigelR 6:22 pm on 30 November 2023 Permalink | Reply

      Hi Jim
      I agree your solution, but I’m not sure how you reached it with your short diagonal condition of
      “E + J + P < 34" (which isn't satisfied by the solution). Shouldn't it be E+J+O?

      Like

      • NigelR's avatar

        NigelR 6:25 pm on 30 November 2023 Permalink | Reply

        Apologies: Just realised that your notation didn’t include ‘O’!!

        Like

      • Jim Randell's avatar

        Jim Randell 7:55 pm on 30 November 2023 Permalink | Reply

        @NigelR: I often skip O as a variable, as it is easily confused with 0 (zero).

        Like

    • GeoffR's avatar

      GeoffR 7:02 pm on 1 December 2023 Permalink | Reply

      #  A B C D
      #  E F G H
      #  I J K L
      #  M N P Q
      
      from itertools import product, permutations
      from enigma import all_different
      
      # Given grid values
      A, J, N, Q = 9, 13, 12, 14
      
      # Find remaining 12 digits
      digits = set(range(1,17)).difference({9, 13, 12, 14 }) 
      
      # 1st row of grid
      for B, C, D in product(digits, repeat=3):
        if not all_different(A, B, C, D):continue
        if A + B + C + D != 34:continue
        R1 = list(digits.difference({B, C, D}))
        
        # 2nd row of grid
        for E, F, G, H in product(R1, repeat=4):
          if not all_different(E, F, G, H):continue
          if E + F + G + H != 34:continue
          R2 = set(R1).difference({E, F, G, H})
        
          # 3rd row of grid
          for I, K, L in product(R2, repeat=3):
            if not all_different(I, J, K, L):continue
            if I + J + K + L != 34:continue
            if B + G + L >= 34:continue
            if C + F + I >= 34:continue
            
            # only M and P are missing from the 4th row of grid
            R3 = list(set(R2).difference({I, K, L}))
            for M, P in permutations(R3, 2):
              # columns
              if A + E + I + M != 34:continue
              if B + F + J + N != 34:continue
              if C + G + K + P != 34:continue
              if D + H + L + Q != 34:continue
              # diagonals
              if E + J + P >= 34:continue
              if H + K + N >= 34:continue
              if A + F + K + Q != 34:continue
              if D + J + G + M != 34:continue
              
              print('A, B, C, D = ', A,B,C,D)
              print('E, F, G, H = ', E,F,G,H)
              print('I, J, K, L = ', I,J,K,L)
              print('M, N, P, Q = ', M,N,P,Q)
              exit() # only 1 solution needed
      
      # A, B, C, D =  9 6 15 4
      # E, F, G, H =  16 3 10 5
      # I, J, K, L =  2 13 8 11
      # M, N, P, Q =  7 12 1 14
      
      
      
      

      Like

    • Hugo's avatar

      Hugo 10:01 am on 2 December 2023 Permalink | Reply

      I found a second solution. Did I do something wrong?

      9 2 15 8
      6 7 10 11
      16 13 4 1
      3 12 5 14

      Like

      • Jim Randell's avatar

        Jim Randell 11:03 am on 2 December 2023 Permalink | Reply

        Yes, the shorter diagonals have to sum less than 34.

        You have 16 + 7 + 15 = 38 in your diagram.

        Like

        • Hugo's avatar

          Hugo 11:16 am on 2 December 2023 Permalink | Reply

          Aha! I misread the condition as “not equal to that sum”.

          Like

  • Unknown's avatar

    Jim Randell 9:27 am on 28 November 2023 Permalink | Reply
    Tags:   

    Teaser 2648: Painted cubes 

    From The Sunday Times, 23rd June 2013 [link] [link]

    Oliver found some painted cubes in the loft. These cubes had edges whose lengths were whole numbers of centimetres. After choosing some cubes whose edge lengths were consecutive, Oliver proceeded to cut them into “mini-cubes” of side one centimetre. Of course, some of these mini-cubes were partially painted and some were not painted at all.

    On counting up the mini-cubes, Oliver noticed that exactly half of them were not painted at all.

    How many mini-cubes were not painted at all?

    [teaser2648]

     
    • Jim Randell's avatar

      Jim Randell 9:28 am on 28 November 2023 Permalink | Reply

      I assume the large cubes are painted on all faces.

      When a cube with side n cm is cut into 1 cm cubelets, there will be (n − 2)³ cubelets (or 0 for n ≤ 2) that were hidden in the interior, and so have all faces unpainted. And the remaining cubelets will have at least one face painted.

      n = 1 → 1 painted, 0 unpainted
      n = 2 → 8 painted, 0 unpainted
      n = 3 → 26 painted, 1 unpainted
      n = 4 → 56 painted, 8 unpainted

      This Python program assembles a list of painted/unpainted cubelets for increasing sizes of cubes (up to 50 cm) and looks for a collection of consecutively sized cubes that has the same number of painted and unpainted cubes.

      It runs in 59ms. (Internal runtime is 3.8ms).

      Run: [ @replit ]

      from enigma import (irange, cb, unzip, printf)
      
      # record painted/unpainted cubelets
      cs = dict()
      
      # consider the size of the largest cube
      for n in irange(1, 50):
        # calculate painted/unpainted cubelets
        u = (0 if n < 3 else cb(n - 2))
        cs[n] = (cb(n) - u, u)
      
        # choose the number of large cubes selected k..n
        for k in irange(1, n - 1):
          # calculate total painted/unpainted cubelets
          (tp, tu) = map(sum, unzip(cs[i] for i in irange(k, n)))
          if tp == tu:
            # output solution
            printf("cubes {k}..{n} -> {tp} painted + {tu} unpainted")
      

      Solution: There 3024 unpainted cubelets.

      The cubes are sizes 4 to 12.

      So the total number of cubelets is:

      4³ + … + 12³ = 6048

      And the total number of unpainted cubelets is:

      2³ + … + 10³ = 3024

      So exactly half the cubelets are unpainted.


      With some analysis we can construct a more efficient program:

      Assuming the cubes are sizes k .. n, then the total number of cubelets is:

      T = k³ + … + n³

      And the number of unpainted cubelets is:

      U = (k − 2)³ + … + (n − 2)³

      And:

      T = 2U

      The sum of the first n cube numbers is given by [@wikipedia]:

      ST[n] = T[n]² = (n(n + 1)/2)²

      So we have:

      ST[n] − ST[k − 1] = 2 ST[n − 2] − 2 ST[k − 3]

      or:

      ST[n] − 2 ST[n − 2] = ST[k − 1] − 2 ST[k − 3]

      which is of the form:

      f[n − 2] = f[k − 3]
      where:
      f[x] = ST[x + 2] − 2 ST[x]

      So we can calculate values for f[x] until we find two values that have the same result.

      Say:

      f[x] = f[y]
      where x > y

      Then we have:

      n = x + 2
      k = y + 3

      This Python program runs in 59ms. (Internal runtime is 319µs).

      Run: [ @replit ]

      from enigma import (irange, sq, tri, printf)
      
      # square triangular numbers
      ST = lambda x: sq(tri(x))
      
      # calculate the value of f for increasing x
      d = dict()
      for x in irange(1, 48):
        # calculate f(x)
        v = ST(x + 2) - 2 * ST(x)
        printf("[{x} -> {v}]")
        # have we seen this value before
        y = d.get(v)
        if y:
          # corresponding n, k values
          (n, k) = (x + 2, y + 3)
          # output solution
          printf("cubes {k} .. {n} -> {u} unpainted", u=ST(x) - ST(y))
          break
        # record the value
        d[v] = x
      

      Like

  • Unknown's avatar

    Jim Randell 4:46 pm on 24 November 2023 Permalink | Reply
    Tags:   

    Teaser 3192: In formation technology 

    From The Sunday Times, 26th November 2023 [link] [link]

    Football formations are generally described by three or four nonzero whole numbers summing to 10 (the goalkeeper isn’t counted), representing, from defence to attack, the number of players in approximate lines across the pitch.

    Last season we played a different formation every week, always using four lines, each with at most four players; the difference between one week and the next was that from one line two players moved, one to an adjacent line and the other to the line beyond that (e.g. 3-4-1-2 could only be followed by 3-2-2-3). Our number of fixtures was the largest it could have been, given these conditions. The first number in our formations was more often 3 than any other number; 3-1-3-3 gave us our worst result.

    How many games did we play, and what were our first three formations?

    [teaser3192]

     
    • Jim Randell's avatar

      Jim Randell 5:38 pm on 24 November 2023 Permalink | Reply

      This Python program runs in 68ms. (Internal runtime is 2.5ms).

      Run: [ @replit ]

      from enigma import (Accumulator, decompose, update, multiset, join, printf)
      
      # find possible formations
      fs = list(decompose(10, 4, increasing=0, sep=0, min_v=1, max_v=4))
      
      # find possible transitions
      trans = dict()
      for s in fs:
        ts = set()
        # choose an index to donate 2 players
        for (i, n) in enumerate(s):
          if n < 3: continue
          # i -> j, k
          for d in [-1, +1]:
            j = i + d
            if j < 0 or j > 3 or s[j] > 3: continue
            k = j + d
            if k < 0 or k > 3 or s[k] > 3: continue
            ts.add(update(s, [(i, n - 2), (j, s[j] + 1), (k, s[k] + 1)]))
        trans[s] = ts
      
      # find paths in graph <adj>
      def paths(adj, ss):
        yield ss
        # try to extend the path
        s = ss[-1]
        for t in adj[s]:
          if t not in ss:
            yield from paths(adj, ss + [t])
      
      # find maximal length paths
      r = Accumulator(fn=max, collect=1)
      for s in fs:
        for ss in paths(trans, [s]):
          r.accumulate_data(len(ss), ss)
      printf("max len = {r.value}")
      
      # consider maximal length paths
      for ss in r.data:
        # 3-1-3-3 must be present
        if (3, 1, 3, 3) not in ss: continue
        # 3 occurs most frequently as the first number
        m = multiset.from_seq(s[0] for s in ss)
        n3 = m.count(3)
        if not all(n3 > nk for (k, nk) in m.items() if k != 3): continue
        # output solution
        fmt = lambda x: join(x, sep='-')
        printf("{ss}", ss=join((fmt(x) for x in ss), sep=", ", enc="()"))
      

      Solution: There were 13 games. The first three formations were: 3-2-4-1, 4-3-2-1, 4-1-3-2.

      The full list of formations is:

      1: 3-2-4-1
      2: 4-3-2-1
      3: 4-1-3-2
      4: 2-2-4-2
      5: 3-3-2-2
      6: 3-1-3-3
      7: 4-2-1-3
      8: 2-3-2-3
      9: 2-1-3-4
      10: 3-2-1-4
      11: 1-3-2-4
      12: 1-4-3-2
      13: 1-2-4-3

      There are 4 weeks that begin with 3-, and 3 weeks that each start 1-, 2-, 4-.

      Like

      • Frits's avatar

        Frits 5:05 pm on 1 December 2023 Permalink | Reply

        @Jim,

        I noticed that you don’t see (among others ) 4-1-3-2 to 2-2-3-3 as a valid transition. I don’t consider “to the line beyond that” as the immediate adjacent line.

        Like

        • Jim Randell's avatar

          Jim Randell 5:12 pm on 1 December 2023 Permalink | Reply

          @Frits: Yes, it has to be adjacent (it is “the line beyond” not “a line beyond”). It would probably have been better expressed as “the next line beyond”.

          I think there are many solutions to the puzzle where you allow transfers to non-adjacent lines. (I originally tried it with this interpretation).

          And welcome back, it has been a while.

          Like

  • Unknown's avatar

    Jim Randell 9:36 am on 23 November 2023 Permalink | Reply
    Tags:   

    Teaser 2654: Square cut 

    From The Sunday Times, 4th August 2013 [link] [link]

    Given a rectangular piece of paper that is not actually square it is possible with one straight cut to divide it into a square and a rectangle (which might or might not itself be square). I call this process a “square cut”. Recently I started with a rectangle of paper one metre long with the width being more than half a metre. I performed a square cut and put the square to one side. On the remaining rectangle I performed a square cut and put the square to one side. I kept repeating this process until the remaining rectangle was itself a square. The result was that I had cut the original piece of paper into six squares all of whose sides were whole numbers of centimetres.

    How many centimetres wide was the original piece of paper?

    [teaser2654]

     
    • Jim Randell's avatar

      Jim Randell 9:37 am on 23 November 2023 Permalink | Reply

      This Python program considers possible widths between 51 and 99 cm, and looks for those which cut the rectangle into 6 squares.

      It runs in 69ms. (Internal runtime is 452µs).

      Run: [ @replit ]

      from enigma import (irange, ordered, printf)
      
      # perform cuts on an a x b rectangle, where a <= b
      def cut(a, b):
        assert not (a > b)
        ss = list()
        while True:
          ss.append(a)
          if a == b: break
          (a, b) = ordered(a, b - a)
        return ss
      
      # consider the width of the rectangle
      for n in irange(51, 99):
        # cut into squares
        ss = cut(n, 100)
        if len(ss) == 6:
          # output solution
          printf("n={n}: {ss}")
      

      Solution: The original piece of paper was 70 cm wide.

      The sizes of the 6 squares made are: 70, 30, 30, 10, 10, 10.

      Like

  • Unknown's avatar

    Jim Randell 4:23 pm on 20 November 2023 Permalink | Reply
    Tags:   

    Teaser 2670: Answers on a postcard 

    From The Sunday Times, 24th November 2013 [link] [link]

    On a postcard I have written four two-digit numbers, none of which is divisible by three. In three of the numbers the two digits used are consecutive (in some order) and in fact overall the four numbers use eight consecutive digits. I have calculated the sum and product of the four numbers. Then I have consistently replaced each of the digits 0 to 9 by a different letter of the alphabet. It turns out that the sum of my four numbers is SUM and their product is PRODUCT.

    What number is represented by POSTCARD?

    [teaser2670]

     
    • Jim Randell's avatar

      Jim Randell 4:24 pm on 20 November 2023 Permalink | Reply

      Here is a solution using the [[ SubstitutedExpression ]] solver from the enigma.py library.

      It runs in 73ms. (Internal runtime of the generated code is 2.3ms).

      Run: [ @replit ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      --distinct="abcdefgh,ACDMOPRSTU"
      
      # check integers <ns> are consecutive (when considered in order)
      --code="check = lambda ns: ns[-1] + 1 == ns[0] + len(ns)"
      --code="is_consecutive = lambda *ns: check(sorted(ns))"
      
      # sum is SUM, product is PRODUCT
      "{ab} + {cd} + {ef} + {gh} = {SUM}"
      "{ab} * {cd} * {ef} * {gh} = {PRODUCT}"
      
      # suppose {ab}, {cd}, {ef} (in order) are the 3 with consecutive digits
      "is_consecutive({a}, {b})"
      "is_consecutive({c}, {d})"
      "is_consecutive({e}, {f})"
      "{a} < {c} < {e}"
      # [optional] the other one does not consist of consecutive digits
      "not is_consecutive({g}, {h})"
      
      # 8 consecutive digits are used overall
      "is_consecutive({a}, {b}, {c}, {d}, {e}, {f}, {g}, {h})"
      
      --answer="POSTCARD"
      --template="({ab} {cd} {ef} {gh}) ({SUM}) ({PRODUCT}) ({POSTCARD})"
      --solution=""
      

      Solution: POSTCARD = 94267830.

      The numbers are:

      (23, 56, 74, 98)
      SUM = 251
      PRODUCT = 9340576

      Like

    • GeoffR's avatar

      GeoffR 9:43 am on 21 November 2023 Permalink | Reply

      from enigma import all_different,nsplit,nconcat
      
      def consec_dig(L):
          return sorted(L) == list(range(min(L), max(L)+1))
      
      # Find three 2-digit numbers (ab, cd, ef) with consecutive digits
      for ab in range(12, 99):
        if ab % 3 == 0:continue
        for cd in range(ab+1, 99):
          if cd % 3 == 0:continue
          for ef in range(cd+1, 99):
            if ef % 3 == 0:continue
            a, b, c, d = ab // 10, ab % 10, cd // 10, cd % 10
            e, f = ef // 10, ef % 10
            if not a < c < e:continue
            L_6d = [a, b, c, d, e, f]
            if consec_dig(L_6d):
                
              # last 2-digit number does not have consecutive digits
              for gh in range(ef+1, 99):
                if gh % 3 == 0:continue
                g, h = gh // 10, gh % 10
                if g < h:continue
                
                # check overall the four numbers use eight consecutive digits 
                L_8d = [a, b, c, d, e, f, g, h]
                if consec_dig(L_8d):
                    
                  # Find SUM and PRODUCT
                  SUM = ab + cd + ef + gh
                  S, U, M = SUM //100, SUM // 10 % 10, SUM % 10
                  if not all_different(S, U, M): continue
                  
                  PRODUCT = ab * cd * ef * gh
                  # Check PRODUCT has 7 digits
                  if len(str(PRODUCT)) != 7:continue
                  P, R, O, D, U, C, T = nsplit(PRODUCT)
                  if not all_different (P,R,O,D,U,C,T ):continue
                  
                  # Check 'U' is same value in SUM and PRODUCT
                  if SUM // 10 % 10 == PRODUCT // 100 % 10:
                    # Find missing letter A for POSTCARD value
                    digits = set(range(10))
                    A = digits.difference({S,U,M,P,R,O,D,C,T}).pop()
                    POSTCARD = nconcat(P,O,S,T,C,A,R,D)
                    print(f"SUM = {SUM},PRODUCT = {PRODUCT}")
                    print(f"POSTCARD = {POSTCARD}")
                    print(f"Four Numbers are {ab},{cd},{ef} and {gh}.")
      
      # SUM = 251,PRODUCT = 9340576
      # POSTCARD = 94267830
      # Four Numbers are 23,56,74,98.
         
      
      

      Like

  • Unknown's avatar

    Jim Randell 4:46 pm on 17 November 2023 Permalink | Reply
    Tags:   

    Teaser 3191: The budgie’s extra ration 

    From The Sunday Times, 19th November 2023 [link] [link]

    The budgie’s circular toy hung on a hook. Two equal legs suspended his budgerigar-seed dispensing chord from that hook. Parallel to the chord, a diameter crossed the middle. When budgie knocked his seed dispenser below the  diameter, a triangle lit up, as shown, and he got an extra seed ration. In the design of the toy, the ratio of the length of the chord to the length of the smallest side of the lit triangle has been adjusted so that a right-angled triangle results, with the right angle on the diameter.

    What is the square of that ratio?

    [teaser3191]

     
    • Jim Randell's avatar

      Jim Randell 7:05 pm on 17 November 2023 Permalink | Reply

      You can have a pretty good guess at the answer by measuring the relevant lines in the diagram.

      Here’s a numerical solution:

      This Python program runs in 56ms. (Internal runtime is 382µs).

      Run: [ @replit ]

      from enigma import (find_value, rcs, line_intersect, sq, fdiv, printf)
      
      # distance between A and B
      def dist(A, B):
        ((x1, y1), (x2, y2)) = (A, B)
        return rcs(abs(x1 - x2), abs(y1 - y2))
      
      # return the cosine of the angle for a chord of length 2x (on a unit circle)
      def solve(x, verbose=0):
        y = rcs(1, -x)
        # vertices of the isosceles triangle = A, B, C
        (A, B, C) = ((0, -1), (x, y), (-x, y))
        # chord length = c
        c = dist(B, C)
        # find where AB intersects the diameter = X
        X = line_intersect(A, B, (1, 0), (-1, 0)).pt
        # non-hypotenuse sides of the lit triangle = f, g
        (f, g) = (dist(A, X), dist(X, C))
      
        # print the answer R = (c/f)^2
        if verbose: printf("R = sq(c/f) = {r:.6g} [x={x:.6f} y={y:.6f}]", r=fdiv(sq(c), sq(min(f, g))))
      
        # return the cosine of the angle AXC (cosine rule)
        h = dist(A, C)
        return fdiv(sq(f) + sq(g) - sq(h), 2 * f * g)
      
      # find x that gives an angle of pi/2 (cosine = 0)
      r = find_value(solve, 0, 0, 1)
      # output solution
      solve(r.v, verbose=1)
      

      Solution: The square of the ratio is 2.

      i.e. the ratio itself is √2.


      We can determine the answer analytically using a similar approach as follows:

      With a unit circle, and a chord of length 2x the co-ordinates of the isosceles triangle can be represented as:

      A = (0, −1)
      B = (x, y)
      C = (−x, y)
      where:
      x, y ∈ (0, 1) and x² + y² = 1

      The line AB intersects the diameter at:

      X = (x/(y + 1), 0)

      And so we can determine the 3 sides of the lit triangle f, g, h in terms of y:

      f² = |AX|² = x²/(y + 1)² + 1
      f² = 2/(y + 1)

      g² = |CX|² = x²(y + 2)²/(y + 1)² + y²
      g² = (4 − 2y²)/(y + 1)

      h² = |AC|² = x² + (y+1)²
      h² = 2y + 2

      And this is a right-angled triangle, so f² + g² = h²:

      2/(y + 1) + (4 − 2y²)/(y + 1) = 2y + 2
      y² + y − 1 = 0

      y = (√5 − 1)/2 ≈ 0.618 (and x = √y ≈ 0.786)

      If φ is the Golden Ratio, then: y = φ − 1 = 1/φ, but we don’t need to deal with the actual value of y, instead we note:

      y = 1 − y²
      y(y + 1) = y² + y = 1

      We can then determine the required answer (R) as c²/f² where the length of the chord c = 2x:

      R = 4x² / 2/(y + 1)
      R = 2(1 − y²)(y + 1)
      R = 2y(y + 1)
      R = 2

      Like

  • Unknown's avatar

    Jim Randell 8:57 am on 16 November 2023 Permalink | Reply
    Tags:   

    Brain-Teaser 422: Telephone number 

    From The Sunday Times, 8th June 1969 [link]

    Fred was an exasperating person; he would never give a straight answer to a straight question. The other day I was seeing him off at a bus stop and he said, just as the bus was coming, “Give me a ring some time”.

    “I will”, I said, and asked him for his telephone number.

    “It has five digits”, he replied, and the first two are the same as my wife’s age while the last two are my age”.

    “But I don’t know how old you are”, I said, “except that you are less than 70”.

    “There’s no need to be rude”, he said. “I am older than my wile by as many years as our son’s age”.

    “What has he got to do with your telephone number?”, I asked.

    “Oh”, he replied, “his age is the middle digit”.

    “That doesn’t help much”, I said.

    “It’s divisible by 259, he shouted”, as the bus whisked him away.

    “That’s a great help”, I shouted back, and it really was.

    What was Fred’s telephone number?

    This puzzle is included in the book Sunday Times Brain Teasers (1974).

    [teaser422]

     
    • Jim Randell's avatar

      Jim Randell 8:57 am on 16 November 2023 Permalink | Reply

      This puzzle is straightforward to solve programatically.

      Here is a solution using the [[ SubstitutedExpression ]] solver from the enigma.py library.

      It runs in 84ms. (Internal runtime of the generated program is 11ms).

      Run: [ @replit ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      --invalid="0,ACD"
      --distinct=""
      
      # Fred is less than 70
      "DE < 70"
      
      # Fred is older than his wife by as many years as his son's age
      "AB + C = DE"
      
      # The phone number is divisible by 259
      "ABCDE % 259 = 0"
      
      --answer="ABCDE"
      

      Solution: Fred’s telephone number is 35742.

      And we have:

      35 + 7 = 42
      35742 = 138 × 259

      Like

    • GeoffR's avatar

      GeoffR 2:51 pm on 16 November 2023 Permalink | Reply

      for H in range(15, 70):
        for W in range(15, H):
          if H - W > 9:
            continue
          for S in range(1, 10):
            # Son's age = Husband's age - Wife's age 
            if H - W == S:
              # Son's age is the single middle digit of the telephone number
              tel_num = int(str(W) + str(S) + str(H))
              if tel_num % 259 == 0:
                print(f"Fred's telephone number was {tel_num}.")
      
      # Fred's telephone number was 35742.
      
      

      If the telephone number was not divisible by 259, I found 450 solutions.

      Like

  • Unknown's avatar

    Jim Randell 7:55 am on 14 November 2023 Permalink | Reply
    Tags:   

    Teaser 2652: Square meals 

    From The Sunday Times, 21st July 2013 [link] [link]

    A company produces five different types of muesli. The ingredients are bought from a wholesaler who numbers his items from 1 to 10. In each type of muesli there is a mixture of a square number of different ingredients and the weight in grams of each ingredient is the square of its item number: also the total weight of its ingredients is a perfect square number of grams.

    Last month one of the ingredients was unavailable and so only the “basic” and “fruity” varieties could be produced. This week a different ingredient is unavailable and so only the “luxury” variety can be made.

    What are the item numbers of the ingredients in the luxury muesli?

    [teaser2652]

     
    • Jim Randell's avatar

      Jim Randell 7:55 am on 14 November 2023 Permalink | Reply

      I assumed each mixture has multiple ingredients, and as there are only 10 possible ingredients this means each must have 4 or 9.

      This Python program looks for sets of 4 or 9 numbers from 1 to 10 whose squares sum to a square number. We then choose 5 of these sets to form the different types of muesli made, and look for the 2 (different) unavailable ingredients. The first unavailable ingredient only allows 2 of the types to be made (these are “basic” and “fruity”) and the second only allows 1 to be made (and this is “luxury”).

      It runs in 84ms. (Internal runtime is 879µs).

      Run: [ @replit ]

      from enigma import (irange, subsets, sq, is_square, union, intersect, printf)
      
      # collect possible collections of ingredients
      ms = list()
      
      # choose 4 or 9 ingredients
      for k in [4, 9]:
        for ns in subsets(irange(1, 10), size=k):
          # calculate the total weight
          t = sum(sq(n) for n in ns)
          if not is_square(t): continue
          printf("[k={k}: ns={ns} t={t}]")
          ms.append(ns)
      
      # choose 5 varieties
      for vs in subsets(ms, size=5):
        ns = union(vs)
        # choose the first unavailable ingredient
        for u1 in ns:
          # find how many can be made without u1
          vs1 = list(v for v in vs if u1 not in v)
          # there are 2 that cannot be made ("basic" and "fruity")
          if len(vs1) != 2: continue
      
          # choose the second unavailable ingredient
          for u2 in ns:
            if u2 == u1: continue
            # find how many can be made without u2
            vs2 = list(v for v in vs if u2 not in v)
            # there is only 1 that cannot be made ("luxury")
            if len(vs2) != 1: continue
            if intersect([vs1, vs2]): continue
      
            # output solution
            printf("u1={u1} -> basic/fruity={vs1}; u2={u2} -> luxury={vs2[0]}")
      

      Solution: Luxury muesli uses ingredients: 2, 4, 5, 6.

      There are only 5 possible sets of ingredients, so these correspond to each of the 5 types of museli:

      (2, 4, 5, 6) → 81
      (1, 2, 4, 10) → 121
      (1, 2, 8, 10) → 169
      (2, 4, 7, 10) → 169
      (5, 6, 8, 10) → 225

      The unavailable ingredient last month was 4, meaning only: (1, 2, 8, 10) and (5, 6, 8, 10) could be made. These are (in some order) “basic” and “fruity”.

      The unavailable ingredient this week is 10, meaning only (2, 4, 5, 6) can be made, and this is “luxury”.

      Like

  • Unknown's avatar

    Jim Randell 2:48 pm on 12 November 2023 Permalink | Reply
    Tags:   

    Brainteaser 1500: Lying about his age 

    From The Sunday Times, 9th June 1991 [link]

    It’s Uncle Joe’s birthday today, but he’s reluctant to tell me how old he is. Here are some clues, although some of them aren’t true:

    1. Every number of a true statement is a factor of Joe’s age.

    2. Every number of a false statement is a factor of Joe’s age.

    3. This is neither the first true nor the last false statement.

    4. Of the two statements immediately before and after this one, just one is true and the other is false.

    5. Of the two statements immediately before and after this one, just one is true and the other is false.

    6. Each digit of Joe’s age is different and is the number of a statement which is false.

    7. This is either the last true or the last false statement.

    8. Every prime factor of Joe’s age is the number of a true statement.

    How old is Joe?

    [teaser1500]

     
    • Jim Randell's avatar

      Jim Randell 2:49 pm on 12 November 2023 Permalink | Reply

      The following Python program considers possible ages, and truth values for the statements.

      The [[ Delay() ]] class from the enigma.py library is used to calculate the digits and prime factors of the age only as necessary. (Although in the event this doesn’t save a great deal of processing).

      The program runs in 147ms. (Internal runtime is 73ms).

      Run: [ @replit ]

      from enigma import (Delay, irange, subsets, nsplit, prime_factor, map2str, printf)
      
      # the prime factors of <n>
      factors = lambda n: list(f for (f, _) in prime_factor(n))
      
      # choose an age
      for n in irange(1, 121):
        # delay the evaluation of digits and factors
        _ds = Delay(nsplit, n)
        _fs = Delay(factors, n)
      
        # choose truth values for the statements
        for vs in subsets((False, True), size=8, select="M"):
          if all(vs): continue
          ss = dict(enumerate(vs, start=1))
      
          # check the values:
          # 1. "every number of a true statement is a factor of the age"
          if ss[1] != all(n % k == 0 for (k, v) in ss.items() if v): continue
      
          # 2. "every number of a false statement is a factor of the age"
          if ss[2] != all(n % k == 0 for (k, v) in ss.items() if not v): continue
      
          # 3. "this is neither the first true nor the last false statement"
          if ss[3] != (not ((not any(vs[:2])) if ss[3] else all(vs[3:]))): continue
      
          # 4. "one of (3), (5) is true and one is false"
          if ss[4] != (ss[3] != ss[5]): continue
      
          # 5. "one of (4), (6) is true and one is false"
          if ss[5] != (ss[4] != ss[6]): continue
      
          # 6. "each digit of the age is different, and the number of a false statement"
          ds = _ds.value
          if ss[6] != (len(ds) == len(set(ds)) and all(not ss.get(d, 1) for d in ds)): continue
      
          # 7. "this is either the last true or the last false statement"
          if ss[7] != ((not ss[8]) if ss[7] else ss[8]): continue
      
          # 8. "every prime factor of the age is the number of a true statement"
          fs = _fs.value
          if ss[8] != all(ss.get(f, 0) for f in fs): continue
      
          # output solution
          printf("n={n} {ss}", ss=map2str(ss, enc="[]"))
      

      Solution: Joe is 72.

      And the values of the statements are:

      1. true [the true statements are 1, 3, 4, 6, and these are all divisors of 72]
      2. false [5 and 7 are false statements, but there are not divisors of 72]
      3. true [this is not the first true statement (1), nor the last false statement (8)]
      4. true [3 is true, 5 is false]
      5. false [both 4 and 6 are true]
      6. true [7 and 2 are different, and both number false statements]
      7. false [this is not the last true statement (6), nor the last false statement (8)]
      8. false [2 is a prime factor of 72, and statement 2 is false]

      Like

  • Unknown's avatar

    Jim Randell 4:37 pm on 10 November 2023 Permalink | Reply
    Tags:   

    Teaser 3190: Mods-In-Suits 

    From The Sunday Times, 12th November 2023 [link] [link]

    In single-pack card game Mods-In-Suits, players are dealt two cards. Each card’s face value (Ace=1 to K=13) is modified by its suit, thus:

    “Spade” squares it;
    “Heart” halves it;
    “Club” changes its sign;
    “Diamond” divides it by the other card’s face value.

    Players score their modified values’ sum (or zero if there is a matching pair of face values). Players may exchange their second dealt card for a fresh card from the pack.

    Stuck in the jam in the Smoke at rush hour, John’s children were missing Andy’s party. Playing Mods-In-Suits for amusement led to one unusual game. Jo’s initial score was a positive whole number, Bo’s its negative. Four different suits and face values were dealt. Both exchanged their second card, but each score was unchanged. Four different suits were still showing.

    Give Jo’s final hand.

    [teaser3190]

     
    • Jim Randell's avatar

      Jim Randell 5:21 pm on 10 November 2023 Permalink | Reply

      This Python program runs in 80ms. (Internal runtime is 12ms).

      Run: [ @replit ]

      from enigma import (
        irange, cproduct, sq, rdiv, group, subsets, unpack,
        as_int, intersect, singleton, diff, join, printf
      )
      
      # a pack of cards (<suit>, <value>)
      pack = list(cproduct(['SHCD', irange(1, 13)]))
      
      # calculate modified value for card <X> paired with <Y>
      def value(X, Y):
        ((sx, vx), (sy, vy)) = (X, Y)
        if sx == 'S': return sq(vx)
        if sx == 'H': return rdiv(vx, 2)
        if sx == 'C': return -vx
        if sx == 'D': return rdiv(vx, vy)
      
      # score a pair of cards (we are only interested in non-zero integer
      # values, from pairs of cards with different suits)
      def score(X, Y):
        ((sx, vx), (sy, vy)) = (X, Y)
        if sx == sy or vx == vy: return None
        return as_int(value(X, Y) + value(Y, X), include='+-', default=None)
      
      # deal 3 cards from the pairs <ps>
      # return cards <x1> and <x2> which is replaced by <x3>
      def deal(ps):
        for (p1, p2) in subsets(ps, size=2, select='P'):
          x1 = singleton(intersect([p1, p2]))
          if x1 is None: continue
          x2 = singleton(diff(p1, p2))
          x3 = singleton(diff(p2, p1))
          yield (x1, x2, x3)
      
      # group pairs by integer value
      g = group(subsets(pack, size=2), by=unpack(score))
      del g[None]  # remove scores we are not interested in
      
      # consider possible scores for J
      for (k, psJ) in g.items():
        if k < 0 or len(psJ) < 2: continue
        # B's score is -k
        psB = g.get(-k)
        if psB is None or len(psB) < 2: continue
      
        # consider cards for J (J1, J2 -> J3)
        for (J1, J2, J3) in deal(psJ):
          # consider cards for B (B1, B2 -> B3)
          for (B1, B2, B3) in deal(psB):
            # check deals are possible
            if len({J1, J2, J3, B1, B2, B3}) < 6: continue
            # check 4 different suits and values initially
            if any(len({J1[i], J2[i], B1[i], B2[i]}) < 4 for i in [0, 1]): continue
            # check 4 different suits finally
            if len({J1[0], J3[0], B1[0], B3[0]}) < 4: continue
            # output solution
            (J1, J2, J3, B1, B2, B3) = map(join, (J1, J2, J3, B1, B2, B3))
            printf("J: {J1}, {J2} -> {J3} [+{k}]; B: {B1}, {B2} -> {B3} [-{k}]")
      

      Solution: Jo’s final hand is: Ace of Spades, 6 of Hearts.

      The initial cards dealt were:

      Jo: Ace of Spades, 3 of Diamonds; score = (+1, +3) = +4
      Bo: 6 of Clubs, 4 of Hearts; score = (−6, +2) = −4

      The suits are: S, D, C, H and the values: 1, 3, 4, 6.

      Jo then chooses to discard 3 of Diamonds, and is dealt 6 of Hearts:

      Jo: Ace of Spades, 6 of Hearts; score = (+1, +3) = +4

      Bo then chooses to discard 4 of Hearts, and is dealt Queen (12) of Diamonds:

      Bo: 6 of Clubs, 12 of Diamonds; score = (−6, +2) = −4

      The suits are: S, H, C, D and the values: 1, 6, 6, 12.


      If Jo’s discarded card is returned to the pack, and then it can be Bo’s exchange card (rather than a “fresh” card from the pack) and this leads to a further solution, where the final values are also all different (I initially was solving the puzzle with this extra condition). So presumably that does not happen.

      The initial cards dealt were:

      Jo: Ace of Spades, 4 of Hearts; score = (+1, +2) = 3
      Bo: 5 of Clubs, 10 of Diamonds; score = (−5, +2) = −3

      The suits are: S, H, C, D and the values 1, 4, 5, 10.

      Jo then chooses to discard the 4 of Hearts (which is returned to the pack), and is dealt 2 of Diamonds:

      Jo: Ace of Spades, 2 of Diamonds; score = (+1, +2) = 3

      Bo then chooses to discard the 10 of Diamonds, and is dealt 4 of Hearts (the card discarded by Jo):

      Bo: 5 of Clubs, 4 of Hearts; score = (−5, +2) = −3

      The suits are: S, D, C, H and the values: 1, 2, 4, 5.

      Like

  • Unknown's avatar

    Jim Randell 8:13 am on 5 November 2023 Permalink | Reply
    Tags:   

    Brain-Teaser 935: Ears, noses & throats 

    From The Sunday Times, 22nd June 1980 [link]

    Our local hospital is a busy place, with a large department, luckily, to keep records of what is wrong with whom. Those who come to the ENT specialist to complain about their ears, sometimes complain about their nose or their throat.

    Of his 60 patients, the number complaining of ears and nose only is three times as great as the number complaining of ears and throat only.

    Another group consists of those who say that their ears are the only body part of the three where they are in good health; and this group is three times as large as the group which declares that the throat alone is healthy.

    It’s all very confusing, I know; but I can tell you that there are 110 complaints in all — if you count a complaint about two ears as one complaint.

    Everyone complains about at least one thing.

    How many patients come with complaints about one part of their anatomy (ears or nose or throat) only?

    This puzzle is included in the book The Sunday Times Book of Brainteasers (1994).

    [teaser935]

     
    • Jim Randell's avatar

      Jim Randell 8:14 am on 5 November 2023 Permalink | Reply

      We can label the areas of the Venn diagram we are interested in as: E, N, T, EN, ET, NT, ENT (this accounts for all patients, as each has at least one complaint).

      We have:

      E + N + T + EN + ET + NT + ENT = 60
      EN = 3 ET
      NT = 3 EN
      E + N + T + 2(EN + ET + NT) + 3 ENT = 110

      And we want to determine the value of E + N + T.

      So:

      EN = 3 ET
      NT = 3 EN = 9 ET

      Hence:

      EN + ET + NT = 3 ET + ET + 9 ET = 13 ET

      Writing: X = E + N + T, we get:

      X + 13 ET + ENT = 60
      X + 26 ET + 3 ENT = 110

      X = ENT + 10

      And so:

      2 ENT = 50 − 13 ET

      There are 2 possibilities:

      ET = 0 ⇒ ENT = 25, E+N+T = 35
      ET = 2 ⇒ ENT = 12, E+N+T = 22

      If we suppose the phrase: “three times as great/large” in the puzzle text precludes zero values, then only a single solution remains.

      Solution: 22 of the patients have a single complaint.

      Like

  • Unknown's avatar

    Jim Randell 4:33 pm on 3 November 2023 Permalink | Reply
    Tags:   

    Teaser 3189: Telling tiles 

    From The Sunday Times, 5th November 2023 [link] [link]

    I have four tiles with a digit written on each of them: I shall refer to these as A, B, C and D. I have rearranged the tiles in various ways to make two 2-digit numbers and I have then multiplied those two numbers together (e.g., CB times AD). In this way I have found as many answers as possible with this particular set of tiles and I have discovered that:

    1. The number of different answers is AB.
    2. Of those answers B consist of the four digits A, B, C, D in some order.
    3. There are C other 4-digit answers.

    What are A, B, C and D respectively?

    [teaser3189]

     
    • Jim Randell's avatar

      Jim Randell 5:02 pm on 3 November 2023 Permalink | Reply

      It wasn’t clear to me if 0 digits were allowed or not, or if repeated digits were allowed, so I wrote code to solve the most permissive interpretation. But it turns out there is the same unique answer whatever variation is used.

      This Python program runs in 131ms. (Internal runtime is 52ms).

      Run: [ @replit ]

      from enigma import (irange, subsets, multiset, nconcat, nsplit, singleton, printf)
      
      # choose the 4 digits
      for ds in subsets(irange(0, 9), size=4, select='R'):
        m = multiset.from_seq(ds)
      
        # find the products of 2 digit pairs (ignoring duplicates)
        ps = set(
          nconcat(a, b) * nconcat(c, d)
            for (a, b, c, d) in subsets(ds, size=4, select='mP')
        )
      
        # AB = number of different products
        n = len(ps)
        (A, B) = nsplit(n, 2)
        if not m.issuperset((A, B)): continue
      
        # count total 4-digit products = t
        # those that are rearrangements of <ds> = r
        t = r = 0
        for p in ps:
          ds_ = nsplit(p)
          if len(ds_) != 4: continue
          t += 1
          if multiset.from_seq(ds_) == m: r += 1
      
        # B = number of rearrangements
        if r != B: continue
      
        # C = number of remaining 4-digit products
        C = t - r
        # and D is the remaining digit
        D = singleton(m.difference((A, B, C)))
        if D is None: continue
      
        # output solution
        printf("(A, B, C, D) = {ds} [n={n} t={t} r={r}]", ds=(A, B, C, D))
      

      Solution: (A, B, C, D) = (1, 2, 7, 8).

      There are 12 different products:

      17 × 28 = 476
      18 × 27 = 486
      12 × 78 = 936
      12 × 87 = 1044
      18 × 72 = 1296
      17 × 82 = 1394
      21 × 78 = 1638
      21 × 87 = 1827 [*]
      28 × 71 = 1988
      27 × 81 = 2187 [*]
      71 × 82 = 5822
      72 × 81 = 5832

      2 of them [*] are rearrangements of the digits A, B, C, D, and there are 7 other 4-digit products.


      There are 55 sets of digits that satisfy condition 1, and the numbers of distinct products are: 1, 2, 4, 6, 10, 12.

      12 is the largest number of distinct products we can have, because there are 24 rearrangements of the 4 digits, but in this list each product will appear twice (as pq × rs and rs × pq).

      When we include condition 2 only 3 sets of digits survive:

      (1, 0, 4, 6) → 10 products {46, 64, 84, 244, 246, 460, 640, 840, 2440, 2460}, 0 rearrangements [2 others]
      (1, 0, 5, 9) → 10 products {59, 95, 135, 455, 459, 590, 950, 1350, 4550, 4590}, 0 rearrangements [3 others]
      (1, 2, 7, 8) → 12 products {476, 486, 936, 1044, 1296, 1394, 1638, 1827, 1988, 2187, 5822, 5832}, 2 rearrangements [7 others]

      And of these only the last set satisfies condition 3, and provides the required answer.

      Like

  • Unknown's avatar

    Jim Randell 11:20 am on 2 November 2023 Permalink | Reply
    Tags:   

    Brainteaser 1555: Riddle-me-ree 

    From The Sunday Times, 28th June 1992 [link]

    My first is a digit
    That is equal to “y”.
    My second’s not zero,
    But smaller than pi.

    My third, fourth and fifth
    You’ll find if you try,
    For my whole is the cube
    Of “x” squared plus “y”.

    “x” is an integer
    And so is “y”.
    I’ve only five digits,
    What number am I?

    [teaser1555]

     
    • Jim Randell's avatar

      Jim Randell 11:21 am on 2 November 2023 Permalink | Reply

      Here is a solution using the [[ SubstitutedExpression ]] solver from the enigma.py library.

      The following run file executes in 94ms. (Internal runtime of the generated code is 32ms).

      Run: [ @replit ]

      #! python3 -m enigma -rr
      
      # we are looking for: YABCD = (X^2 + Y)^3
      
      SubstitutedExpression
      
      --distinct=""
      --invalid="0,AY"
      --invalid="4|5|6|7|8|9,A"  # 2nd digit is 1, 2, 3
      
      # the 5-digit number is the cube of X^2 + Y
      "is_square(is_cube(YABCD) - Y)"
      
      --answer="YABCD"
      

      Or we can use a simple Python program:

      from enigma import (irange, nsplit, is_square, printf)
      
      # consider 5-digit cubes
      for i in irange(22, 46):
        n = i**3
        (y, a, _, _, _) = nsplit(n)
        if a == 0 or a > 3: continue
        x = is_square(i - y)
        if x is None: continue
        # output solution
        printf("{n} = ({x}^2 + {y})^3")
      

      Solution: The number is 91125.

      We have x = 6, y = 9, and:

      (6² + 9)³ = 91125

      Like

    • Ender Aktulga's avatar

      Ender Aktulga 11:12 am on 7 November 2023 Permalink | Reply

      Answer: 91125

      from math import sqrt
      
      i=0
      n=0
      while True:
          i+=1
          n=i**3
              
          if n=100000:
              break
          
          n2=int(str(n)[1])  #:[1]
          if n2==0 or n2>3:
              continue
      
          y=n//10000
          x=round(sqrt(i-y))
          if n!=(x**2+y)**3:
              continue
      
          print(f"{i=}, i^3={n=}, {x=}, i={x**2+y=}")
      
      """
      i=45, i^3=n=91125, x=6, i=x**2+y=45
      """
      

      Like

      • Jim Randell's avatar

        Jim Randell 8:21 am on 9 November 2023 Permalink | Reply

        Thanks for the comment, but if this is meant to be a Python program there seem to be some problems with it, because it doesn’t run.

        If you want to post a new comment with a revised version I can remove this version.

        When posting code it is best to wrap it in [code]...[/code] tags to make sure it appears correctly.

        Like

    • GeoffR's avatar

      GeoffR 9:53 am on 11 November 2023 Permalink | Reply

      cb5d = [x * x * x for x in range(22, 47)]
      
      for x in range(1, 10):
          for y in range(1, 10):
              n = (x * x + y) ** 3
              if n not in cb5d:continue
              # y is my first digit
              if str(n)[0] != str(y):continue
              # My second digit is not zero, but smaller than pi
              if str(n)[1] not in ('1', '2', '3'):continue
              print(f"My 5-digit number is {n}.")
      

      My 5-digit number is 91125.

      Like

    • GeoffR's avatar

      GeoffR 10:42 am on 12 November 2023 Permalink | Reply

      I updated the original 5-digit cube list to include a check on the 2nd digit of the 5-digit number. This reduced the original cube list from 25 potential candidates to 6 cubes to check.

      
      # list of 5-digit cubes with 2nd digit in range 1..3
      cb_5d = [x * x * x for x in range(22, 47)
              if str(x * x * x)[1] in ('1','2','3')]
      
      # find x and y values
      for x in range(1, 10):
          for y in range(1, 10):
              n = (x * x + y) ** 3
              # 5-digit number required
              if n < 10000:
                  continue
              if n in cb_5d:
                  # y is my first digit
                  if str(n)[0] == str(y):
                      print(f"My 5-digit number is {n}.")
      
      print(f"Candidate cube list was {cb_5d}")
      
      # My 5-digit number is 91125.
      # Candidate cube list was [12167, 13824, 21952, 32768, 42875, 91125]
      
      
      
      

      Like

  • Unknown's avatar

    Jim Randell 7:39 am on 31 October 2023 Permalink | Reply
    Tags:   

    Teaser 2647: Happy medium 

    From The Sunday Times, 16th June 2013 [link] [link]

    At a recent séance Adam, Alan, Andy, Eden, Eric, Fred, Gary, Glen, John, Mike, Pete and Tony sat around a circular table of radius one metre. Around its edge there were 12 equally-spaced points, each representing a different letter of the alphabet.

    A light started at the centre, moved straight to one of the points, moved straight to another, then straight to another, and so on, before returning directly to the centre. In this way it spelt out the name of one of the people present. It then started again and in a similar fashion spelt out a day of the week. Then it started again and spelt out a month. Every straight line path that it took was a whole number of centimetres long.

    Which three words did it spell out?

    [teaser2647]

     
    • Jim Randell's avatar

      Jim Randell 7:41 am on 31 October 2023 Permalink | Reply

      See also: Enigma 595a, Enigma 146, Enigma 1369.

      The 12 points fall into two regular hexagonal orbits, and once the initial letter is selected we must stay in that particular orbit, making transitions of ±1 or 3 to move between letters. Therefore any word spelled out must not have more than 6 different letters (which eliminates 4 of the days of the week, and 3 months of the year).

      Also, if we label the letters in any particular orbit alternately as “odd” and “even”, then we can only transition from an “odd” position to an “even” position and vice versa. (So we can eliminate 3 more months which have a letter with both parities).

      So each arrangement consists of two distinct orbits, and each orbit consists of two parities, each of which consists of 3 letters. And there are 12 different letters used in an arrangement.

      This Python program runs in 61ms. (Internal runtime is 703µs).

      Run: [ @replit ]

      from enigma import (update, union, disjoint_union, join, unpack, printf)
      
      # an orbit is an (<even>, <odd>) pair:
      empty = (set(), set())  # the empty orbit
      
      # possible index orders for a pair
      def orders(vs):
        yield (0, 1)
        if vs[0] != vs[1]: yield (1, 0)
      
      # add a word into an orbit
      def add(word, orbit):
        # collect the letters by even/odd parity
        ps = (set(word[0::2]), set(word[1::2]))
        # consider possible orderings to add the letters
        for (i0, i1) in orders(orbit):
          # construct new orbit
          orb = (union([orbit[0], ps[i0]]), union([orbit[1], ps[i1]]))
          # check orbit is valid
          if len(orb[0]) < 4 and len(orb[1]) < 4 and disjoint_union(orb):
            # return updated orbit
            yield orb
      
      # add a word into a pair of orbits
      def add_word(word, pair):
        # choose an orbit to add the word to
        for (i0, i1) in orders(pair):
          # attempt to add the word to the orbit
          for orb in add(word, pair[i0]):
            # check orbits are disjoint
            if disjoint_union(orb + pair[i1]):
              yield update(pair, [(i0, orb)])
      
      # find arrangements that spell out a word from each of the word lists <wss>
      def solve(wss, ws=[], orbs=(empty, empty)):
        # are we done?
        if not wss:
          yield (ws, orbs)
        else:
          # choose the next word
          for w in wss[0]:
            for orbs_ in add_word(w, orbs):
              yield from solve(wss[1:], ws + [w], orbs_)
      
      # word sets (with impossible words removed)
      words1 = "ADAM ALAN ANDY EDEN ERIC FRED GARY GLEN JOHN MIKE PETE TONY".split()
      words2 = "MONDAY FRIDAY SUNDAY".split()
      words3 = "MARCH APRIL MAY JUNE JULY AUGUST".split()
      
      # format an orbit (x, y)
      fmt = unpack(lambda x, y: join(sorted(x)) + "+" + join(sorted(y)))
      
      # solve the puzzle
      for (ws, orbs) in solve([words1, words2, words3]):
        # output solution
        printf("{ws} <- {orbs}", ws=join(ws, sep=" "), orbs=join(map(fmt, orbs), sep=", "))
      

      Solution: The words are: GLEN, FRIDAY, JUNE.

      The two orbits are:

      EGU + JLN → GLEN, JUNE
      AFI + DRY → FRIDAY

      From these we can construct many viable arrangements of letters. For example: E A J D G F L R U I N Y.

      Like

  • Unknown's avatar

    Jim Randell 3:06 pm on 27 October 2023 Permalink | Reply
    Tags:   

    Teaser 3188: Royal Mail slims down 

    From The Sunday Times, 29th October 2023 [link] [link]

    The Royal Mail, facing stiff competition, was looking for ways to streamline and simplify its operations. One dotty idea circulating in 2022 was to sell only two face values of postage stamps. Customers would then need to be able to make up 68p for a second-class letter and all values above 68p, to be ready for subsequent price rises. An obvious solution would be to sell only 1p and 68p stamps. But this would mean sticking 28 stamps on a first-class letter (costing 95p), leaving little room for the address!

    Which two stamp values would minimise the total number of stamps required to post two letters, one at 68p and one at 95p, and still allow any value above 68p to be made up?

    [teaser3188]

     
    • Jim Randell's avatar

      Jim Randell 3:23 pm on 27 October 2023 Permalink | Reply

      We have encountered similar puzzles before. (See: Enigma 1154, Enigma 1194, Enigma 228, Enigma 221, Enigma 122, Enigma 1635).

      For a pair of coprime denominations, the largest amount that cannot be expressed is known as the Frobenius number [@wikipedia], and can be calculated as:

      F(x, y) = x.y − (x + y)

      This Python program runs in 74ms. (Internal runtime is 10ms).

      Run: [ @replit ]

      from enigma import (Accumulator, coprime_pairs, express, printf)
      
      # calculate Frobenius number for coprime <x>, <y>
      F = lambda x, y: x * y - x - y
      
      # find minimal stamps to make total <t> with denominations <ds>
      stamps = lambda t, ds: min(express(t, ds), key=sum)
      
      # find minimal total
      r = Accumulator(fn=min, collect=1)
      
      # consider possible denominations
      for ds in coprime_pairs(68):
        # can we make 68p and all larger amounts?
        if F(*ds) > 67: continue
      
        # find minimal number of stamps used
        (q1, q2) = (stamps(68, ds), stamps(95, ds))
        r.accumulate_data(sum(q1) + sum(q2), ds)
      
      # output solution
      printf("denominations = {r.data} [{r.value} stamps]")
      

      Solution: The minimal number of stamps required is with denominations of 2p and 31p.

      With these denominations we can make the required amounts as:

      68p = 2× 31p + 3× 2p = 5 stamps
      95p = 3× 31p + 1× 2p = 4 stamps
      total = 9 stamps

      These denominations can make all values from 30p upwards.

      Like

  • Unknown's avatar

    Jim Randell 5:18 pm on 26 October 2023 Permalink | Reply
    Tags:   

    Teaser 2128: Goodbye, Norma Jean(e) 

    From The Sunday Times, 29th June 2003 [link]

     

    She was originally Norma Jean Baker, then she called herself Norma Jeane, before becoming the much-loved Marilyn Monroe. It is more than 40 years since she died and yet people still remember her fondly. Today we celebrate her life once again in the above addition sum, where each letter stands consistently for a different non-zero digit and O is prime.

    What is the numerical value of JAMBOREE?

    [teaser2128]

     
    • Jim Randell's avatar

      Jim Randell 5:18 pm on 26 October 2023 Permalink | Reply

      We can use the [[ SubstitutedExpression ]] solver from the enigma.py library to solve this puzzle.

      The following run file executes in 75ms. (Internal runtime of the generated code is 144µs).

      Run: [ @replit ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression.split_sum
      
      # digits are non-zero
      --invalid="0,ABEJKMNOR"
      # O is a single-digit prime = {2, 3, 5, 7}
      --invalid="1|4|6|8|9,O"
      
      "NORMA + JEAN = BAKER"
      
      --answer="JAMBOREE"
      

      Solution: JAMBOREE = 94735611.

      And the unencoded sum is:

      25674 + 9142 = 34816

      Like

  • Unknown's avatar

    Jim Randell 9:04 am on 24 October 2023 Permalink | Reply
    Tags:   

    Teaser 2664: Time ‘n’ again 

    From The Sunday Times, 13th October 2013 [link] [link]

    Time and again at school we would be given the exercise of changing a fraction into a decimal.

    This time the given fraction is in its simplest form and it equals a recurring decimal. In some places the digits have been consistently replaced by letters, with different letters used for different digits, but in four places the digits have merely been replaced by asterisks:

    TIME / **N** = .AGAINAGAIN

    Numerically, what is the TIME?

    [teaser2664]

     
    • Jim Randell's avatar

      Jim Randell 9:06 am on 24 October 2023 Permalink | Reply

      The fraction:

      TIME / **N**

      is in its lowest form, but may also be written:

      AGAIN / 99999

      So it follows that the numerator and denominator of the first fraction can be scaled up by an integer value (k) to give the numerator and denominator of second fraction.

      And k must be a 1-digit divisor of 99999.

      The only possible values are k=3 or k=9, meaning

      **N** = 33333
      **N** = 11111

      The following run file executes in 74ms. (Internal runtime of the generated program is 1.8ms).

      Run: [ @replit ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      --invalid="0,NT"
      --invalid="2|4|5|6|7|8|9,N"  # N is 1 or 3
      
      # TIME / NNNNN is in lowest terms
      "gcd(TIME, NNNNN) = 1"
      
      # TIME scales up to give AGAIN
      "div(N * AGAIN, 9) = TIME"
      
      --answer="TIME"
      

      Solution: TIME = 5269.

      And we have:

      TIME / **N** = .(AGAIN)… → 5269 / 11111 = 0.(47421)…

      Like

      • Hugo's avatar

        Hugo 1:36 pm on 24 October 2023 Permalink | Reply

        99999 = 3² × 41 × 271. 11111 = 41 × 271.
        41 is the smallest value of n such that multiples and submultiples of 1/n recur with period five.

        5269 = 11 × 479, and AGAIN = 47421 is 9 times as much.

        Like

c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel
Design a site like this with WordPress.com
Get started