# 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]

### 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
```