75 lines
2.2 KiB
Plaintext
75 lines
2.2 KiB
Plaintext
defmodule Ternary do
|
|
def to_string(t), do: ( for x <- t, do: to_char(x) ) |> List.to_string
|
|
|
|
def from_string(s), do: ( for x <- to_char_list(s), do: from_char(x) )
|
|
|
|
defp to_char(-1), do: ?-
|
|
defp to_char(0), do: ?0
|
|
defp to_char(1), do: ?+
|
|
|
|
defp from_char(?-), do: -1
|
|
defp from_char(?0), do: 0
|
|
defp from_char(?+), do: 1
|
|
|
|
def to_ternary(n) when n > 0, do: to_ternary(n,[])
|
|
def to_ternary(n), do: neg(to_ternary(-n))
|
|
|
|
defp to_ternary(0,acc), do: acc
|
|
defp to_ternary(n,acc) when rem(n, 3) == 0, do: to_ternary(div(n, 3), [0|acc])
|
|
defp to_ternary(n,acc) when rem(n, 3) == 1, do: to_ternary(div(n, 3), [1|acc])
|
|
defp to_ternary(n,acc), do: to_ternary(div((n+1), 3), [-1|acc])
|
|
|
|
def from_ternary(t), do: from_ternary(t,0)
|
|
|
|
defp from_ternary([],acc), do: acc
|
|
defp from_ternary([h|t],acc), do: from_ternary(t, acc*3 + h)
|
|
|
|
def mul(a,b), do: mul(b,a,[])
|
|
|
|
defp mul(_,[],acc), do: acc
|
|
defp mul(b,[a|as],acc) do
|
|
bp = case a do
|
|
-1 -> neg(b)
|
|
0 -> [0]
|
|
1 -> b
|
|
end
|
|
a = add(bp, acc ++ [0])
|
|
mul(b,as,a)
|
|
end
|
|
|
|
defp neg(t), do: ( for h <- t, do: -h )
|
|
|
|
def sub(a,b), do: add(a,neg(b))
|
|
|
|
def add(a,b) when length(a) < length(b),
|
|
do: add(List.duplicate(0, length(b)-length(a)) ++ a, b)
|
|
def add(a,b) when length(a) > length(b), do: add(b,a)
|
|
def add(a,b), do: add(Enum.reverse(a), Enum.reverse(b), 0, [])
|
|
|
|
defp add([],[],0,acc), do: acc
|
|
defp add([],[],c,acc), do: [c|acc]
|
|
defp add([a|as],[b|bs],c,acc) do
|
|
[c1,d] = add_util(a+b+c)
|
|
add(as,bs,c1,[d|acc])
|
|
end
|
|
|
|
defp add_util(-3), do: [-1,0]
|
|
defp add_util(-2), do: [-1,1]
|
|
defp add_util(-1), do: [0,-1]
|
|
defp add_util(3), do: [1,0]
|
|
defp add_util(2), do: [1,-1]
|
|
defp add_util(1), do: [0,1]
|
|
defp add_util(0), do: [0,0]
|
|
end
|
|
|
|
as = "+-0++0+"; at = Ternary.from_string(as); a = Ternary.from_ternary(at)
|
|
b = -436; bt = Ternary.to_ternary(b); bs = Ternary.to_string(bt)
|
|
cs = "+-++-"; ct = Ternary.from_string(cs); c = Ternary.from_ternary(ct)
|
|
rt = Ternary.mul(at,Ternary.sub(bt,ct))
|
|
r = Ternary.from_ternary(rt)
|
|
rs = Ternary.to_string(rt)
|
|
IO.puts "a = #{as} -> #{a}"
|
|
IO.puts "b = #{bs} -> #{b}"
|
|
IO.puts "c = #{cs} -> #{c}"
|
|
IO.puts "a x (b - c) = #{rs} -> #{r}"
|