Tagged: by: Harold Reiter Toggle Comment Threads | Keyboard Shortcuts

  • Unknown's avatar

    Jim Randell 9:10 am on 13 July 2023 Permalink | Reply
    Tags: by: Harold Reiter   

    Teaser 2192: Digital shuffle 

    From The Sunday Times, 19th September 2004 [link]

    I have tried rearranging the nine digits from one to nine into various expressions of the following form:

    What is the largest whole number answer that I can get?

    [teaser2192]

     
    • Jim Randell's avatar

      Jim Randell 9:11 am on 13 July 2023 Permalink | Reply

      This Python program runs in 94ms. Internal runtime is 30ms.

      Run: [ @replit ]

      from enigma import (Accumulator, irange, subsets, fraction, printf)
      
      # available digits
      digits = set(irange(1, 9))
      
      # find maximum configurations
      r = Accumulator(fn=max, collect=1)
      
      # choose the denominators R, T, V, X in increasing order
      for (R, T, V, X) in subsets(digits, size=4, select='C'):
        # allocate the numerators
        for (Q, S, U, W, Y) in subsets(digits.difference((R, T, V, X)), size=5, select='P'):
          # evaluate the expression
          (a, b) = fraction(Q, R,  S, T,  U, V,  W, X,  -Y, 1)
          if b == 1:
            r.accumulate_data(a, (Q, R, S, T, U, V, W, X, Y))
      
      # output solution(s)
      for (Q, R, S, T, U, V, W, X, Y) in r.data:
        printf("{Q}/{R} + {S}/{T} + {U}/{V} + {W}/{X} - {Y} = {r.value}")
      

      Solution: The largest possible answer is 12.

      9/1 + 7/2 + 8/3 + 5/6 − 4 = 12

      Like

    • Frits's avatar

      Frits 1:11 pm on 13 July 2023 Permalink | Reply

      #! python3 -m enigma -r
      
      SubstitutedExpression
      
      # Q/R + S/T + U/V + W/X - Y = AB
      "div(Q*T*V*X + R*S*V*X + R*T*U*X + R*T*V*W - R*T*V*X*Y, R*T*V*X) = AB"
      
      --answer="AB"
      --distinct="QRSTUVWXY"
      --accumulate=max
      --invalid="0,QRSTUVWXY"
      --verbose=16   
      

      Like

      • Frits's avatar

        Frits 1:20 pm on 13 July 2023 Permalink | Reply

        @Jim, is it possible to get a button like crayon on PuzzlingInPython?
        It makes it less error prone to post replies.

        Like

      • Jim Randell's avatar

        Jim Randell 2:02 pm on 13 July 2023 Permalink | Reply

        Requiring the denominators be ordered makes this approach run about 10× faster:

        Run: [ @replit ]

        #! python3 -m enigma -rr
        
        SubstitutedExpression
        
        --distinct="QRSTUVWXY"
        --invalid="0,QRSTUVWXY"
        --code="q = Rational()"
        
        "as_int(q(Q, R) + q(S, T) + q(U, V) + q(W, X) - Y) = AB"
        
        "R < T" "T < V" "V < X"
        
        --answer="AB"
        --accumulate="max"
        

        (Is “crayon” a WordPress plugin? I don’t think it is possible to install plugins on a free WordPress site. It looks like you need to pay £20/month to be able to do that).

        Like

      • Frits's avatar

        Frits 5:48 pm on 13 July 2023 Permalink | Reply

        Not using the fact that 5 and 7 can’t be used as denominators.

           
        from fractions import Fraction as RF
        
        # Q/R + S/T + U/V + W/X - Y = mx
        
        # available digits
        digits = set(range(1, 10))
        
        # maximum sum for <k> fractions choosing numbers from a sorted sequence <s> 
        def maxleft(s, k=4):
          assert len(s) >= 2 * k
          return int(sum([RF(s[-1 - x], s[x]) for x in range(k)]))
        
        # check if we can make total m of <k> fractions from digits in set <s> 
        def check(s, m, k=4, ns=[]):
          if k == 1:
            ls = list(s)
        
            if m in {RF(ls[0], ls[1]), RF(ls[1], ls[0])}:
              print("answer:", sum(RF(x[0], x[1]) for x in ns) + m - Y)
              print(f"we can make remaining fraction {m} with digits {s}, other "
                    f"fractions = {', '.join(str(x) + '/' + str(y) for x, y in ns)}")
              exit(0)
          else:
            # start with lowest denominators
            for d in (ss := sorted(s)):
              # ascending denominators
              if ns and d < ns[-1][1]: continue
              # start with highest numerators
              for n in ss[::-1]:
                if n != d:
                  yield from check(s.difference([n, d]), m - RF(n, d),
                                   k - 1, ns + [(n, d)])
        
        # build a descending list of maxima per Y
        M = sorted([(maxleft(sorted(digits.difference([Y]))) - Y, Y) 
                    for Y in range(1, 10)], reverse=1)
        
        inc = 0
        # keep checking until solution gets too low (-9)
        while True:
          cnt = 0
          # check Y's with the highest maximum first
          for (mx, Y) in M:
            if mx + Y - inc >= -8:
              cnt += 1
              # check if we can make total from eight remaining digits
              for c in check(digits.difference([Y]), mx + Y - inc):
                pass
                
          if not cnt: break     
          inc += 1  
        

        Like

    • GeoffR's avatar

      GeoffR 2:05 pm on 14 July 2023 Permalink | Reply

      I found two integer solutions for the equation for the largest whole number. The largest of the two integer solutions was 12.

      
      % A Solution in MiniZinc
      include "globals.mzn";
      
      var 1..9:Q; var 1..9:R; var 1..9:S; var 1..9:T;
      var 1..9:U; var 1..9:V; var 1..9:W; var 1..9:X;
      var 1..9:Y; 
      
      % Assumed LB for the sum is 1/9 + 2/8 + 3/7 + 4/6 - 5 = -3.54 (i.e  -4)
      % Assumed UB for the sum is 9/1 + 8/2 + 7/3 + 6/4 - 5 = 11.83 (i.e. 12)
      var -4..12:Z;   % Z = Q/R + S/T + U/V + W/X - Y
      
      constraint all_different( [Q, R, S, T, U, V, W, X, Y] );
      
      % Equation in integers only (for Z == Q/R + S/T + U/V + W/X - Y) is:
      constraint Z*R*T*V*X == Q*T*V*X + S*R*V*X + U*R*T*X + W*R*T*V - Y*R*T*V*X;
      
      solve maximize(Z);
      
      output [" Z = " ++ show(Z) ++ "\n" 
      ++ "[Q,R,S,T,U,V,W,X,Y,Z] = " ++ show( [Q,R,S,T,U,V,W,X,Y,Z] ) ];
      
      % Z = 11
      % [Q,R,S,T,U,V,W,X,Y,Z] = [6, 4, 9, 3, 7, 2, 8, 1, 5, 11]
      % ----------
      %  Z = 12
      % [Q,R,S,T,U,V,W,X,Y,Z] = [5, 6, 8, 3, 7, 2, 9, 1, 4, 12]
      % ----------
      % ==========
      
      

      Like

      • Frits's avatar

        Frits 3:10 pm on 14 July 2023 Permalink | Reply

        Highest rational number seems to be 12.95 (9/1 + 8/2 + 7/4 + 6/5 – 3) and
        -7.5381 (1/5 + 2/6 + 3/7 + 4/8 – 9) for the lowest.

        Like

  • Unknown's avatar

    Jim Randell 8:31 am on 5 July 2020 Permalink | Reply
    Tags: by: Harold Reiter   

    Brainteaser 1823: The special seven 

    From The Sunday Times, 24th August 1997 [link]

    A “special seven” fraction is one whose decimal expansion uses only 7s and/or 0s. So examples of special sevens are:

    0.7707
    0.70707070…

    which are the decimal expansions of:

    7707/10000
    70/99

    respectively.

    You can set yourself all sorts of tasks with the special sevens. For example, is it possible to find some which add up to 1? In fact this is possible in many different ways, but…

    … what is the smallest number of special sevens adding to 1?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1823]

     
    • Jim Randell's avatar

      Jim Randell 8:32 am on 5 July 2020 Permalink | Reply

      Each “special seven” number corresponds to a “special one” number, which can be derived by dividing by 7.

      So if we find a collection of special sevens that sum to 1, there is a corresponding set of special ones that sum to 1/7.

      The decimal expansion of 1/7 = 0.(142857)…

      Which if we write it as a sum of special ones will require at least 8 of them to construct the 8 digit.

      Solution: The smallest number of special sevens that sum to 1 is 8.


      We can construct a collection of 8 special ones that sum to 1/7 as follows:

      0.(000100)...  [h]
      0.(000101)...  [g] = [f]
      0.(000101)...  [f]
      0.(000111)...  [e]
      0.(010111)...  [d] = [c]
      0.(010111)...  [c]
      0.(011111)...  [b]
      0.(111111)...  [a]
      -------------
      0.(142857)...
      

      (This is not the only set, the 0’s and 1’s in each column can be re-ordered to give other sets, and there is no reason why each recurring section should use the same arrangement of columns).

      Writing these as fractions (from [a] to [h]) we have:

      [a] = 0.(111111)... = 111111/999999 = 1/9
      [b] = 0.(011111)... = 11111/999999
      [c] = 0.(010111)... = 10111/999999
      [d] = 0.(010111)... = 10111/999999
      [e] = 0.(000111)... = 111/999999 = 1/9009
      [f] = 0.(000101)... = 101/999999
      [g] = 0.(000101)... = 101/999999
      [h] = 0.(000100)... = 100/999999
      

      Which sum to: 142857/999999 = 1/7 as required.

      Multiplying these values by 7 gives us a set of 8 special sevens that sum to 1:

      [a] = 0.(777777)... = 777777/999999 = 7/9
      [b] = 0.(077777)... = 77777/999999
      [c] = 0.(070777)... = 70777/999999
      [d] = 0.(070777)... = 70777/999999
      [e] = 0.(000777)... = 777/999999 = 7/9009
      [f] = 0.(000707)... = 707/999999
      [g] = 0.(000707)... = 707/999999
      [h] = 0.(000700)... = 700/999999
      

      Like

  • Unknown's avatar

    Jim Randell 8:13 am on 10 March 2020 Permalink | Reply
    Tags: by: Harold Reiter   

    Brainteaser 1791: Untied problem 

    From The Sunday Times, 12th January 1997 [link]

    Here is an exact long division sum. In some places digits have been consistently replaced by letters, with different letters used for different digits. In all other places the digits have been replaced by asterisks.

    Untie this and find UNTIED.

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book and differs slightly from the original puzzle.

    [teaser1791]

     
    • Jim Randell's avatar

      Jim Randell 8:13 am on 10 March 2020 Permalink | Reply

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

      The following run file executes in 147ms.

      Run: [ @repl.it ]

      #!/usr/bin/env python -m enigma -r
      
      SubstitutedDivision
      
      "UNTIED / JIM = ADAM"
      
      "UNT - ??? = ??"
      "??? - ??? = ??"
      "??? - ??D = ??"
      "??? - ??? = 0"
      
      --answer="UNTIED"
      

      Solution: UNTIED = 986304.

      The correct division sum is: 986304 ÷ 132 = 7472.

      Like

    • GeoffR's avatar

      GeoffR 6:32 pm on 10 March 2020 Permalink | Reply

      
      from itertools import permutations
      
      for P in permutations('1234567890', 9):
          j, i, m, u, n, t, e, d, a = P
      
          # leading digits must not be zero
          if j == '0' or a =='0'or u == '0': continue
          jim = int(j + i + m)
          untied = int(u + n + t + i + e + d)
          adam = int(a + d + a + m)
          if jim * adam == untied:
              
              # check the lone 'D' position is correct
              if (int(a) * jim) % 10 == int(d):
                print (f"Sum is {untied} / {jim} = {adam}")
                
      # Sum is 986304 / 132 = 7472
      
      # There are only two solutions to the main division sum:
      # 986304 / 132 = 7472
      # and 785601 / 369 = 2129
      
      # Checking the lone 'D' digit position is enough to eliminate the
      # second solution ie 785601 / 369 =  2129. The last line of the
      # second solution also has 4 digits, instead of 3 digits.
      # It ran in 112 msec.
      
      
      

      Like

  • Unknown's avatar

    Jim Randell 11:50 am on 27 February 2020 Permalink | Reply
    Tags: by: Harold Reiter   

    Brainteaser 1785: Back to front 

    From The Sunday Times, 1st December 1996 [link]

    Given a row of eleven playing cards:

    [J] [10] [9] [8] [7] [6] [5] [4] [3] [2] [1]

    I wish to reverse the order to give:

    [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [J]

    To do this we are allowed at any stage to make a “move” of the following type:

    remove any section of adjacent cards from the pack and move them elsewhere.

    For example, one possible move from the starting position would be to take:

    [9] [8] [7]

    and move it to the right to give:

    [J] [10] [6] [5] [9] [8] [7] [4] [3] [2] [1]

    What is the minimum number of moves required to reverse them?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book and differs slightly from the original puzzle.

    [teaser1785]

     
    • Jim Randell's avatar

      Jim Randell 11:51 am on 27 February 2020 Permalink | Reply

      (See also: Puzzle #32).

      We can measure the “disorderedness” of a list by going through it and looking how each element compares to the next element. If it is less than the next element, then it is “ordered”. If it is greater than the next element, then it is “disordered”.

      Looking at the initial list we have:

      [11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

      which gives the following pairs:

      (11, 10) (10, 9) (9, 8) (8, 7) (7, 6) (6, 5) (5, 4) (4, 3) (3, 2) (2, 1)

      all of which are disordered, giving the initial list a score of 10.

      The target list is:

      [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

      which gives the following pairs:

      (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7) (7, 8) (8, 9) (9, 10) (10, 11)

      all of which are ordered, give the target list a score of 0.

      Suppose the list is:

      [? … a] [b … c] [d … e] [f … ?]

      And we move the [b … c] section to between e and f.

      Then we end up with

      [? … a] [d … e] [b … c] [f … ?]

      In the process we lose the adjacent pairs (a, b) (c, d) (e, f) and we gain the adjacent pairs (a, d) (e, b) (c, f).

      So the best improvement we could hope for is if the first three pairs are disordered, and the second three pairs are ordered, then we has reduced the disorderedness score by 3.

      For this to happen we need:

      a > b
      c > d
      e > f

      and:

      a < d
      e < b
      c < f

      We can write all six inequalities as the following chain:

      a < d < c < f < e < b < a

      So it is not possible for all the inequalities to hold simultaneously. So the best we can hope for in a move is to reduce the disorderedness score by 2.

      A similar argument holds if a block is moved to the left.

      Furthermore, if we consider the first move, we know the values a, b, c, d, e, f are in descending order. So the pairs (a, b), (c, d), (e, f) are disordered, and of the pairs (a, d) (e, b) (c, f) only (e, b) is ordered, so we can only reduce the disorderedness by 1 on the first move.

      Similarly, on the final move the list ends up correctly ordered, and a similar argument shows that we can only reduce the disorderedness by 1 on the final move.

      So, for a sequence of length 11, we start with a disorderedness score of 10, and to reduce this to a disorderedness score of 0 will require at least 6 moves (the score being reduced by 1+2+2+2+2+1 = 10). In general reversing a sequence of length n > 2 will require at least 1 + [n / 2] moves (where [x] denotes the integer part of x).

      But can we achieve a reversal in 6 moves?

      I wrote a program to try.

      The following program can be used to examine the behaviour of sequences up to length 9 in less than 7s (and length 10 takes 23 minutes). All of these were achievable with the expected minimum number of moves. Unfortunately we want to know about sequences of length 11 (which takes 93m).

      However, in my experiments with smaller sequences, I found that the minimal sequence found always had as an initial move, removing the two leftmost elements, and then re-inserting them at position (m − 1) // 2 (where m is the length of the original sequence).

      Using this as the first move reduces the run time for a length 10 sequence to 6s, and produces a solution of 6 moves for a length 11 sequence in just 29s.

      Run: [ @replit ]

      from enigma import (irange, inf, subsets, first, arg, printf)
      
      # start with a [1..m] list, reversed
      m = arg(9, 0, int)
      f = arg(1, 1, int)
      printf("[m={m}, f={f}]")
      
      # collect possible different moves
      move = dict()
      s = list(irange(0, m - 1))
      for (i, j) in subsets(irange(0, m - 1), size=2):
        for k in irange(1, m - j + i - 1):
          if k == i: continue
          r = s[i:j + 1]
          t = s[:i] + s[j + 1:]
          r = t[:k] + r + t[k:]
          if r not in move.values():
            move[(i, j, k)] = r
      
      # disorderedness score
      def score(s):
        r = 0
        a = None
        for b in s:
          if a is not None: r += (a > b)
          a = b
        return r
      
      # sort s in n (or fewer moves)
      def solve(s, n, d, ms=[]):
        # are we done?
        if d == 0:
          yield ms
        elif n > 0:
          # choose a move
          (diff1, diff2) = (list(), 0)
          for (m, v) in move.items():
            s1 = list(s[x] for x in v)
            d1 = score(s1)
            diff = d - d1
            if diff == 2:
              # try diff 2
              yield from solve(s1, n - 1, d1, ms + [m])
              diff2 += 1
            elif diff == 1:
              # save up diff 1
              diff1.append((s1, d1, m))
          # try any diff 1 moves
          if not diff2:
            for (s1, d1, m) in diff1:
              yield from solve(s1, n - 1, d1, ms + [m])
      
      s0 = list(irange(m, 1, step=-1))
      for n in irange(1 + m // 2, inf):
      
        # make an initial move...
        if f:
          m1 = (0, 1, (m - 1) // 2)
          s1 = list(s0[x] for x in move[m1])
          (s, n, ms) = (s1, n - 1, [m1])
        else:
          (s, ms) = (s0, [])
      
        ss = first(solve(s, n, score(s), ms), 1)
        for ms in ss:
          # output solution
          printf("n={n}: {ms}", n=len(ms))
          s = s0
          for (i, j, k) in ms:
            t = list(s[x] for x in move[(i, j, k)])
            printf("  [{i}, {j}] @ {k}: {s} -> {t} ({ss} -> {st})", ss=score(s), st=score(t))
            s = t
          printf()
        if ss: break
      

      Solution: The minimum number of moves required is 6.

      Here is one set of 6 moves that achieves the reversal:

      (Adjacent pairs that are ordered are linked with a hyphen).

      Like

    • Jim Randell's avatar

      Jim Randell 11:19 am on 1 March 2020 Permalink | Reply

      John Crabtree has come up with the following procedure to reverse a sequence using a minimal number of moves.

      The first move partitions the sequence into an ordered sequence (to the left) and a subsequence from which ordered pairs can be removed and inserted into the ordered sequence (to the right). The total number of moves required is 1 + [n / 2].

      Here is the procedure used to reverse a length 11 sequence in 6 moves:

      And here is the procedure encapsulated in a Python program:

      Run: [ @replit ]

      from enigma import (irange, tuples, arg, printf)
      
      # generate the moves to reverse a sequence of length n
      def reverse(n):
        if n < 3:
          if n == 2: yield (1, 1, 0)
          return
        (h, r) = divmod(n, 2)
        # 1st move
        yield (h + r, n - 1, r)
        # then move successive pairs into position
        for k in irange(0, h - 1):
          i = k + h + r - 1
          j = i + 1
          yield (i, j, k)
          
      
      # disorderedness score
      score = lambda s: sum(a > b for (a, b) in tuples(s, 2))
      
      # make a block move
      def move(s, i, j, k):
        r = s[i:j + 1]
        t = s[:i] + s[j + 1:]
        return t[:k] + r + t[k:]
      
      n = arg(11, 0, int)
      
      # collect the moves
      ms = list(reverse(n))
      printf("[n={n}, {m} moves]", m=len(ms))
      s = list(irange(n, 1, step=-1))
      for (i, j, k) in ms:
        t = move(s, i, j, k)
        printf("  [{i}, {j}] @ {k}: {s} -> {t} ({ss} -> {st})", ss=score(s), st=score(t))
        s = t
      printf()
      

      Like

    • Lise Andreasen's avatar

      Lise Andreasen 2:01 am on 18 October 2024 Permalink | Reply

      Very nice analysis!

      Liked by 1 person

  • Unknown's avatar

    Jim Randell 5:04 pm on 29 September 2019 Permalink | Reply
    Tags: by: Harold Reiter   

    Brainteaser 1721: Prime leaps 

    From The Sunday Times, 10th September 1995 [link]

    The history-cum-maths teacher asked the class to name some years which the knew from history lessons. Johnny named 1066, the Battle of Hastings, and 1939, the outbreak of the Second World War. The teacher then asked him to calculate the difference between the two and Johnny got the correct answer of 873.

    The teacher then asked Johnny if this difference was prime and Johnny answered correctly that it was not because, for example, it was divisible by three.

    The teacher then asked the class to find the longest list of years they could from 0, 1, 2, …, 1999, 2000 so that for any two numbers in the list their difference was not prime.

    Which numbers are in the longest such list?

    This puzzle is included in the book Brainteasers (2002). The puzzle text above is taken from the book.

    [teaser1721]

     
    • Jim Randell's avatar

      Jim Randell 5:05 pm on 29 September 2019 Permalink | Reply

      First, lets treat the list as a sequence of consecutive integers starting at 0. (We’re only interested in differences, so it doesn’t really matter where we start).

      If we consider the set of numbers (0, 4, 8, 12, 16, …) (i.e. the multiples of 4) then we see the difference between any two numbers is also a multiple of 4, and hence not prime. This allows us to select ⌈n / 4⌉ numbers from a sequence of n numbers.

      And this is the best we can manage. Every segment of size 4 has 1 number (and if there is a shorter segment left over from chopping the sequence into fours, then that also has one number).

      To do better we would have to have a segment of size 4 with (at least) two numbers in it.

      We can’t have … 0 _ 2 _ … or … 0 _ _ 3 … as these have a difference of 2 and 3 respectively, so the only possible segment is … 0 1 _ _ ….

      But any numbers that differ by 1 have to be followed by (or preceded by) 7 gaps:

      So the best we could manage is 2 numbers out of every 9, which is worse than 1 out of every 4.

      So presented with a sequence of 2001 numbers the best we can manage is ⌈2001 / 4⌉ = 501 numbers: (0, 4, 8, 12, 16, …, 1992, 1996, 2000).

      Solution: The longest list contains all exact multiples of 4.

      Considered as years (ignoring the fact that there was no year 0), most of the numbers represent leap years, hence the title of the puzzle.

      Like

    • Lise Andreasen's avatar

      Lise Andreasen 12:18 pm on 5 August 2024 Permalink | Reply

      Elegant.

      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