90 lines
1.9 KiB
Text
90 lines
1.9 KiB
Text
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
|