procedure main() a := "+-0++0+" write("a = +-0++0+"," = ",cvtFromBT("+-0++0+")) write("b = -436 = ",b := cvtToBT(-436)) c := "+-++-" write("c = +-++- = ",cvtFromBT("+-++-")) d := mul(a,sub(b,c)) write("a(b-c) = ",d," = ",cvtFromBT(d)) end procedure bTrim(s) return s[upto('+-',s):0] | "0" end procedure cvtToBT(n) if n=0 then return "0" if n<0 then return map(cvtToBT(-n),"+-","-+") return bTrim(case n%3 of { 0: cvtToBT(n/3)||"0" 1: cvtToBT(n/3)||"+" 2: cvtToBT((n+1)/3)||"-" }) end procedure cvtFromBT(n) sum := 0 i := -1 every c := !reverse(n) do { sum +:= case c of { "+" : 1 "-" : -1 "0" : 0 }*(3^(i+:=1)) } return sum end procedure neg(n) return map(n,"+-","-+") end procedure add(a,b) if *b > *a then a :=: b b := repl("0",*a-*b)||b c := "0" sum := "" every place := 1 to *a do { ds := addDigits(a[-place],b[-place],c) c := if *ds > 1 then c := ds[1] else "0" sum := ds[-1]||sum } return bTrim(c||sum) end procedure addDigits(a,b,c) sum1 := addDigit(a,b) sum2 := addDigit(sum1[-1],c) if *sum1 = 1 then return sum2 if *sum2 = 1 then return sum1[1]||sum2 return sum1[1] end procedure addDigit(a,b) return case(a||b) of { "00"|"0+"|"0-": b "+0"|"-0" : a "++" : "+-" "+-"|"-+" : "0" "--" : "-+" } end procedure sub(a,b) return add(a,neg(b)) end procedure mul(a,b) if b[1] == "-" then { b := neg(b) negate := "yes" } b := cvtFromBT(b) i := "+" mul := "0" while cvtFromBT(i) <= b do { mul := add(mul,a) i := add(i,"+") } return (\negate,map(mul,"+-","-+")) | mul end