任意の整数について、平衡三進記法の各桁の trit を収めた配列を返すメソッド - Smalltalkのtは小文字です の Smalltalk のコードをベタ移植して、PHP と Python でも整数を 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)))