Balanced ternary numbers

TrustyTony 1 Tallied Votes 948 Views Share

Here is my take on balanced ternary conversion (the base considered by Donald Knuth "Maybe the prettiest")

def val(number_sequence, base):
    """ produce integer value of number_sequence as base number """
    return sum(int(n) * base ** p for p, n in enumerate(reversed(number_sequence)))

def balanced_ternary_value(number):
    """ produce integer value of balanced ternary number """
    return val([(-1 if c == '-' else (1 if c == '+' else 0))
                for c in str(number)], 3)

def make_balanced(n):
    """ Make balanced ternary by doing carry at
        2 and using identity 2 = 3 + -1
    """
    n = int(n)
    if not n:
        return '0'
    else:
        digits = ''
        while n:
            n, this = divmod(n, 3)
            if this == 2:
                n += 1
            digits = '0+-'[this] + digits
    return digits

class BalancedTernary(long):
    def __new__(cls, n):
        instance = long.__new__(cls,
                     balanced_ternary_value(n)
                      if isinstance(n, str) else n)
        return instance
       
    def __repr__(self):
        return make_balanced(self)

    __str__ = __repr__
    

if __name__  == '__main__':
    print('%10s %10s' % ('dec', 'balanced ternary'))
    for t in range(-27,+28):
        print('%10s %10s' % (t, BalancedTernary(t)))
        assert balanced_ternary_value(str(BalancedTernary(t))) == t

    print balanced_ternary_value('++-0+')
    print BalancedTernary('++-0+'), int(BalancedTernary('++-0+'))
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.