Kevin Stock

Prime Number Card

September 9, 2017

Inspired by The Corpus Christi Prime, I created a prime personal contact card, shown below, with all zeros shown as dots. I added my birthday because my phone number doesn’t end in an odd number.

11....11.......................11..........
11...11....................................
11..11.....111111...77.....77..11..1111111.
11111.....11....11...77...77...11..11....11
11..11....11111111....77.77....11..11....11
11...11...11...........777.....11..11....11
11....11...1111111......7......11..11....11
...........................................
614.458.8382......................1.26.1987

This script can generate such a picture from a template by replacing each character with a digit.

#!/usr/bin/env python3

import fileinput
import random
from itertools import product

def decompose(n):
   exponentOfTwo = 0

   while n % 2 == 0:
      n = n//2
      exponentOfTwo += 1

   return exponentOfTwo, n

def isWitness(possibleWitness, p, exponent, remainder):
   possibleWitness = pow(possibleWitness, remainder, p)

   if possibleWitness == 1 or possibleWitness == p - 1:
      return False

   for _ in range(exponent):
      possibleWitness = pow(possibleWitness, 2, p)

      if possibleWitness == p - 1:
         return False

   return True

def probablyPrime(p, accuracy=100):
   if p == 2 or p == 3:
       return True
   if p < 2:
       return False

   exponent, remainder = decompose(p - 1)

   for _ in range(accuracy):
      possibleWitness = random.randint(2, p - 2)
      if isWitness(possibleWitness, p, exponent, remainder):
         return False

   return True

def main():
    template = ''
    rowlen = 0

    for line in fileinput.input():
        line = line.strip()
        template = template + line.strip()
        rowlen = len(line)

    template = template.replace('.', '0')

    nondigits = set()
    for c in template:
        if not c.isdigit():
            nondigits.add(c)
    nondigits = list(nondigits)

    it = 0
    for x in product(range(1,10), repeat=len(nondigits)):
        it += 1
        t = template[:]
        for c, v in zip(nondigits, x):
            t = t.replace(c, str(v))

        if probablyPrime(int(t)):
            print(''.join(str(v) for _, v in sorted(zip(nondigits, x))), it)
            for i in range(0, len(t), rowlen):
                print(t[i:i+rowlen])
            print()

if __name__ == '__main__':
    main()

Example template:

aa....aa.......................dd..........
aa...aa....................................
aa..aa.....bbbbbb...cc.....cc..dd..eeeeeee.
aaaaa.....bb....bb...cc...cc...dd..ee....ee
aa..aa....bbbbbbbb....cc.cc....dd..ee....ee
aa...aa...bb...........ccc.....dd..ee....ee
aa....aa...bbbbbbb......c......dd..ee....ee
...........................................
614.458.8382.....................01.26.1987