Updates from April, 2019 Toggle Comment Threads | Keyboard Shortcuts

  • Unknown's avatar

    Jim Randell 8:57 am on 1 April 2019 Permalink | Reply
    Tags:   

    Teaser 2928: Golf balls 

    From The Sunday Times, 4th November 2018 [link] [link]

    Three friends play 18 holes of golf together every week. They have a large supply of golf balls numbered from 1 to 5. At the beginning of a year, they each start playing with a new ball, but all three ball numbers are different. Alf uses the same ball number for exactly 21 holes before changing to the next higher number (or to number 1 if he was using a number 5). He continues to use each number for exactly 21 holes. The same applies to Bert, except that he changes his ball number in the same way after every 22 holes, and to Charlie who changes his ball number after every 23 holes.

    Last year, there was just one occasion when they all used the same ball number on a hole.

    What was the number of the hole on that occasion?

    [teaser2928]

     
    • Jim Randell's avatar

      Jim Randell 8:59 am on 1 April 2019 Permalink | Reply

      This Python program finds the solution constructively in 79ms.

      Run: [ @replit ]

      from enigma import (irange, subsets, singleton, printf)
      
      # increment ball count, and ball if necessary
      def inc(i, x, X):
        i += 1
        if i == X:
          x = (1 if x == 5 else x + 1)
          i = 0
        return (i, x)
      
      # find (week, hole) pairs
      def solve(A, B, C, a, b, c, n):
        i = j = k = 0
        # consider number of weeks
        for w in irange(1, n):
          # and each hole
          for h in irange(1, 18):
            if a == b == c:
              yield (w, h, b)
            # increment ball counters
            (i, a) = inc(i, a, A)
            (j, b) = inc(j, b, B)
            (k, c) = inc(k, c, C)
      
      # choose starting balls for A, B, C
      # suppose A's ball is 1, we only have to choose B and C
      a = 1
      for (b, c) in subsets((2, 3, 4, 5), size=2, select='P'):
        # in 2017 there were 52 whole weeks, + 1 extra Sunday
        rs = singleton(solve(21, 22, 23, a, b, c, 53))
        if rs:
          (w, h, x) = rs
          printf("a={a} b={b} c={c}: week={w}, hole={h}, ball={x}")
      

      Solution: Hole number 10.

      It would happen on week number 53.

      Like

  • Unknown's avatar

    Jim Randell 8:10 am on 31 March 2019 Permalink | Reply
    Tags:   

    Teaser 2949: Mystery numbers 

    From The Sunday Times, 31st March 2019 [link] [link]

    I wrote down a 2-digit number and a 5-digit number and then carried out a long division.

    I then erased all of the digits in the calculation, other than one of them, which I have indicated by X.

    This gave me the image above.

    What were my two original numbers?

    [teaser2949]

     
    • Jim Randell's avatar

      Jim Randell 8:15 am on 31 March 2019 Permalink | Reply

      We can feed this problem directly to the [[ SubstitutedDivision() ]] solver from the enigma.py library.

      This run file executes in 153ms.

      Run: [ @repl.it ]

      #! python -m enigma -rr
      
      SubstitutedDivision
      
      "XX??X / ?X = ????"
      
      "XX - ?X = ??"
      "??? - ?? = ??"
      "??? - ?X? = ?"
      "?X - ?X = 0"
      

      Solution: The two original numbers were: 23 and 33603.

      Like

      • Jim Randell's avatar

        Jim Randell 4:32 pm on 31 March 2019 Permalink | Reply

        Although the run file given above does find the correct answer, which can be verified by inspection. I think there is a little bit more work to do to ensure that the erased digits are all different from the digit X.

        Here is a run file that uses symbols for the erased digits (instead of the wildcard “?”), and includes an extra check to make sure they are all different from X.

        #! python -m enigma -rr
        
        #          D E F G
        #      -----------
        #  C X ) X X A B X
        #        H X
        #        ---
        #        I J A
        #          K M
        #        -----
        #          N P B
        #          Q X R
        #          -----
        #              S X
        #              S X
        #              ===
        
        SubstitutedDivision
        
        "XXABX / CX = DEFG"
        
        "XX - HX = IJ"
        "IJA - KM = NP"
        "NPB - QXR = S"
        "SX - SX = 0"
        
        --distinct="XA,XB,XC,XD,XE,XF,XG,XH,XI,XJ,XK,XM,XN,XP,XQ,XR,XS"
        

        Like

    • GeoffR's avatar

      GeoffR 12:34 pm on 21 April 2019 Permalink | Reply

      % A Solution in MiniZinc  
      include "globals.mzn";
      
      %           D E F G
      %       -----------
      %   C X ) X X A B X
      %         H X
      %         ---
      %         I J A
      %           K M
      %         -----
      %           N P B
      %           Q X R
      %           -----
      %               S X
      %               S X
      %               ===
      
      var 0..9:A; var 0..9:B; var 0..9:C; var 0..9:D; var 0..9:E;
      var 0..9:F; var 0..9:G; var 0..9:H; var 0..9:I; var 0..9:J;
      var 0..9:K; var 0..9:M; var 0..9:N; var 0..9:P; var 0..9:Q;
      var 0..9:R; var 0..9:S; var 0..9:X; 
      
      constraint D > 0 /\ C > 0 /\ X > 0 /\ I > 0 /\ K > 0 
      /\ N > 0 /\ Q > 0 /\ S > 0;
      
      var 10..99: XX = 11*X;
      var 10..99: HX = 10*H + X;
      
      var 10..99: CX = 10*C + X;
      var 10..99: KM = 10*K + M;
      var 10..99: IJ = 10*I + J;
      var 10..99: NP = 10*N + P;
      var 10..99: SX = 10*S + X;
      
      var 100..999: XXA = 110*X + A;
      var 100..999: IJA = 100*I + 10*J + A;
      var 100..999: NPB = 100*N + 10*P + B;
      var 100..999: QXR = 100*Q + 10*X + R;
      
      var 1000..9999: DEFG = 1000*D + 100*E + 10*F + G;
      var 10000..99999: XXABX = 11001*X + 100*A + 10*B;
      
      % main sum
      constraint CX * DEFG == XXABX;
      
      % partial products and subtractions
      constraint D * CX == HX /\ XX - HX == IJ;
      
      constraint E * CX == KM /\ IJA - KM == NP;
      
      constraint F * CX == QXR /\ NPB - QXR == S;
      
      constraint G * CX == SX;
      
      solve satisfy;
       
      % A = 6; B = 0; C = 2; D = 1; E = 4; F = 6; G = 1;
      % H = 2; I = 1; J = 0; K = 9; M = 2; N = 1; P = 4;
      % Q = 1; R = 8; S = 2; X = 3;
      % ----------
      % ==========
      % Finished in 271msec
      
      % The only full division sum is :
      
      %        1 4 6 1
      %     -----------     
      %  2 3)3 3 6 0 3
      %      2 3
      %      ---
      %      1 0 6
      %        9 2
      %      -----
      %        1 4 0
      %        1 3 8
      %        -----
      %            2 3
      %            2 3
      %            ===     
      % My two original numbers were therefore 23 and 33603.
      

      Like

  • Unknown's avatar

    Jim Randell 7:10 am on 30 March 2019 Permalink | Reply
    Tags:   

    Brainteaser 1510: Sum puzzle 

    From The Sunday Times, 18th August 1991 [link]

    In this addition sum nine digits are each represented by a different letter and the remaining one digit it represented in various places by nine letters.

    When the 47-figure number:

    INTHISADDITIONSUMNINEDIGITSAREEACHREPRESENTEDBY

    is added to the 46-digit number:

    ONELETTERANDONEDIGITISREPRESENTEDBYNINELETTERS

    the answer is the 47-figure number:

    TDODRRITECIPADAABSDLOTRSORANOHMIAGSAOTUDAYDOEOE

    What is the SOLUTION?

    The text of this puzzle is taken from the book Brainteasers (2002), so may differ from the originally published puzzle.

    [teaser1510]

     
    • Jim Randell's avatar

      Jim Randell 7:11 am on 30 March 2019 Permalink | Reply

      Potentially we could just feed the entire sum as a single expression to the [[ SubstitutedExpression() ]] solver from the enigma.py library, but generating and considering all the possibilities for the 15 digits in the terms of the sum is going to take some time.

      So to help it along I provided some additional expressions, which are the sums formed taking some of the columns (in pairs, to reduce the amount of typing), linked together by carries. After 9 pairs we have mentioned each letter at least once, and the solver finds the solution in less than 200ms.

      This run-file executes in 183ms.

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --distinct=""
      --answer="SOLUTION"
      
      # use lowercase symbols for carries
      --symbols="ABCDEGHILMNOPRSTUYabcdefghi"
      --invalid="0,IOT"
      --invalid="2-9,abcdefghi"
      
      # neaten up the output
      --template=""
      --solution="ABCDEGHILMNOPRSTUY"
      
      # the entire sum
      "INTHISADDITIONSUMNINEDIGITSAREEACHREPRESENTEDBY + ONELETTERANDONEDIGITISREPRESENTEDBYNINELETTERS = TDODRRITECIPADAABSDLOTRSORANOHMIAGSAOTUDAYDOEOE"
      
      # verify the digit count in the solution
      --code="v = lambda ds: sorted(ds.count(d) for d in irange(0, 9))"
      
      "v([A, B, C, D, E, G, H, I, L, M, N, O, P, R, S, T, U, Y]) == [1, 1, 1, 1, 1, 1, 1, 1, 1, 9]"
      
      # to speed things up we break down the sum in a sequence of partial
      # sums starting from the rightmost column (in groups of 2)
      "BY + RS + 0 = aOE"
      "ED + TE + a = bOE"
      "NT + ET + b = cYD"
      "SE + EL + c = dDA"
      "RE + IN + d = eTU"
      "EP + YN + e = fAO"
      "HR + DB + f = gGS"
      "AC + TE + g = hIA"
      "EE + EN + h = iHM"
      # by this stage we have used all the letters at least once
      

      Solution: SOLUTION = 78665482

      The assignment of letters to digits is:

      A=9 D=0 E=3 I=4 N=2 O=8 R=1 S=7 T=5; {BCGHLMPUY}=6

      so the sum is:

        42564790045482766242304645791339661361373253066
      +  8236355319208230464547136137325306624236355317
        -----------------------------------------------
      = 50801145364690996706851781928664967985609608383
        ===============================================
      

      This is the only solution, even if the 18 symbols are grouped together differently (i.e. not 9 symbols standing for 1 digit each, and 9 all standing for the same remaining digit).

      Like

      • Jim Randell's avatar

        Jim Randell 3:50 pm on 27 April 2023 Permalink | Reply

        Instead of splitting the sum manually we can use the [[ SubstitutedExpression.split_sum ]] solver from the enigma.py library to do it for us.

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

        #! python3 -m enigma -rr
        
        SubstitutedExpression.split_sum
        
        --distinct=""
        --invalid="0,IOT"
        --answer="SOLUTION"
        --split=4
        
        # the entire sum
        "INTHISADDITIONSUMNINEDIGITSAREEACHREPRESENTEDBY + ONELETTERANDONEDIGITISREPRESENTEDBYNINELETTERS = TDODRRITECIPADAABSDLOTRSORANOHMIAGSAOTUDAYDOEOE"
        
        # verify the digit count in the solution (9 digits have 1 symbol, 1 digit has 9 symbols)
        --code="check = lambda ds: multiset.from_seq(ds.count(d) for d in irange(0, 9)) == {1: 9, 9: 1}"
        --extra="check([A, B, C, D, E, G, H, I, L, M, N, O, P, R, S, T, U, Y])"
        
        # neaten up the output
        --template=""
        

        Like

  • Unknown's avatar

    Jim Randell 7:44 am on 29 March 2019 Permalink | Reply
    Tags:   

    Teaser 2929: My PIN numbers 

    From The Sunday Times, 11th November 2018 [link] [link]

    Using all but one of the digits 0 to 9, and systematically replacing them by a letter, my PIN numbers become ONE, TWO, FIVE and SEVEN.

    These numbers are such that:

    ONE is odd;
    TWO is even;
    FIVE is odd and divisible by 5;
    SEVEN is divisible by 7;
    ONE + TWO + TWO = FIVE

    If I told you which digit was not used, you should be able to work out my PIN numbers.

    What PIN number is represented by SEVEN?

    [teaser2929]

     
    • Jim Randell's avatar

      Jim Randell 7:45 am on 29 March 2019 Permalink | Reply

      This Python program links together a couple of routines from the enigma.py library. First we use the [[ SubstitutedExpression() ]] solver to find solutions to the alphametic expressions, then use use the [[ filter_unique() ]] function to select solutions that have a unique unused digit.

      It runs in 90ms.

      Run: [ @replit ]

      from enigma import (SubstitutedExpression, filter_unique, unpack, printf)
      
      # the conditions
      p = SubstitutedExpression(
        [
          "ONE % 2 = 1",
          "TWO % 2 = 0",
          "FIVE % 10 = 5",
          "SEVEN % 7 = 0",
          "ONE + TWO + TWO = FIVE",
        ],
        # X is the unused digit
        answer="(X, ONE, TWO, FIVE, SEVEN)",
        # leading zeros are allowed
        d2i={},
        # [optional] output the individual solutions to the conditions
        template="[X={X}, ONE={ONE} TWO={TWO} FIVE={FIVE} SEVEN={SEVEN}]",
        header="",
        solution="",
      )
      
      # find solutions unique by X
      rs = filter_unique(p.answers(), unpack(lambda x, p1, p2, p5, p7: x)).unique
      
      # output solutions
      for (x, p1, p2, p5, p7) in rs:
        printf("unused={x} -> ONE={p1:03d} TWO={p2:03d} FIVE={p5:04d} SEVEN={p7:05d}")
      

      Solution: SEVEN = 95452.

      Like

    • GeoffR's avatar

      GeoffR 4:11 pm on 29 March 2019 Permalink | Reply

      This programme finds four answers, three of which have the same unused digit 4, whilst the last answer has the unique unused digit 3, which gives the answer ie SEVEN = 95452

      
      % A Solution in MiniZinc
      include "globals.mzn";
      
      enum letters = {O, N, E, T, W, F, I, V, S};  
      array [letters] of var 0..9: v;
      
      constraint all_different(v);
      
      % ONE is odd
      constraint (100*v[O] + 10*v[N] + v[E]) mod 2 == 1;
      
      % TWO is even
      constraint (100*v[T]  + 10*v[W] + v[O] ) mod 2 == 0;
      
      % FIVE is odd and divisible by 5
      constraint (1000*v[F] + 100*v[I] + 10*v[V] + v[E]) mod 2 == 1 
      /\ (1000*v[F] + 100*v[I] + 10*v[V] + v[E]) mod 5 == 0;
      
      % ONE + TWO + TWO = FIVE
      constraint (100*v[O] + 10*v[N] + v[E]) + 2 * (100*v[T] + 10*v[W]
       + v[O] ) == (1000*v[F] + 100*v[I] + 10*v[V] + v[E]);
      
      % SEVEN is divisible by 7
      constraint (10000*v[S] + 1000*v[E] + 100*v[V] + 10*v[E]
       + v[N]) mod 7 == 0; 
      
      % Set of all ten digits
      var set of int: s1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
      
      % Set of digits used in the solution
      var set of int: s2 = {v[O], v[N], v[E], v[T], v[W],
       v[F], v[I], v[V], v[S]};
       
      % The unused digit
      var set of int: s3 == s1 diff s2;  
      
      solve satisfy;
      
      output [" ONE = " ++ show(v[O]), show(v[N]), show(v[E])]
      ++ ["  TWO = " ++ show(v[T]), show(v[W]), show(v[O])]
      ++ ["  FIVE = " ++ show(v[F]), show(v[I]), show(v[V]), show(v[E])]
      ++ ["\n SEVEN = " ++ show(v[S]),show(v[E]),show(v[V]),show(v[E]),show(v[N]) 
      ++ " - unused digit set: " ++ show(s3) ];
      
      %  ONE = 035  TWO = 820  FIVE = 1675  
      %  SEVEN = 95753 - unused digit set: 4..4
      %-----------------------------------------
      %  ONE = 095  TWO = 820  FIVE = 1735  
      %  SEVEN = 65359 - unused digit set: 4..4
      % -----------------------------------------
      %  ONE = 065  TWO = 830  FIVE = 1725  
      %  SEVEN = 95256 - unused digit set: 4..4
      %  ----------------------------------------
      %  ONE = 025  TWO = 860  FIVE = 1745 
      %  SEVEN = 95452 - unused digit set: 3..3 <<< answer
      % ----------
      % ==========
      % Finished in 234msec
      
      

      Like

  • Unknown's avatar

    Jim Randell 7:48 am on 28 March 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 467: [Registration numbers] 

    From The Sunday Times, 10th May 1970 [link]

    There was a christening at our house last Sunday and there were three visitors’ cars in the drive.

    The car registration numbers of these three cars (disregarding any letters) each a three-digit prime number and among these numbers each of the digits 1 to 9 was used once only.

    This in itself was quite remarkable, but the sum of there three three-digit primes gave the three digit registration number of my own car.

    What were the three registration numbers of the visitors’ cars?

    This puzzle was originally published with no title.

    [teaser467]

     
    • Jim Randell's avatar

      Jim Randell 7:49 am on 28 March 2019 Permalink | Reply

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

      This run-file executes in 82ms.

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --digits="1-9"
      --answer="(ABC, DEF, GHI)"
      
      # the three 3-digit primes
      "is_prime(ABC)"
      "is_prime(DEF)"
      "is_prime(GHI)"
      
      # their sum is also a 3-digit number
      "ABC + DEF + GHI < 1000"
      
      # put them in order
      "ABC < DEF < GHI"
      

      Solution: The registration numbers are: 149, 263, 587.

      So, the setters registration number is 999.

      Like

    • GeoffR's avatar

      GeoffR 4:00 pm on 28 March 2019 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
      
      enum letters = {A, B, C, D, E, F, G, H, I};   
      array [letters] of var 1..9: v;
      
      constraint all_different (v);
      
      predicate is_prime(var int: x) = 
      x > 1 /\ forall(i in 2..1 + ceil(sqrt(int2float(ub(x))))) ((i < x) -> (x mod i > 0));
      
      var 100..999: ABC = 100*v[A] + 10*v[B] + v[C];
      var 100..999: DEF = 100*v[D] + 10*v[E] + v[F];
      var 100..999: GHI = 100*v[G] + 10*v[H] + v[I];
      var 100..999: XYZ;    % my car registration number
      
      constraint ABC + DEF + GHI == XYZ /\ GHI > DEF /\ DEF > ABC;
      
      constraint is_prime(ABC) /\ is_prime(DEF) /\ is_prime(GHI);
      
      solve satisfy;
      
      output[ "The three registration numbers of the visitors’ cars were " ++ show(ABC) 
      ++ ", " ++ show(DEF) ++ " and " ++ show(GHI) ]; 
      
      % The three registration numbers of the visitors’ cars were 149, 263 and 587
      
      
      

      Like

  • Unknown's avatar

    Jim Randell 7:04 am on 27 March 2019 Permalink | Reply
    Tags:   

    Teaser 2905: Trackword 

    From The Sunday Times, 27th May 2018 [link]

    George and Martha are tackling a Trackword problem which appears in magazines. Nine letters are placed in a 3×3 grid and you have to work from one square to a neighbour, proceeding up, down, left, right or diagonally until all nine squares have been visited to form a nine-letter word. You must start in the top-left corner. As an example, you can get the word EIGHTFOLD from the following grid:

    George and Martha thought that would be interesting to work out how many possible routes there are which start in the top-left corner.

    How many routes are there?

    [teaser2905]

     
    • Jim Randell's avatar

      Jim Randell 7:05 am on 27 March 2019 Permalink | Reply

      (See also: Grid Puzzle)

      There’s a handy [[ grid_adjacency() ]] function in the enigma.py library to compute the adjacency matrix on a square grid.

      This Python program can be used to calculate the number of paths on an m×n grid. For the 3×3 grid it runs in 81ms.

      from enigma import (grid_adjacency, icount, arg, printf)
      
      # consider an m x n grid
      m = arg(3, 0, int)
      n = arg(m, 1, int)
      
      # adjacency matrix
      adj = grid_adjacency(m, n, include_diagonal=1)
      
      # generate paths with k additional steps, prefix p, visiting different squares
      def paths(k, p):
        # are we done?
        if k == 0:
          yield p
        else:
          # extend the path
          for x in adj[p[-1]]:
            if x not in p:
              yield from paths(k - 1, p + [x])
      
      # count maximal length paths that start at square 0
      k = m * n - 1
      t = icount(paths(k, [0]))
      printf("[{m}x{n}] total paths = {t}")
      

      Solution: There are 138 different possible routes.

      From square 0 we can go to to the central square (4) or to an edge square (1 or 3), so we can just count the paths with prefix [0, 4] and [0, 1]. There will be the same number of paths with prefix [0, 3] as there are with prefix [0, 1].

      >>> icount(paths(7, [0, 4])) + 2 * icount(paths(7, [0, 1]))
      138
      

      Like

  • Unknown's avatar

    Jim Randell 7:01 am on 26 March 2019 Permalink | Reply
    Tags:   

    Brainteaser 1505: Waste not … 

    From The Sunday Times, 14th July 1991 [link]

    The “tangram” is an ancient Chinese puzzle. It consists of seven pieces which can be formed into a square (as shown) and into many other artistic shapes.

    The middle-sized triangle, the square and the parallelogram are all twice the area of the smaller triangles, and half the area of the larger ones. All the angles are 45, 90 or 135 degrees. And in my version the lengths of the shorter sides of the largest triangles are 7 cm.

    I have a thin rectangular sheet of card 70 cm by 91 cm from which I wish to cut as many such sets of tangrams as possible with the minimum amount of wastage.

    How many complete sets can I make?

    The text of this puzzle is taken from the book Brainteasers (2002), so may differ from the puzzle originally published in the newspaper.

    [teaser1505]

     
    • Jim Randell's avatar

      Jim Randell 7:03 am on 26 March 2019 Permalink | Reply

      The Tangram square shown, has sides measuring 7√2 cm. Which gives it an area of 98 cm².

      The 70 cm × 91 cm piece of card has an area of 6370 cm².

      So there is potentially enough card to make 65 complete sets with no wastage.

      However the square shown does will not fit into the length or width of the card an exact number of times.

      My solution is cut the card into 7 cm × 7 cm squares. This divides the card into 10 × 13 = 130 squares.

      We then rearrange the Tangram into two squares:

      These squares also measure 7 cm × 7cm.

      So, we then cut 65 of the squares using pattern A, and the remaining 65 sets using pattern B, giving us 65 complete Tangram sets.

      Solution: We can make 65 sets, with no wastage.

      Like

    • Lise Andreasen's avatar

      Lise Andreasen 7:28 am on 19 April 2024 Permalink | Reply

      Neat.

      Like

  • Unknown's avatar

    Jim Randell 8:40 am on 25 March 2019 Permalink | Reply
    Tags:   

    Teaser 2930: Odd socks 

    From The Sunday Times, 18th November 2018 [link] [link]

    I had a drawer containing some black socks and some white socks. If I drew out two socks at random the chance of getting a black pair was 1 in __.

    After many washes all the socks looked grey. So I added some red socks to the drawer. Then if I drew out two at random the chance of getting a grey pair was 1 in __.

    After many washes all the socks looked pink. So I added some green socks to the drawer. Then if I drew out two the chance of getting a pink pair was 1 in __.

    After many washes all the socks looked brown. So I have now added some yellow socks to the drawer giving me a total of fewer than fifty socks. Now if I draw out two the chance of getting a brown pair is 1 in __.

    The gaps above consist of four different prime numbers.

    If I draw out two socks at random, what is the chance of getting a yellow pair?

    [teaser2930]

     
    • Jim Randell's avatar

      Jim Randell 8:41 am on 25 March 2019 Permalink | Reply

      This Python 3 program works by finding possible (prime, X, Y) tuples for choosing a pair of X socks from X+Y, and then links together the appropriate number of tuples to solve the puzzle.

      It runs in 75ms.

      Run: [ @replit ]

      from enigma import (irange, is_prime, fraction, printf)
      
      # min and max
      (m, M) = (2, 49)
      
      # find primes of the form (X + Y)(X + Y - 1) / X(X - 1)
      # where X + Y =< M and X >= m, Y >= m
      rs = list()
      for X in irange(max(m, 2), M - m):
        for Y in irange(m, M - X):
          (p, r) = divmod((X + Y) * (X + Y - 1), X * (X - 1))
          if not (r == 0 and is_prime(p)): continue
          rs.append((p, X, Y))
      
      # solve for k steps
      def solve(k, ns=None, ps=None):
        # are we done?
        if k == 0:
          yield (ns, ps)
        else:
          if not ns:
            # first step, use both X and Y
            for (p, X, Y) in rs:
              yield from solve(k - 1, [X, Y], [p])
          else:
            # subsequent steps match sum on X
            T = sum(ns)
            for (p, X, Y) in rs:
              if X == T and p not in ps:
                yield from solve(k - 1,  ns + [Y], ps + [p])
      
      # find a sequence of 4 primes
      for ((B, W, R, G, Y), (p1, p2, p3, p4)) in solve(4):
        # calculate the probability of a yellow pair
        T = B + W + R + G + Y
        (a, b) = fraction(Y * (Y - 1), T * (T - 1))
        # output solution
        printf("P(yellow) = {a}/{b} [B={B} W={W}, p1={p1}; R={R} p2={p2}; G={G} p3={p3}; Y={Y} p4={p4}; T={T}]")
      

      Solution: There is a 1 in 6 chance of getting a yellow pair.

      There are two scenarios which give the answer:

      From 3 black and 3 white, the probability a black pair is 1/5.
      From 6 grey and 9 red, the probability of a grey pair is 1/7.
      From 15 pink and 6 green, the probability of a pink pair is 1/2.
      From 21 brown and 15 yellow, the probability of a brown pair is 1/3.

      From 3 black and 4 white, the probability a black pair is 1/7.
      From 7 grey and 8 red, the probability of a grey pair is 1/5.
      From 15 pink and 6 green, the probability of a pink pair is 1/2.
      From 21 brown and 15 yellow, the probability of a brown pair is 1/3.

      But in both cases the probability of a yellow pair (from 21 brown and 15 yellow) is 1/6.

      In the puzzle I interpreted “some” to mean “at least 2”, and this gives the solution above. However, if we interpret it as “at least 1” then you get 2 further solutions, which give an answer of 1/14. (You can change the value of [[ m ]] to [[ 1 ]] in the program to see this).

      Interestingly there are no solutions (even with the relaxation of “some”) where all the numbers of different coloured socks are all even. Which certainly is an “odd” way to acquire socks.

      Like

  • Unknown's avatar

    Jim Randell 6:36 am on 24 March 2019 Permalink | Reply
    Tags:   

    Teaser 2948: A hardy annual 

    From The Sunday Times, 24th March 2019 [link] [link]

    Yesterday was my grandson’s birthday and we continued a family tradition. I asked him to use any eight different non-zero digits (once each) to form a set of numbers that added to 2019. Last year I asked the equivalent question with a sum of 2018, and I have done this each year for over ten years. Only on one occasion has he been unable to complete the task.

    In this year’s answer his set of numbers included a 3-figure prime that had also featured in last year’s numbers.

    (a) In which year was he unable to complete the task?

    (b) What was the 3-figure prime that featured in this year’s answer?

    [teaser2948]

     
    • Jim Randell's avatar

      Jim Randell 7:48 am on 24 March 2019 Permalink | Reply

      I assumed the numbers are formed only by concatenation of digits, and not any other method.

      This Python program considers the number of digits present in each column of the sum to construct viable solutions.

      It runs in 84ms.

      Run: [ @repl.it ]

      from itertools import (combinations, product)
      from enigma import (nsplit, irange, nconcat, is_prime, printf)
      
      # different ways to construct the sum (for the years under consideration)
      # (number of digits in each column)
      exprs = [ (1, 2, 2, 3), (1, 1, 3, 3), (1, 1, 2, 4), (1, 1, 1, 5) ]
      
      # solve for the end column
      def _solve(ds, expr, digits, c, ss):
        # are we done?
        if not ds:
          # check there is no carry
          if c == 0:
            yield ss
        else:
          # consider digits for this columns
          for s in combinations(digits, expr[-1]):
            (c1, r) = divmod(sum(s) + c, 10)
            # check the sum matches the desired result
            if r == ds[-1]:
              # solve for the remaining columns
              yield from _solve(ds[:-1], expr[:-1], digits.difference(s), c1, [s] + ss)
      
      # find solutions for result n
      # return (<construction>, <digits>)
      def solve(n):
      
        # split the result into digits
        ds = nsplit(n)
      
        # digits to use (can remove (9 - digrt(n)))
        digits = set(irange(1, 9))
      
        # try to solve for each construction
        for expr in exprs:
          for ss in _solve(ds, expr, digits, 0, []):
            yield (expr, ss)
      
      # return 3-digit primes involved in solutions
      def collect(ss):
        r = set()
        for (expr, s) in ss:
          if expr != (1, 2, 2, 3): continue
          for ds in product(s[1], s[2], s[3]):
            n = nconcat(ds)
            if is_prime(n):
              r.add(n)
        return r
      
      # there must be a non-viable year in the last 11 years
      for n in irange(2019, 2009, step=-1):
        ss = list(solve(n))
      
        # are there any solutions?
        if not ss:
          printf("(a) {n} has no viable solutions")
          break
      
        if n == 2019:
          ps2019 = collect(ss)
      
        if n == 2018:
          ps2018 = collect(ss)
          ps = ps2018.intersection(ps2019)
          printf("(b) primes = {ps}")
      

      Solution: (a) 2015. (b) 523.

      Like

      • Jim Randell's avatar

        Jim Randell 8:30 am on 31 March 2019 Permalink | Reply

        There are 9 different ways we can construct the sum to potentially give a 4-digit result.

        Counting the number of digits in each of the columns of the sum (<thousands>, <hundreds>, <tens>, <ones>), we have:

        (2, 2, 2, 2) → ABCD + EFGH
        (1, 2, 2, 3) → ABCD + EFG + H
        (1, 1, 3, 3) → ABCD + EF + GH
        (1, 1, 2, 4) → ABCD + EF + G + H
        (1, 1, 1, 5) → ABCD + E + F + G + H
        (0, 2, 3, 3) → ABC + DEF + GH
        (0, 2, 2, 4) → ABC + DEF + G + H
        (0, 1, 3, 4) → ABC + DE + FG + H
        (0, 1, 2, 5) → ABC + DE + F + G + H

        However, for years in the range 2009 to 2019 we only need to consider the constructions that have a single 4-digit number, i.e.:

        (1, 2, 2, 3)
        (1, 1, 3, 3)
        (1, 1, 2, 4)
        (1, 1, 1, 5)

        It turns out there are 132 sets of numbers that can be made that sum to 2019. And 114 that sum to 2018.

        We can compute the number of solutions for various years as follows:

        2019: 132
        2018: 114
        2017: 114
        2016: 96
        2015: 0
        2014: 132
        2013: 132
        2012: 114
        2011: 132
        2010: 132
        2009: 132
        2008: 234
        2007: 114
        2006: 0
        2005: 65
        2004: 71
        2003: 95
        2002: 65
        2001: 71
        2000: 95
        1999: 96
        1998: 48
        1997: 0
        1996: 83
        1995: 83
        1994: 107
        1993: 89
        1992: 113
        1991: 108
        1990: 101
        1989: 66
        1988: 0

        Using digital roots we can see that the missing digit in the sum for year n is:

        9 − digrt(n)

        So every 9 years (when the year has remainder of 8 when divided by 9), we get a year that has no solutions, as it is not possible to make a year after 1889 without using the digit 1, until we get to 2375. The years we are considering fall within this range, and so there is one year in the required range can have no solutions. This provides the answer to the first part of puzzle.

        The possible solutions for the year 2018 are (with the solutions involving 3 digit numbers indicated (*)):

        [1][36][28][459] = 2018 (*)
        [1][45][28][369] = 2018 (*)
        [1][9][235][468] = 2018
        [1][9][28][3456] = 2018
        [1][9][46][2358] = 2018

        The digits are grouped into columns, so the first number is made by choosing one digit from each of the groups, e.g. 1324, then the second number is made by choosing from the remaining digits, e.g. 685, and the next number is formed from the remaining digits, in this case 9. This exhausts all the digits, so: 1324 + 685 + 9 = 2018.

        In this way we see the possible 3-digit numbers involved are:

        [36][28][459]
        [45][28][369]

        and the only ones that are prime are 389 and 523.

        For 2019 the corresponding solutions are:

        [1][45][28][379] = 2019 (*)
        [1][45][37][289] = 2019 (*)
        [1][8][579][234] = 2019
        [1][9][235][478] = 2019
        [1][9][28][3457] = 2019
        [1][9][37][2458] = 2019

        So the 3-digit prime needs to match:

        [45][28][379]
        [45][37][289]

        And the only one of our candidates that matches is 523.

        So we have:

        2018 = 523 + [1][4][8][69] = (523 + 1486 + 9, 523 + 1489 + 6)

        missing out the digit 7.

        And:

        2019 = 523 + [1][4][8][79] = (523 + 1487 + 9, 523 + 1489 + 7)

        missing out the digit 6.

        This provides the answer to the second part of the puzzle.

        Like

  • Unknown's avatar

    Jim Randell 7:21 am on 23 March 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 466: [Ferry fare] 

    From The Sunday Times, 3rd May 1970 [link]

    The ferryman collected 5s. when he took six horses and two prams across the river, and 5s. 9d. when he brought six bicycles and three wheel-barrows back. He is at present collecting 4s. for two wheel-barrows, three prams and a horse.

    His idiosyncratic tariff of charges is for vehicles and animals only, and not for people.

    How much will he collect for his next cargo, which awaits him on the far bank and consists of one wheel-barrow, one horse, one bicycle and one pram?

    This puzzle was originally published with no title.

    [teaser466]

     
    • Jim Randell's avatar

      Jim Randell 7:32 am on 23 March 2019 Permalink | Reply

      We note that 1 shilling (s) = 12 pence (d).

      So we have the following 3 equations (expression amounts in pence):

      [1]: 6h + 2p = 60
      [2]: 3w + 6b = 69
      [3]: 2w + 1h + 3p = 48

      There are 3 equations in 4 variables, so we cannot work out the actual prices. But we don’t need to, we are looking for the price of a particular combination.

      So, we can consider looking for multipliers t, u, v for the equations that give the required combination:

      [*]: t × [1] + u × [2] + v × [3] = 1w + 1h + 1b + 1p

      Then the amount to be collected (in pence) is then:

      t × 60 + u × 69 + v × 48

      Equating the coefficients of w, h, b, p we get the following 4 equations:

      [w]: 3u + 2v = 1
      [h]: 6t + v = 1
      [b]: 6u = 1
      [p]: 2t + 3v = 1

      which is 4 equations in 3 variables, so we try to solve them:

      From [b]:

      u = 1/6

      Then from [w]:

      v = 1/4

      and from [h]:

      t = 1/8

      And we can check [p] gives the right value (which it does).

      So the equations are consistent, and the solution is:

      60/8 + 69/6 + 48/4 = 31 (pence)

      Solution: He will collect 2s 7d.


      Here’s a Python program that does the same thing using the Gaussian elimination solver for linear equations from the enigma.py library. (Originally written for Enigma 287).

      It runs in 87ms.

      from enigma import (Matrix, printf)
      
      # solve the equations
      (t, u, v) = Matrix.linear([[0, 3, 2], [6, 0, 1], [0, 6, 0], [2, 0, 3]], [1, 1, 1, 1])
      
      # determine the answer in pence
      x = t * 60 + u * 69 + v * 48
      # ... in shillings and pence
      (s, d) = divmod(x, 12)
      
      printf("fare = {s}s {d}d [t={t} u={u} v={v}]")
      

      Like

  • Unknown's avatar

    Jim Randell 7:58 am on 22 March 2019 Permalink | Reply
    Tags:   

    Teaser 2931: Unfortunate 57 

    From The Sunday Times, 25th November 2018 [link] [link]

    In the early days of the internet, I used a secret shorthand for my important passwords:

    Bank=1/7, Credit Card=2/7, ISP=3/7, etc.

    Like all fractions, the decimal expansions:

    1/7 = 0.142857142857142…
    2/7 = 0.285714285714285…

    eventually repeat themselves, in this case in sequences of six digits. In each case, my password was the set of digits that repeat (“Unfortunate 57” is a mnemonic for 142857). As password requirements became stricter, I changed my system to base 11, using an X for the extra digit for “ten”; so for instance in base 11:

    234 (= 1 × 11^2 + 10 × 11^1 + 3 × 11^0) is 1X3 [base 11], and;
    1/2 = 0.5555… [base 11] = 5 / (11^1) + 5 / (11^2) + 5 / (11^3) + …

    In the sequence 1/2, 1/3, …, what is the first password of length greater than six that my base-11 system produces?

    The setter is probably conflating “the internet” with “the world wide web”.

    [teaser2931]

     
    • Jim Randell's avatar

      Jim Randell 7:58 am on 22 March 2019 Permalink | Reply

      For Enigma 1247 I wrote the [[ recurring() ]] function, which will calculate the recurring representation of a fraction in a given base.

      We can use this routine in a short Python program to solve this puzzle. It runs in 74ms.

      Run: [ @replit ]

      from enigma import (irange, inf, recurring, format_recurring, printf)
      
      for x in irange(2, inf):
        (i, nr, rr) = recurring(1, x, base=11, digits='0123456789X')
        printf("1 / {x} = {f} [period = {n}]", f=format_recurring(i, nr, rr), n=len(rr))
        if len(rr) > 6: break
      

      Solution: The first password with length greater than 6 is: 093425X17685.

      It is produced by the fraction 1/13 (in decimal notation).

      Like

    • Lise Andreasen's avatar

      Lise Andreasen 7:17 am on 19 April 2024 Permalink | Reply

      In the early days of the internet, we had SMTP (email), FTP etc.

      Like

  • Unknown's avatar

    Jim Randell 7:08 am on 21 March 2019 Permalink | Reply
    Tags:   

    Teaser 1986: Protracted calculation 

    From The Sunday Times, 8th October 2000 [link]

    In the circle illustrated the numbers represent the sizes of the sectors:

    By combining adjacent ones it is possible to find sectors in this circle of sizes 1, 2, 3, … all the way up to 13 (13 being the whole circle). For example:

    7 = 4 + 1 + 2.

    In a similar fashion, given a circle divided into five sectors in a particular way, it is possible to combine adjacent sectors to give sizes 1, 2, 3, … up to the biggest possible in the circumstances.

    What, in increasing order, are the sizes of the five sectors?

    The text of this puzzle is taken from the book Brainteasers (2002), the wording differs only slightly from the puzzle originally published in the newspaper.

    [teaser1986]

     
    • Jim Randell's avatar

      Jim Randell 7:09 am on 21 March 2019 Permalink | Reply

      If the circle is divided into k sectors, then for each starting sector (and there are k of them) we can make a contiguous region consisting of 1, 2, 3, …, (k − 1) sectors. We don’t make a region of k sectors because that is the whole circle, so we add that in separately giving a total number of arrangements of:

      n(k) = k(k − 1) + 1 = k² − k + 1

      To make the arrangements correspond to the numbers 1, 2, 3, … n(k), the whole circle needs to correspond to the value n(k), and there needs to be a single sector corresponding to the number 1. So we place the number 1 in the first sector, and then distribute the remaining (n(k) − 1) between the remaining (k − 1) sectors.

      This Python 3 program finds the solution in 83ms.

      Run: [ @replit ]

      from itertools import permutations
      from enigma import (irange, arg, printf)
      
      # generate (non-empty) tuples of adjacent sectors
      def sectors(k):
        # consider n consecutive sectors
        for n in irange(1, k - 1):
          # possible start sector
          for i in irange(0, k - 1):
            yield tuple((i + j) % k for j in irange(0, n - 1))
        # the whole circle
        yield tuple(irange(0, k - 1))
      
      # decompose <t> into <n> different numbers, min <m>
      def decompose(t, n, m, s=[]):
        if n == 1:
          if not (t < m):
            yield s + [t]
        else:
          for x in irange(m, t - n):
            yield from decompose(t - x, n - 1, x + 1, s + [x])
      
      # number of sectors to divide the circle into
      k = arg(5, 0, int, prompt="number of sectors")
      assert k > 1
      
      # make a list of adjacent sectors
      ss = list(sectors(k))
      t = len(ss)
      printf("[k={k}: {t} arrangements]")
      
      # put 1 at sector 0, and decompose the remainder
      for d in decompose(t - 1, k - 1, 2):
        for p in permutations(d):
          if p[0] > p[-1]: continue
          s = (1,) + p
          # calculate the values of adjacent sectors
          vs = set(sum(s[i] for i in x) for x in ss)
          if len(vs) == t:
            printf("{s}")
      

      Solution: The five sectors have values: 1, 2, 3, 5, 10 (in numerical order).

      They can be arranged like this:

      As well as the example given it is also possible to make a circle with 4 sectors using the values: 1, 3, 2, 7.

      The program is suitable for experimenting with small values of k. (One simple way to improve the program is to note that as well as a 1 sector, we will also need a 2 sector in the remaining decomposition).

      Here are the number of solutions for various values of k:

       k  n(k)  solutions
       1     1    1
       2     3    1
       3     7    1
       4    13    2
       5    21    1
       6    31    5
       7    43    0
       8    57    6
       9    73    4
      10    91    6
      11   111    0
      12   133   18
      13   157    0
      14   183   20
      ...

      (See: OEIS A058241 [ link ]).

      We’ve come across the following formula before:

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

      Specifically in the exploration of Teaser 2907, where it is the number of elements in a finite projective plane of order (k − 1).

      The fact that there is no solution for (k = 7, n = 43), (k = 11, n = 111) and (k = 13, n = 157) makes me wonder if there is a link with projective planes, as finite projective planes of order 6, 10, and 12 (probably) do not exist.


      For a more efficient way to generate “magic circles” see my comment on Enigma 985.

      Like

      • Frits's avatar

        Frits 11:47 am on 13 June 2022 Permalink | Reply

        @Jim,

        You might use (and in Enigma 985):

           
        for x in irange(m, t - n * (n - 1) // 2):
        

        in decompose() as we need different numbers. It doesn’t seem to make much of a difference in the performance.

        Like

        • Jim Randell's avatar

          Jim Randell 11:29 am on 14 June 2022 Permalink | Reply

          @Frits: If I were to re-write the code now I would probably just use [[ decompose() ]] from enigma.py (and [[ tuples() ]] to generate the adjacent sectors). [See: @replit]

          from enigma import (irange, tuples, decompose, arg, printf)
          
          # generate (non-empty) tuples of adjacent sectors
          def sectors(k):
            # the whole circle
            t = tuple(irange(k))
            # consider n consecutive sectors
            for n in irange(1, k - 1):
              yield from tuples(t, n, circular=1)
            # and the whole circle
            yield t
          
          # number of sectors to divide the circle into
          k = arg(5, 0, int)
          assert k > 1
          
          # make a list of adjacent sectors
          ss = list(sectors(k))
          t = len(ss)
          printf("[k={k}: {t} arrangements]")
          
          # put 1 at sector 0, and 2 somewhere, and decompose the remainder
          for d in decompose(t - 3, k - 2, increasing=0, sep=1, min_v=3, fn=list):
            # insert 2 somewhere
            for i in irange(0, (0 if k == 2 else k - 3)):
              s = list(d)
              s.insert(i, 2)
              if s[0] > s[-1]: continue
              # insert 1 at sector 0
              s.insert(0, 1)
              # calculate the value for adjacent sectors
              vs = set(sum(s[i] for i in x) for x in ss)
              if len(vs) == t:
                printf("{s}", s=tuple(s))
          

          But using magic_circles.py gives a much shorter and faster program:

          from enigma import (arg, printf)
          from magic_circles import magic_circle
          
          # number of sectors to divide the circle into
          k = arg(5, 0, int, prompt="number of sectors")
          assert k > 1
          
          # find magic k-circles
          for s in magic_circle(k):
            # output solution
            printf("{s}")
          

          Like

  • Unknown's avatar

    Jim Randell 11:31 am on 20 March 2019 Permalink | Reply
    Tags:   

    Teaser 2932: Triangulation 

    From The Sunday Times, 2nd December 2018 [link] [link]

    Liam plans to make a set of dominoes. They will be triangular, and one face of each domino will have a number at each corner. The numbers run from 0 up to a maximum digit (9 or less), and the set is to include all possible distinguishable dominoes.

    With the maximum digit he has chosen the set would contain a triangular number of dominoes. [A triangular number is one where that number of balls can fit snugly in an equilateral triangle, for example the 15 red balls on a snooker table].

    How many dominoes will he need to make?

    [teaser2932]

     
    • Jim Randell's avatar

      Jim Randell 11:32 am on 20 March 2019 Permalink | Reply

      For each maximum digit, this Python program constructs all possible dominoes that are unique by rotation. It runs in 75ms.

      Run: [ @repl.it ]

      from itertools import product
      from enigma import (irange, is_triangular, printf)
      
      for d in irange(0, 9):
        s = set()
        # choose three numbers for the corners
        for (a, b, c) in product(irange(0, d), repeat=3):
          # record the domino by it's minimal rotation
          s.add(min((a, b, c), (b, c, a), (c, a, b)))
      
        # count the number of different dominoes
        n = len(s)
        t = ('[triangular]' if is_triangular(n) else '')
        printf("d={d}: {n} dominoes {t}")
      

      Solution: He will need to make 45 dominoes.

      There is a degenerate solution where only the digit 0 is used. There is only one domino (0, 0, 0), and 1 is a triangular number T(1) = 1.

      Running the program we see the number dominoes is given by the following sequence:

      1, 4, 11, 24, 45, 76, 119, 176, 249, 340

      which is OEIS A006527 [ link ] the general formula is:

      a(n) = n (n² + 2) / 3

      so we don’t have to count the dominoes.

      from enigma import (irange, is_triangular, printf)
      
      for d in irange(1, 10):
        n = (d**3 + 2 * d) // 3
        t = ('[triangular]' if is_triangular(n) else '')
        printf("d={d}: {n} dominoes {t}", d=d - 1)
      

      If we consider d > 9 there are larger solutions at d = 12 (741 dominoes) and d = 35 (15576 dominoes).

      Like

  • Unknown's avatar

    Jim Randell 7:04 am on 19 March 2019 Permalink | Reply
    Tags: ,   

    Brain-Teaser 465: [Lifts] 

    From The Sunday Times, 26th April 1970 [link]

    Near my house is an impressive block of flats. It stands 16 storeys high, and each story is a lofty 15 feet from floor to floor. My old friends Bob and Horace operate the two lifts, and both start their shift each morning leaving the ground floor at 8 a.m. precisely.

    The two lifts make automatic compulsory stops at the ground level (there is no basement), the 12th and top floors. But below the 12th, Bob serves only the odd-numbered floors, and Horace the even numbers; these stops are also compulsory (up and down). All stops take just 10 seconds, except at ground level where both lifts wait for 20 seconds.

    Above the 12th both Bob and Horace stop as desired, going up and coming down. Both lifts travel between floors at identical speeds.

    Every morning the two attendants make a rendezvous to exchange newspapers and collect their coffee when their arrivals at a certain floor coincide exactly at two minutes after 11 a.m.

    In feet per second what the speed of each lift between stops?

    Note: In the UK the floors in buildings are: ground floor, first floor, second floor, etc.

    Also, as stated this puzzle does not appear to have a unique solution.

    An answer was published (with Teaser 467) stating:

    “This clever trap, with its nice reasoning, outweighed the slight mathematical bias and kept down the entry to a mixed handful.”

    But later, with Teaser 471 the following statement was made:

    “[465: Regretfully a wrong transposition led to a false calculation of time.]”

    In the comments I give a variation on the puzzle that does have a unique answer.

    This puzzle was originally published with no title.

    [teaser465]

     
    • Jim Randell's avatar

      Jim Randell 7:05 am on 19 March 2019 Permalink | Reply

      Replacing the third paragraph (“Above the 12th floor…”) with the following gives a puzzle that does have a unique solution, and it is the same as the published answer.

      The 13th floor is considered to be unlucky, so at the beginning of each day the attendants toss a coin to decide who should service it that day. The loser has to stop at the 13th floor each time they pass it, and the winner stops at the 14th floor each time they pass it. Both lifts take the same amount of time to travel between adjacent floors.

      This Python program can be used to investigate situations where the attendants follow a fixed schedule of stops. And it solves this variation puzzle in 412ms.

      Run: [ @repl.it ]

      from fractions import Fraction as F
      from enigma import printf
      
      # number of seconds between 08:00:00 and 11:02:00
      S = (3 * 60 + 2) * 60
      
      # wait at each floor (seconds)
      wait = [20] + [10] * 15
      
      # generate (<floor>, <seconds>, <n floors>)
      def stops(fs, wait=wait):
        s = n = f = 0
        while True:
          # going up
          for (i, x) in enumerate(fs):
            if i == 0: continue
            s += wait[f]
            n += (x - f)
            f = x
            yield (f, s, n)
          # going down
          for (i, x) in enumerate(reversed(fs)):
            if i == 0: continue
            s += wait[f]
            n += (f - x)
            f = x
            yield (f, s, n)
      
      # collect possible (f, s, n) tuples
      def collect(fs, xs):
        for (f, s, n) in stops(fs):
          if not (s < S): break
          if f in xs: yield (f, s, n)
      
      # solve for specific floors visited by B and H
      def solve(B, H):
        # find common floors
        xs = set(B).intersection(H)
        # collect (<floor>, <seconds>, <n floor>) tuples for each
        Bs = list(collect(B, xs))
        Hs = list(collect(H, xs))
      
        # consider possible meeting stops for B (at time S)
        for (fB, sB, nB) in Bs:
          # calculate time between floors
          t = F(S - sB, nB)
          # look for matching stops for H
          for (fH, sH, nH) in Hs:
            if fH == fB and sH + t * nH == S:
              printf("t={t}s [floor={fB}, B=(wait={sB}s, floors={nB}), H=(wait={sH}s, floors={nH})]")
      
      # send B to floor 13, H to floor 14
      solve(
        [0, 1, 3, 5, 7, 9, 11, 12, 13, 15], # floors for B
        [0, 2, 4, 6, 8, 10, 12, 14, 15], # floors for H
      )
      

      Solution: The time between floors is 3s, giving an average speed of 5 ft/s.

      By 11:02 am, Bob has spent 7410s waiting and travelled 1170 floors. Horace has has waited for 7140s and travelled 1260 floors.

      Like

  • Unknown's avatar

    Jim Randell 7:41 am on 18 March 2019 Permalink | Reply
    Tags:   

    Teaser 2933: Sunday Teaser 

    From The Sunday Times, 9th December 2018 [link] [link]

    I wrote down two three-figure numbers and worked out their product by long multiplication. Systematically replacing digits by letters, my workings became:

    I then wrote down two numbers which were represented by SUNDAY TEASER.

    What were these two numbers?

    [teaser2933]

     
    • Jim Randell's avatar

      Jim Randell 7:42 am on 18 March 2019 Permalink | Reply

      This alphametic problem can be solved directly using the [[ SubstitutedExpression() ]] solver in the enigma.py library.

      The following run file executes in 123ms.

      Run: [ @repl.it ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      --answer="(SUNDAY, TEASER)"
      
      "NTS * EDS = ARRATS"
      
      "NTS * S = DURS"
      "NTS * D = YRD"
      "NTS * E = ANDU"
      

      Solution: SUNDAY = 684219; TEASER = 731635.

      Like

    • GeoffR's avatar

      GeoffR 9:48 am on 2 December 2020 Permalink | Reply

      
      from itertools import permutations
      digits = set('1234567890')
      
      for P1 in permutations(digits, 7):
        n, t, s, e, d, a, r = P1
        if '0' in (n, e, d, a, t, s):
          continue
        nts, eds = int(n + t + s), int(e + d + s)
        arrats = int(a + r + r + a + t + s)
        if nts * eds == arrats:
      
          # find remaining digits
          Q1 = digits.difference(P1)
          for P2 in permutations(Q1, 2):
            u, y = P2
            durs, yrd = int(d + u + r + s), int(y + r + d)
            andu = int(a + n + d + u)
            if int(s) * nts == durs:
              if int(d) * nts == yrd:
                if int(e) * nts == andu:
                  if durs + yrd * 10 + andu * 100 == arrats:
                    SUNDAY = int(s + u + n + d + a + y)
                    TEASER = int(t + e + a + s + e + r)
                    print(f"SUNDAY = {SUNDAY}, TEASER = {TEASER}")
                    print(f"Main sum: {nts} x {eds} = {arrats}")
      
      # SUNDAY = 684219, TEASER = 731635
      # Main sum: 476 x 326 = 155176
      
      
      

      Like

    • Frits's avatar

      Frits 9:31 pm on 2 December 2020 Permalink | Reply

      A different approach, not very efficient.

      from enigma import nconcat
      
      # get integer value for string <s>
      getvar = lambda vals, template, s: nconcat(vals[template.index(x)] for x in s)
      
      LETTERS = "SDNTURYAE" 
      VARLIST = ["NTS", "DURS", "S", "D", "YRD", "E", "ARRATS", "EDS", "ANDU"]
      
      # minimum values of letters
      RNGMIN = [1, 1, 1, 1, 0, 1, 1, 1, 1]
      
      def solve(t, ns=[]):
        if t == 0:  # we have set all letters
          # calculate variables (we need to store results in a dictionary)
          ex = ""
          d = dict()
          for v in VARLIST:
            ex += "d['" + v + "'] = getvar(ns, LETTERS, '" + v + "');\n"  
          exec(ex)
        
          # perform final checks  
          if d["NTS"] * d["EDS"] != d["ARRATS"]: return
          if d["NTS"] * d["S"] != d["DURS"]: return
          if d["NTS"] * d["D"] != d["YRD"]: return
          if d["NTS"] * d["E"] != d["ANDU"]: return
          
          yield ns
        else:
          if t == 8:       # variable S read, check (S*S) % 10 = S
            if ns[0]**2 % 10 != ns[0]:
              return
          if t == 7:       # variable S and D read, check (S*D) % 10 = D
            if (ns[0] * ns[1]) % 10 != ns[1]:
              return    
          if t == 3:       # variable S,D,N,T,U,R read
            ex = ""
            d = dict()
            for v in VARLIST[:3]:
              ex += "d['" + v + "'] = getvar(ns, LETTERS, '" + v + "');\n" 
            exec(ex)
            if d["NTS"] * d["S"] != d["DURS"]: 
              return
            
          for n in range(RNGMIN[len(LETTERS) - t], len(LETTERS) + 1):
            if n not in ns:   # variables all diffferent
              yield from solve(t - 1, ns + [n])
      
      res = solve(len(LETTERS))
      for r in res: 
        print(f"SUNDAY = {getvar(r, LETTERS, 'SUNDAY')} "
              f"TEASER = {getvar(r, LETTERS, 'TEASER')}")
      
      
      # SUNDAY = 684219 TEASER = 731635
      

      Like

  • Unknown's avatar

    Jim Randell 6:17 am on 17 March 2019 Permalink | Reply
    Tags:   

    Teaser 2947: 55 Divisions 

    From The Sunday Times, 17th March 2019 [link] [link]

    To mark her 55th birthday, Martha, a school teacher, gave each of her nine pupils a sheet of paper with a single different digit from 1 to 9 written on it.

    They stood at the front of the classroom in a row and the 9-digit number on display was divisible by 55. Martha then asked the first 3 in the row (from the left) to sit down. The remaining 6-digit number was also divisible by 55. The next 3 then sat down and the remaining 3-digit number was also divisible by 55.

    The 9 digit number was the smallest possible. What was it?

    [teaser2947]

     
    • Jim Randell's avatar

      Jim Randell 6:25 am on 17 March 2019 Permalink | Reply

      We can treat the problem as an alphametic puzzle, use the [[ SubstitutedExpression() ]] solver from the enigma.py library to find all possible solutions, and then find the smallest of these.

      This Python program runs in 98ms.

      from enigma import (SubstitutedExpression, Accumulator, irange, printf)
      
      # the alphametic puzzle
      p = SubstitutedExpression(
        [ "ABCDEFGHI % 55 = 0", "DEFGHI % 55 = 0", "GHI % 55 = 0" ],
        answer="ABCDEFGHI",
        digits=irange(1, 9),
      )
      
      # find the minimum answer
      r = Accumulator(fn=min).accumulate_from(p.answers())
      
      # output solution
      printf("min answer = {r.value} [of {r.count} solutions]")
      

      Solution: The number is 143869275.

      There are 48 different solutions to the alphametic puzzle.

      Like

    • GeoffR's avatar

      GeoffR 2:46 pm on 19 March 2019 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
      
      enum letters = {A, B, C, D, E, F, G, H, I};  
      array [letters] of var 1..9: v;
      
      constraint all_different(v);
      
      var 100000000..999999999: ABCDEFGHI = v[A] * pow(10,8) + v[B] * pow(10,7) 
      + v[C] * pow(10,6) + v[D] * pow(10,5) + v[E] * pow(10,4) + v[F] * 1000 
      + v[G] * 100 + v[H] * 10 + v[I];
      
      var 100000..999999: DEFGHI = 100000 * v[D] + 10000 * v[E] + 1000 * v[F] 
      + 100 * v[G] + 10 * v[H] + v[I];
      
      var 100..999: GHI = 100 * v[G] + 10 * v[H] + v[I];
      
      constraint ABCDEFGHI mod 55 == 0 /\ DEFGHI mod 55 == 0 /\ GHI mod 55 == 0;
      
      solve minimize(ABCDEFGHI);
      
      output ["Smallest 9-digit number = " ++ show(ABCDEFGHI) ];
      
      % Smallest 9-digit number = 143869275
      % time elapsed: 0.03 s
      % ----------
      % ==========
      % Finished in 241msec
      
      
      

      Like

      • Jim Randell's avatar

        Jim Randell 11:09 am on 20 March 2019 Permalink | Reply

        This puzzle is an ideal candidate for using the [[ solve minimize(...) ]] target in a MiniZinc model.

        Also I didn’t know MiniZinc had [[ enum ]]. (In fact, in the tutorial I used I seem to remember there was a section on how it didn’t have them and how to emulate them. I suppose they must have come along in a later version).

        Like

    • GeoffR's avatar

      GeoffR 12:14 pm on 20 March 2019 Permalink | Reply

      The latest version of MiniZinc( Ver 2.2.3) has much improved documentation and a new menu, including timing for Windows and other features. It seems odd that a solution can be found in 20 -30 msec, but still takes over 200msec to finish.

      Here is the link for enums:

      https://www.minizinc.org/doc-2.2.3/en/spec.html#enumerated-types

      Like

    • Jim Randell's avatar

      Jim Randell 10:29 am on 29 July 2020 Permalink | Reply

      I’ve recently added the [[ accumulate ]] parameter to the [[ SubstitutedExpression() ]] solver, which allows values to be computed from all the solutions.

      So, my Python program above can be modified to:

      from enigma import (SubstitutedExpression, irange, printf)
      
      # the alphametic puzzle
      p = SubstitutedExpression(
        [ "ABCDEFGHI % 55 = 0", "DEFGHI % 55 = 0", "GHI % 55 = 0" ],
        digits=irange(1, 9),
        answer="ABCDEFGHI",
        accumulate=min,
      )
      
      # solve the puzzle
      r = p.run()
      
      # output solution
      printf("min answer = {r.accumulate} [of {r.n} values]")
      

      Although the accumulated value will be output twice.

      We can also achieve the same result using a run file:

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --digits="1-9"
      
      "ABCDEFGHI % 55 = 0"
      "DEFGHI % 55 = 0"
      "GHI % 55 = 0"
      
      --answer="ABCDEFGHI"
      --accumulate="min"
      

      Note that changing the [[ --accumulate ]] parameter to [[ --accumulate="(min, max)" ]] allows us to calculate the minimum and maximum values from the answers.

      This functionality is available in the 2020-07-29 version of the enigma.py library.

      Like

  • Unknown's avatar

    Jim Randell 8:04 am on 16 March 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 464: Home meadow 

    From The Sunday Times, 19th April 1970 [link]

    The triangular home meadow at Cowpleasure Farm is bounded West and South by fences running due north and due east from the farmhouse; its other fence forms one side of a square field known as Starvecrow. The south fence of Home Meadow is the shared north boundary of two contiguous square fields, Paddock and Rookery, whose total area is just half that of Starvecrow.

    Farmer Nettle has just refenced the whole outer perimeter (i.e. excluding fences common to two fields). He used 146 equal sections of fencing, none of which needed bending or cutting.

    He plans to replace the other fences next year using the same type of section.

    How many will he need? (Don’t worry about gates; they are incorporated in some of the standard sections).

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

    [teaser464]

     
    • Jim Randell's avatar

      Jim Randell 8:06 am on 16 March 2019 Permalink | Reply

      There’s nothing to distinguish the fields P and R, so we’ll call the smaller one P.

      For the square fields P, R, S, we’ll indicate the size of one side also by P, R, S, and the remaining boundary of H can be Q.

      The amount of perimeter fencing (shown in red) required is X:

      X = 3S + 2P + 2R + (R − P) + Q = 3(S + R) + P + Q

      And the amount of internal fencing (the remaining black lines) required is Y:

      Y = 2P + R + S

      This Python program uses the [[ pythagorean_triples() ]] routine (see Teaser 2910) from the enigma.py library to find possible dimensions of field H, and then determines the dimensions of the other fields.

      It runs in 77ms.

      Run: [ @repl.it ]

      from enigma import pythagorean_triples, irange, printf
      
      for (x, y, z) in pythagorean_triples(48):
        # S is the hypotenuse
        S = z
        # one of the other two sides is P + R
        for (PR, Q) in [(x, y), (y, x)]:
          # suppose P < R
          for P in irange(1, PR // 2):
            R = PR - P
            # P^2 + R^2 = S^2 / 2
            if not (2 * (P * P + R * R) == S * S): continue
            # total sum of perimeter fences is 146
            X = 3 * (S + R) + P + Q
            if not (X == 146): continue
            # sum of the internal fences
            Y = S + PR + P
            # output solution
            printf("Y={Y}, S={S} P={P} R={R} Q={Q}")
      

      Solution: He will need 57 sections.

      Like

  • Unknown's avatar

    Jim Randell 8:36 am on 15 March 2019 Permalink | Reply
    Tags:   

    Teaser 2934: Good arraz, Baz! 

    From The Sunday Times, 16th December 2018 [link] [link]

    Baz’s three darts hit the board, scoring different numbers from 1 to 20. “Curious numbers”, said Kaz. Baz looked puzzled. Kaz explained that the first dart’s score to the power of the second dart’s score is a value that contains each numeral 0 to 9 at least once and has the third dart’s score number of digits. Baz only saw that the third dart’s score was the difference between the other two darts’ scores. Kaz wrote the full value on a beer mat. Then Baz put his glass on it and covered most of the value, leaving just the first dart’s score showing to the right and the second dart’s score to the left.

    What did each dart score in the order thrown?

    [teaser2934]

     
    • Jim Randell's avatar

      Jim Randell 8:36 am on 15 March 2019 Permalink | Reply

      This Python program runs in 75ms.

      Run: [ @repl.it ]

      from itertools import permutations
      from enigma import (irange, printf)
      
      # possible scores
      darts = set(irange(1, 20))
      
      # consider different scores for the first two darts
      for (d1, d2) in permutations(darts, 2):
      
        # "the third dart's score was the difference between the other two darts' scores"
        d3 = abs(d1 - d2)
        if d3 == d1 or d3 == d2 or d3 < 10: continue
      
        # "the first dart's score to the power of the second dart's score is a value that contains
        # each digit 0 to 9 at least once and has the third dart's score number of digits"
        x = str(d1**d2)
        if len(x) != d3: continue
        if len(set(x)) != 10: continue
      
        # "the first dart's score showing to the right and the second dart's score to the left."
        # assuming "right" = "least significant digits"
        # and "left" = "most significant digits"
        if not (x.endswith(str(d1)) and x.startswith(str(d2))): continue
      
        # output solution
        printf("darts = ({d1}, {d2}, {d3}) [{d1}^{d2} = {x}]")
      
      

      Solution: The scores were: 5, 19, 14.

      We have:

      5^19 = 19073486328125

      Which starts with 19, and ends in 5.

      Like

  • Unknown's avatar

    Jim Randell 6:59 am on 14 March 2019 Permalink | Reply
    Tags: by: Fred Neville   

    Brainteaser 1795: Dicey columns 

    From The Sunday Times, 9th February 1997 [link]

    A boy amused himself by building three separate columns of some equal-sized dice. In each column each die was placed squarely on the one below it. He then looked at the tops of the columns, read each as a digit, and then read the digits together to form one long number.

    For example, had the tops been:

    then he would have read 113.

    He was surprised to find that the number which he read equalled the total number of visible spots all around and on top of his three columns of dice. He also multiplied together the three numbers from the tops of the columns and found that the answer equalled the total number of dice which he had used.

    What was that total number of visible spots?

     

    For a more challenging Teaser try to find a corresponding situation with more than three columns of dice. There is only one other possibility.

     

    The text of this puzzle is taken from the book Brainteasers (2002), so may differ from the puzzle originally published in the newspaper.

    In fact, the puzzle published in the paper was the more challenging variation.

    [teaser1795]

     
    • Jim Randell's avatar

      Jim Randell 7:01 am on 14 March 2019 Permalink | Reply

      Suppose the tops of the three columns show A, B, C.

      Opposite faces on a die sum to 7, so each die shows 14 spots on the vertical sides, and the top dice also show A, B, C, so if there are n dice the total number of spots visible is:

      14n + (A + B + C) = ABC

      (where ABC is an alphametic expression).

      Also the number of dice is given by:

      n = A × B × C

      which gives us the following alphametic expression to solve:

      (14 × A × B × C) + (A + B + C) = ABC

      where A, B, C are limited to be digits from 1 to 6.

      This can easily be solved using the [[ SubstitutedExpression() ]] solver from the enigma.py library.

      Run: [ @repl.it ]

      >>> python enigma.py SubstitutedExpression --distinct="" --digits="1-6" "14 * (A * B * C) + (A + B + C) = ABC"
      (14 * (A * B * C) + (A + B + C) = ABC)
      (14 * (1 * 3 * 3) + (1 + 3 + 3) = 133) / A=1 B=3 C=3
      [1 solution]
      

      Solution: The total number of visible spots was 133.

      So there are 9 dice in total (3 columns of 3 dice each).

      In the book the puzzle then goes on to suggest:

      For a more challenging Teaser try to find a corresponding situation with more than three columns of dice. There is only one other possibility.

      We can try the same thing with four dice, showing A, B, C, D:

      >>> python enigma.py SubstitutedExpression --distinct="" --digits="1-6" "14 * (A * B * C * D) + (A + B + C + D) = ABCD"
      (14 * (A * B * C * D) + (A + B + C + D) = ABCD)
      (14 * (2 * 5 * 3 * 6) + (2 + 5 + 3 + 6) = 2536) / A=2 B=5 C=3 D=6
      [1 solution]
      

      So the solution to this extra puzzle is with 180 dice (4 columns of 45 dice each), showing 2536 visible spots.

      There are no solutions for 5 dice, at least not reading the numbers on top of the dice as a base 10 number. If we read them as a base 8 number then there are 5 solutions with 5 dice (and 1 with 4 dice, and 4 with 3 dice). (You can try it by adding a [[ --base=8 ]] argument to the commands).

      Like

      • Jim Randell's avatar

        Jim Randell 2:43 pm on 14 March 2019 Permalink | Reply

        Writing:

        (14 × A × B × C) + (A + B + C) = 100 × A + 10 × B + C

        we can simplify this to:

        (99 × A + 9 × B) / (14 × A × B) = C

        So we only needs to consider values of A and B to derive C:

        % python enigma.py SubstitutedExpression --distinct="" --digits="1-6" "div(99 * A + 9 * B, 14 * A * B) = C
        (div(99 * A + 9 * B, 14 * A * B) = C)
        (div(99 * 1 + 9 * 3, 14 * 1 * 3) = 3) / A=1 B=3 C=3
        [1 solution]
        

        The improvement in run time (if any) is negligible.


        However, this gives us a manual way to solve the puzzle.

        C is an integer between 1 and 6, and as the denominator of the expression for C has a divisor of 7 then so must the numerator. In fact it must be the case that 7 divides (11A + B). So for any given value of A there is only a single value for B that is possible, from which we can calculate potential values for C:

        A = 1 → B = 3 → C = 3 (Solution)
        A = 2 → B = 6 → C = 3/2
        A = 3 → B = 2 → C = 15/4
        A = 4 → B = 5 → C = 63/40
        A = 5 → B = 1 → C = 36/5
        A = 6 → B = 4 → C = 15/8

        And only one value for A gives a viable value for C.

        Like

    • GeoffR's avatar

      GeoffR 7:29 pm on 8 August 2019 Permalink | Reply

      For three columns of dice:

      % A Solution in MiniZinc
      include "globals.mzn";
      
      var 1..6: t1; var 1..6: t2; var 1..6: t3;  % top numbers on 3 dice
      var 1..20: n;  % number of dice per column
      
      % total number of visible spots for 3 columns
      constraint 3 * (2 * 7 * n) + t1 + t2 + t3 == 100*t1 + 10*t2 + t3;
      
      % the three numbers from the tops of the three columns mutiplied
      % together give the total number of dice
      constraint t1 * t2 * t3 == 3 * n;
      
      solve satisfy;
      
      output ["Total number of visible spots = " ++ 
      show(3 * (2 * 7 * n) + t1 + t2 + t3)
      ++"\nTotal number of dice = " ++ show(n * 3) ];
      
      % Total number of visible spots = 133
      % Number of dice = 9
      % ----------
      % ==========
      

      For four columns of dice:

      % A Solution in MiniZinc
      include "globals.mzn";
      
      % top numbers on four dice
      var 1..6: t1; var 1..6: t2; var 1..6: t3; var 1..6: t4;
      var 1..75: n;  % number of dice per column
      
      % total number of visible spots for four columns
      constraint 4 * (2 * 7 * n) + t1 + t2 + t3 + t4 
      == 1000*t1 + 100*t2 + 10*t3 + t4;
      
      % the four numbers from the tops of the four columns mutiplied
      % together give total number of dice
      constraint t1 * t2 * t3 * t4 == 4 * n;
      
      solve satisfy;
      
      output ["Total number of visible spots = " ++ 
      show(4 * (2 * 7 * n) + t1 + t2 + t3 + t4)
      ++"\nTotal Number of dice = " ++ show(n * 4)
      ++"\nTop die numbers are " ++ show(t1) ++ ", " ++ show(t2)
      ++ ", " ++ show(t3) ++ " and " ++ show(t4) ];
      
      % Total number of visible spots = 2536
      % Total Number of dice = 180
      % Top die numbers are 2, 5, 3 and 6
      % ----------
      % ==========
      
      

      Like

  • Unknown's avatar

    Jim Randell 7:45 am on 13 March 2019 Permalink | Reply
    Tags:   

    Teaser 2936: Multicoloured 

    From The Sunday Times, 30th December 2018 [link] [link]

    George and Martha are selling wall-paper of various colours. By replacing letters with positive digits, they have devised the following multiplication problem:

    RED × GREY = YELLOW

    The N in GREEN is the remaining positive digit. The red wall-paper is sold only in squares, which is appropriate since RED is a perfect square.

    What is the value of GREEN?

    [teaser2936]

     
    • Jim Randell's avatar

      Jim Randell 7:47 am on 13 March 2019 Permalink | Reply

      We can use the [[ SubstitutedExpression() ]] solver from the enigma.py library to solve the alphametic expressions directly.

      This run-file executes in 119ms.

      Run: [ @repl.it ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      --digits="1-9"
      --answer="GREEN"
      
      "RED * GREY = YELLOW"
      "is_square(RED)"  # optional
      

      Solution: GREEN = 21668.

      The [[ is_square(RED) ]] condition is optional (in that there are no further solutions if it is omitted), but it verifies the statement of the problem, and also allows the run-file to execute a little faster (and is convenient when pursuing a manual solution).

      Like

    • GeoffR's avatar

      GeoffR 12:12 pm on 13 March 2019 Permalink | Reply

      % A solution in MinZinc 
      include "globals.mzn";
      
      var 1..9:R; var 1..9:E; var 1..9:D; var 1..9:G; var 1..9:Y; 
      var 1..9:L; var 1..9:O; var 1..9:W; var 1..9:N; 
      
      constraint all_different([R, E, D, G, Y, L, O, W, N]);
      
      var 100..999: RED = 100*R + 10*E + D;
      var 1000..9999: GREY = 1000*G + 100*R + 10*E + Y;
      var 100000..999999: YELLOW = 100000*Y + 10000*E + 1000*L + 100*L + 10*O + W;
      var 10000..99999: GREEN =10000*G + 1000*R + 110*E + N;
      
      set of int: sq3 = {n*n | n in 10..31};
      constraint RED in sq3;
      
      constraint RED * GREY == YELLOW;
      
      solve satisfy;
      
      output [ "GREEN = " ++ show(GREEN)  ++ "\n"
      ++ show(RED) ++ " X " ++ show(GREY) ++ " = " ++ show(YELLOW)];
      
      % GREEN = 21668
      % 169 X 2163 = 365547
      % time elapsed: 0.02 s
      
      
      

      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