RosettaCodeData/Task/Balanced-ternary/Icon/balanced-ternary.icon
2015-02-20 00:35:01 -05:00

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