Welcome, guest | Sign In | My Account | Store | Cart
"Graph the progression towards Kaprekar's constant"

from collections import Counter

class Cache(dict):
    'Single variable caching decorator, accessible as a dictionary'
    def __init__(self, func):
        self.func = func
    __call__ = dict.__getitem__
    def __missing__(self, key):
        result = self[key] = self.func(key)
        return result

@Cache
def step(n):
    'Do a single step in the Kaprekar process'
    # http://en.wikipedia.org/wiki/6174_(number)
    s = format(n, '04d')        # 1253          --> '1253'
    t = ''.join(sorted(s))      # '1253'        --> '1235'
    u = t[::-1]                 # '1235'        --> '5321'
    return int(u) - int(t)      # (5321 - 1235) --> 4086

main_template = '''
digraph kaprekar {
    rankdir=LR;
%s
%s
}
'''
node_template = '    "%s" [label="%s: %s"];\n'
pair_template = '    "%s" -> "%s";\n'

def make_graph(show_counts=True):
    'Generate a dot file'
    # python analyze_6174.py | dot -Tpng > a6174.png && open a6174.png

    for i in range(10000):
        step(i)
    outs = Counter(step.values())  # only show destination nodes
    nodes = []
    if show_counts:
        nodes = [node_template % (i, c, i) for i, c in outs.items()]
    results = results = [pair_template % (i, step(i)) for i in outs]
    return main_template % (''.join(nodes), ''.join(results))

if __name__ == '__main__':
    print make_graph(show_counts=True)

History