Enigmatic Code

Programming Enigma Puzzles

Enigma 1132: Phone back

From New Scientist #2288, 28th April 2001 [link]

The PIN code on George’s cash card is a semi-prime number, that is to say it is the product of two different prime numbers. He discovered some time ago that the PIN code multiplied by his car registration number gives his six-digit phone number, which does not begin with a zero. But George has now discovered a slightly more obscure coincidence. If he subtracts his house number from his phone number and multiplies the result by his house number, the result is his phone number with its digits in reverse order!

What is George’s car registration number?

[enigma1132]

Advertisements

2 responses to “Enigma 1132: Phone back

  1. Jim Randell 16 January 2017 at 6:38 am

    The equation that relates the phone number and the house number is:

    (phone − house) × house = reverse(phone)

    Using p for the phone number, r for the reverse of the phone number, and h for the house number, we derive the following quadratic equation:

    h² − ph + r = 0

    Which has the following solutions for h using the standard quadratic formula:

    h = (p ± √(p² − 4r)) / 2

    This Python program looks for possible solutions for h for six-digit numbers p, and then looks at the prime factors of p to determine possible values for the PIN. It runs in 633ms.

    from itertools import combinations
    from enigma import irange, nreverse, is_square, prime_factor, printf
    
    # consider possible phone numbers
    for phone in irange(100000, 999999):
      # reverse it
      rev = nreverse(phone)
    
      # consider the sqrt(b^2 - 4ac) part of the quadratic solution
      x = is_square(phone * phone - 4 * rev)
      if x is None: continue
    
      # determine possible house numbers
      if phone % 2 != x % 2: continue
      house = [ (phone - x) // 2, (phone + x) // 2 ]
      printf("phone = {phone}, rev = {rev}, house = {house}")
    
      # find two different factors to make the PIN
      for (a, b) in combinations((p for (p, e) in prime_factor(phone)), 2):
        pin = a * b
        reg = phone // pin
        printf("  pin = {pin} ({a} * {b}), reg = {reg}")
    

    Solution: George’s car registration number is 127.

    The phone number is 499999, which factorises as (31 × 127 × 127).

    The PIN is therefore (31 × 127) = 3937, and the car registration number is 127.

    The reverse of the phone number is 999994.

    If the house number is h we have:

    (499999 − h) h = 999994
    h² − 499999h + 999994 = 0
    (h − 2)(h − 499997) = 0

    So the house number is either 2 or 499997. The first of these seems more likely.

    • Jim Randell 16 January 2017 at 6:44 am

      The following program uses the SubstitutedExpression() solver from the enigma.py library to find possible phone numbers using an Alphametic expression.

      from itertools import combinations
      from enigma import SubstitutedExpression, prime_factor, sprintf as f
      
      # consider the 6-digit phone number ABCDEF
      # the quadratic equation has solutions when:
      expr = "is_square(ABCDEF ** 2 - 4 * FEDCBA)"
      
      # find solutions to quadratic equation
      p = SubstitutedExpression(
        f("{expr} is not None"),
        # symbols used
        symbols='ABCDEF',
        # digits are not necessarily distinct
        distinct='',
        # the phone number doesn't start with 0
        d2i={ 0: 'A' },
        # return the phone number, it's reverse, and the value of expr
        answer=f("(ABCDEF, FEDCBA, {expr})"),
      )
      
      # solve the alphametic
      for (d, (phone, rev, x)) in p.solve():
      
        # determine possible house numbers
        if phone % 2 != x % 2: continue
        house = [ (phone - x) // 2, (phone + x) // 2 ]
        print(f("phone = {phone}, rev = {rev}, house = {house}"))
      
        # find two different factors to make the PIN
        for (a, b) in combinations((p for (p, e) in prime_factor(phone)), 2):
          pin = a * b
          reg = phone // pin
          print(f("  pin = {pin} ({a} * {b}), reg = {reg}"))
      

      I was pleasantly surprised to find that this program runs in just 187ms.

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: