Enigmatic Code

Programming Enigma Puzzles

Enigma 1159: Measure for measure

From New Scientist #2315, 3rd November 2001 [link]

I bought a few yards of expensive material recently and I suspected that I had been short-measured. So I took it to the local trading standards officer who measured it exactly in inches. She did not tell me the exact length but she did tell me that it involved two decimal places.

She then told me what the length was to the nearest inch (where exact halves are rounded up) and this did equal the whole number of yards which I had purchased.

Also, as required by a European directive, she changed her exact measurement in inches to centimetres (1 inch = 2.54 centimetres) and she told me the length of the material to the nearest centimetre.

From the things which she told me I was in fact able to work out the exact length of the material in inches and to see that I had actually been sold slightly more material than I had asked for.

How many yards of material had I asked for?

[enigma1159]

Advertisements

3 responses to “Enigma 1159: Measure for measure

  1. Jim Randell 11 July 2016 at 8:09 am

    This Python code looks for the smallest number of yards that satisfies the given conditions. It runs in 124ms.

    from itertools import count
    from collections import defaultdict
    from fractions import Fraction as F
    from enigma import irange, printf
    
    # number of yards
    for y in count(1):
    
      # actual length is correct to the nearest inch
      r = defaultdict(list)
      # consider delta of d/100 inches
      for d in irange(-50, 49):
        # but we require 2 decimal places
        if d % 10 == 0: continue
        # actual length in inches
        i = 36 * y + F(d, 100)
    
        # actual length in cm
        cm = i * F(254, 100)
    
        # record length to nearest inch and nearest cm
        k = (int(i + F(1,2)), int(cm + F(1, 2)))
        r[k].append(i)
    
      # look for unique solutions
      for ((i, cm), vs) in r.items():
        if len(vs) != 1: continue
        a = vs[0]
        # the actual amount exceeds the specified number of yards
        if not(a > i): continue
        # output a solution
        printf("{y} yards, {i} in, {cm} cm -> {a} inches", a=float(a))
        exit()
    

    Solution: I originally asked for 12 yards of material.

    12 yards is the smallest number that satisfies the conditions of the puzzle text, but so does 12 + 25k yards, for integer values of k ≥ 0.

    So the next smallest solution would be at 37 yards, which perhaps is a but much to count as “a few yards of material” (although I think 12 yards is leaving the realms of “a few” and entering “several yards of material” territory).

    • geoffrounce 17 July 2016 at 11:28 am

      I think the following notes show how critical the wording is in this Enigma,
      in respect of the statements “nearest inch” and “nearest cm”

      In order to understand better the answer to this Enigma, I explored Jim’s
      dictionary ‘r’ in more detail.

      Dictionary ‘r’ has keys as a tuple in the format (inches,cm) plus values in
      inches, expressed as a fraction.

      We can get the dictionary print-out and the number of values for each key
      by inserting a few lines of code, just before Jim’s exit() statement ie:

      for (k,v) in r.items():
            print(k,v, len(v))
            print()
      

      If we print out the (key,value) pairs in the dictionary ‘r’, we get:

      key (432, 1097) – 35 values

      key (432, 1099) – 1 value ie Fraction(43249, 100)

      key (432, 1096) – 18 values

      key (432, 1098) – 36 values

      Fraction(43249, 100) is 432.49 inches and is a unique value in the dictionary
      providing the solution to this Enigma.

      Also, 432.49 inches is 432.49 * 2.54 = 1098.5246 cm, which is rounded up to
      1099 cm, the nearest whole number of centimetres. 432.49 inches is also rounded
      down to 432 inches to the nearest whole number of inches, which is
      exactly 12 yards.

  2. Brian Gladman 11 July 2016 at 4:22 pm
    from itertools import count
    from collections import defaultdict
    
    # the amount asked for in yards
    for yards in count(1):
    
      # keep a count of lengths that have the same nearest 
      # integer length measured in centimetres
      cms_to_count = defaultdict(int)
    
      # the actual amount is slightly more by a multiple of a
      # hundredth of an inch but is correct to the nearest inch
      for extra in range(1, 50):
        
        # convert the actual length (in hundredths of an inch) to the
        # nearest whole number of centmetres and record in the map
        cms, rem = divmod(254 * (3600 * yards + extra), 10000)
        cms_to_count[cms + (1 if rem >= 5000 else 0)] += 1
    
      # find a unique length when measured to the nearest centimetre
      if 1 in cms_to_count.values():
        print('{} yards of material were requested.'.format(yards))
        break 
    

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: