平衡三進記数法

任意の整数について、平衡三進記法の各桁の trit を収めた配列を返すメソッド - Smalltalkのtは小文字ですSmalltalk のコードをベタ移植して、PHPPython でも整数を 1, 0, -1 の配列(タプル)として返す関数を書いてみました。
平衡三進記数法という呼び方を知ったのはつい最近なのですが、以前から 1, 0, -1 で数を表すのは美しいと思っていたので、実際にそういう考え方があると知ったときはちょっと嬉しかったです。

PHP

<?php

function balanced_trits($num)
{
    $num = (int)$num;
    if ($num == 0) {
        return array(0);
    }
    $abs = abs($num);
    $pow = (pow(3, floor(log($abs * 2, 3)) + 1) - 1) / 2;
    $tri = base_convert((string)($abs + $pow), 10, 3);
    $len = strlen($tri);
    $ret = array();
    if ($num > 0) {
        for ($i = 0; $i < $len; $i++) {
            $ret[] = (int)$tri[$i] - 1;
        }
    } else {
        for ($i = 0; $i < $len; $i++) {
            $ret[] = 1 - (int)$tri[$i];
        }
    }
    return $ret;
}

if (realpath($_SERVER['argv'][0]) == __FILE__) {
    for ($i = -15; $i <= 15; $i++) {
        printf("%d: (%s)\n", $i, implode(', ', balanced_trits($i)));
    }
}

?>

Python

#!/usr/bin/env python

import math

def balanced_trits(n):
    '''>>> balanced_trits(6)
    (1, -1, 0)
    
    Returns the balanced ternary as a tuple of trits.'''
    n = int(n)
    if n == 0:
        return (0,)
    d = abs(n)
    d += (3 ** int(math.floor(math.log(d * 2, 3)) + 1) - 1) / 2
    t = []
    while d:
        (d, m) = divmod(d, 3)
        t.append(m)
    if n > 0:
        return tuple(i - 1 for i in reversed(t))
    else:
        return tuple(1 - i for i in reversed(t))

if __name__ == '__main__':
    for i in range(-15, 16):
        print "%d: %s" % (i, repr(balanced_trits(i)))