Enigmatic Code

Programming Enigma Puzzles

Tantalizer 484: Blockwork

From New Scientist #1035, 20th January 1977 [link]

Someone gave my small son a bag of 1in cubes for Christmas and he was soon busy stacking them. First he built a rectangular wall one brick thick. Then he used the rest of the bricks to build another rectangular block, using 140 bricks more than the other. Then he got bored.

But I didn’t, as I spotted an intriguing fact. The sum of the lengths of the twelve edges on each construction was the same. So were the total surface areas of the two constructions (including the faces standing on the carpet). All the six dimensions involved were different.

How many bricks had he been given?

[tantalizer484]

Advertisements

One response to “Tantalizer 484: Blockwork

  1. Jim Randell 21 April 2017 at 8:15 am

    Suppose the first block constructed has dimensions (a, b, 1) and the second block has dimensions (x, y, z), then from the information given we have the following equations:

    [1] “The second block uses 140 bricks more than the first”

    xyz = ab + 140

    [2] “The sum of the lengths of the edges was the same for both blocks”

    x + y + z = a + b + 1

    [3] “The total surface area of the two blocks is the same”

    xy + xz + yz = ab + a + b

    By expanding (x – 1)(y – 1)(z – 1) we get:

    (x – 1)(y – 1)(z – 1) = (xyz) – (xy + xz + yz) + (x + y + z) – 1

    And we can substitute the bracketed expressions on the RHS with equations [1], [2], [3] to get:

    (x – 1)(y – 1)(z – 1) = (ab + 140) – (ab + a + b) + (a + b + 1) – 1

    which simplifies to give:

    (x – 1)(y – 1)(z – 1) = 140

    So we can consider factors of 140, to find x, y, z, and then find corresponding values for a, b.

    The only solution is (x, y, z) = (15, 6, 3) and (a, b, c) = (13, 10, 1).

    So the first block consists of 130 bricks, and the second of 270 bricks, giving 400 bricks in total, which will fit nicely into a 20″×20″ tray.

    This Python 3 program finds the solution in 50ms.

    from enigma import irange, divisor_pairs, printf
    
    # generate k-tuples of different divisors of n
    def divisor_tuples(n, k, s=()):
      if k == 1:
        if not(s) or n > s[-1]:
          yield s + (n,)
      else:
        for (a, b) in divisor_pairs(n):
          if not(s) or a > s[-1]:
            yield from divisor_tuples(b, k - 1, s + (a,))
    
    # find x1 > y1 > z1 > 0, where x1 * y1 * z1 = 140
    for (z1, y1, x1) in divisor_tuples(140, 3):
    
      # calculate the dimensions of the second block
      (x, y, z) = (x1 + 1, y1 + 1, z1 + 1)
    
      # the volumes of the blocks, and the total volume v
      v2 = x * y * z
      v1 = v2 - 140
      v = v1 + v2
    
      # find a > b > 1, where a * b = v1
      for (b, a) in divisor_tuples(v1, 2):
    
        # check the perimeter and surface area constraints
        if not(x + y + z == a + b + 1): continue
        if not(x * y + x * z + y * z == a * b + a + b): continue
    
        # check the dimensions are all different
        if len(set((x, y, z, a, b, 1))) != 6: continue
    
        printf("v={v} [v1={v1}: ({a}, {b}, 1), v2={v2}: ({x}, {y}, {z})]")
    

    Solution: There were 400 bricks in total.

    Note that the divisor_tuples(n, k) function generates tuples of different divisors, to make it a more general analogue of divisor_pairs(n) the tests need to be modified to return tuples containing repeated divisors.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: