Enigmatic Code

Programming Enigma Puzzles

Enigma 400: Potential difficulties

From New Scientist #1550, 5th March 1987 [link]

I asked Electrophorus what he was working on.

“You know that joining unlike terminals of a pair of batteries produces a voltage across the two free terminals equal to the sum of the voltages of the separate batteries. And connecting unlike terminals produces a voltage equal to the difference of the voltages of the separate batteries?”

“Yes”, I replied. “With a battery of 2 volts and one of 5 volts one obtains 3 volts (sources opposing) or 7 volts (sources reinforcing).”

“Well, before lunch I had three batteries, none of which had zero voltage, and a voltmeter with a holder that would accommodate only two batteries. So I measured the voltages across the free terminals of all possible pairwise combination of these three batteries both in the case where the voltages reinforced and where they opposed. I wrote on my blackboard the resulting six positive numbers in order of increasing magnitude.”

“When I returned from lunch eager to calculate the ratings of the three batteries, I found the three batteries gone and my blackboard wiped clean. I remember that the second smallest reading occurred twice. It was either 13 or 17 volts, I forget which. I had noticed, rather inconsequentially perhaps, that reversing the digits of this double reading produced another reading which occurred in my measurements.”

What were the ratings of the three batteries?



3 responses to “Enigma 400: Potential difficulties

  1. Jim Randell 16 June 2017 at 8:22 am

    The pairwise differences of the three numbers are all non-zero, so the numbers must all be different.

    This Python 3 program considers the three numbers by looking at increasing values for the total sum, and then breaking down that value into three different numbers, until it finds a set that satisfies the conditions.

    It runs in 66ms.

    from itertools import count, combinations
    from enigma import irange, flatten, printf
    # decompose the total <t> into <n> different numbers
    def decompose(t, n, s=[]):
      if n == 1:
        if not(s) or t > s[-1]:
          yield s + [t]
      elif n > 1:
        for x in irange((s[-1] + 1 if s else 1), t // n):
          yield from decompose(t - x, n - 1, s + [x])
    # consider possible total sum of all three batteries
    for t in count(6):
      for (a, b, c) in decompose(t, 3):
        # make the list of sums and differences
        s = flatten((x + y, y - x) for (x, y) in combinations((a, b, c), 2))
        ss = sorted(set(s))
        # the second smallest reading is 13 or 17, and occurs twice
        if not((ss[1] == 13 or ss[1] == 17) and s.count(ss[1]) == 2) : continue
        # and the reverse also occurs
        if not((ss[1] == 13 and 31 in s) or (ss[1] == 17 and 71 in s)): continue
        printf("a={a} b={b} c={c}, s={s}", s=sorted(s))

    Solution: The three batteries are 4V, 9V and 22V.

    The fact that the doubled reading occurs in the list with its digits reversed is not inconsequential. Without this fact there are 14 solutions.

  2. geoffrounce 16 June 2017 at 11:59 am
    # list of six possible voltages from three batteries
    vlist = []
    # b1, b2, b3 are the initial battery voltages
    for b1 in range(1, 50):
      for b2 in range(b1+1, 50):
        for b3 in range(b2+1, 50):
          # form six possible voltages of batteries
          v1, v2, v3 = b1 + b2, b2 - b1, b1 + b3
          v4, v5, v6 = b3 - b1, b2 + b3, b3 - b2
          # form a sorted list of six possible voltages
          vlist = [v1, v2, v3, v4, v5,  v6]
          vlist = sorted(vlist)
          # check 2nd and 3rd values are the same and are 13V or 17V
          if (vlist[1] == 13 and vlist[2] == 13) or \
            (vlist[1] == 17 and vlist[2] == 17):
            # and the 2nd or 3rd value(reversed) equals another value       
            if (str(vlist[1])[::-1] == str(vlist[0])) \
              or (str(vlist[1])[::-1] == str(vlist[3])) \
              or (str(vlist[1])[::-1] == str(vlist[4])) \
              or (str(vlist[1]) [::-1] == str(vlist[5])) :
                print('Battery values are : {}V, {}V, and {}V '.format(b1, b2, b3))
                print( 'Possible voltages are: ', vlist, 'volts')
    # Battery values are : 4V, 9V, and 22V 
    # Possible voltages are:  [5, 13, 13, 18, 26, 31] volts
  3. Brian Gladman 16 June 2017 at 2:30 pm
    from itertools import combinations as comb, count
    from sys import exit
    # the three battery voltages (a, b, c) are different
    # since all the measurements are positive
    for m in count(4):
      for c in range(3, m):
        for b in range(1, c):
          for a in range(1, b):
            # compose the sorted list of battery voltage sums/differences
            m = sorted(sum(([x + y, x - y] for y, x in comb((a, b, c), 2)), []))
            # check that the 2nd and 3rd voltages are equal and either 13 or 17
            if m[1] == m[2] and m[1] in {13, 17}:
              # ... and that the digit reversal of this value is listed
              if m[1] == 13 and 31 in m or m[1] == 17 and 71 in m:
                print(f'The batteries are {a}V, {b}V and {c}V.')

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: