Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -61,12 +61,12 @@ loop{n:nat}
//
if isneqz(inp)
then let
val c = inp.head
val c = inp.head()
val d =
(case- c of '+' => P | '0' => Z | '-' => N): btd
// end of [val]
in
loop (inp.tail, list_cons(d, ds))
loop (inp.tail(), list_cons(d, ds))
end // end of [then]
else ds // end of [else]
//

View file

@ -0,0 +1,74 @@
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}"

View file

@ -1,55 +1,56 @@
/*REXX pgm converts decimal ◄───► balanced ternary; also performs arith.*/
numeric digits 10000 /*handle almost any size numbers.*/
Ao = '+-0++0+' ; Abt = Ao /* [↓] 2 literals used by sub.*/
Bo = '-436' ; Bbt = d2bt(Bo) ; @ = '(decimal)'
Co = '+-++-' ; Cbt = Co ; @@ = 'balanced ternary ='
/*REXX pgm converts decimal ◄───► balanced ternary; also performs arithmetic.*/
numeric digits 10000 /*be able to handle gihugic numbers. */
Ao = '+-0++0+' ; Abt = Ao /* [↓] 2 literals used by subroutine*/
Bo = '-436' ; Bbt = d2bt(Bo) ; @ = '(decimal)'
Co = '+-++-' ; Cbt = Co ; @@ = 'balanced ternary ='
call btShow '[a]', Abt
call btShow '[b]', Bbt
call btShow '[c]', Cbt
say; $bt = btMul(Abt,btSub(Bbt,Cbt))
call btshow '[a*(b-c)]', $bt
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────BT2D subroutine─────────────────────*/
d2bt: procedure; parse arg x 1; p=0; $.='-'; $.1='+'; $.0=0; #=
x=x/1
do until x==0; _=(x//(3**(p+1)))%3**p
if _==2 then _=-1; if _=-2 then _=1
x=x-_*(3**p); p=p+1; #=$._ || #
end /*until*/
return #
/*──────────────────────────────────BT2D subroutine─────────────────────*/
bt2d: procedure; parse arg x; r=reverse(x); #=0; $.=-1; $.0=0; _='+'; $._=1
do j=1 for length(x); _=substr(r,j,1); #=#+$._*3**(j-1); end
return #
/*──────────────────────────────────BTADD subroutine────────────────────*/
btAdd: procedure; parse arg x,y; rx=reverse(x); ry=reverse(y); carry=0
$.='-'; $.0=0; $.1='+'; @.=0; _='-'; @._=-1; _="+"; @._=1; #=
do j=1 for max(length(x),length(y))
x_=substr(rx,j,1); xn=@.x_
y_=substr(ry,j,1); yn=@.y_
s=xn+yn+carry ; carry=0
if s== 2 then do; s=-1; carry= 1; end
if s== 3 then do; s= 0; carry= 1; end
if s==-2 then do; s= 1; carry=-1; end
#=$.s || #
end /*j*/
if carry\==0 then #=$.carry || #; return btNorm(#)
/*──────────────────────────────────BTMUL subroutine────────────────────*/
btMul: procedure; parse arg x,y; if x==0 | y==0 then return 0; S=1
x=btNorm(x); y=btNorm(y) /*handle: 0-xxx values.*/
if left(x,1)=='-' then do; x=btNeg(x); S=-S; end /*positate.*/
if left(y,1)=='-' then do; y=btNeg(y); S=-S; end /*positate.*/
if length(y)>length(x) then parse value x y with y x /*optimize.*/
call btShow '[a*(b-c)]', $bt
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
d2bt: procedure; parse arg x 1; p=0; $.='-'; $.1='+'; $.0=0; #=
x=x/1
do until x==0; _=(x//(3**(p+1)))%3**p
if _== 2 then _= -1
if _== -2 then _= 1
x=x-_*(3**p); p=p+1; #=$._ || #
end /*until ···*/
return #
/*────────────────────────────────────────────────────────────────────────────*/
bt2d: procedure; parse arg x; r=reverse(x); #=0; $.=-1; $.0=0; _='+'; $._=1
do j=1 for length(x); _=substr(r,j,1); #=#+$._*3**(j-1); end
return #
/*────────────────────────────────────────────────────────────────────────────*/
btAdd: procedure; parse arg x,y; rx=reverse(x); ry=reverse(y); carry=0
@.=0 ; _='-'; @._=-1; _="+"; @._=1
$.='-'; $.0=0; $.1='+'
#=; do j=1 for max(length(x),length(y))
x_=substr(rx,j,1); xn=@.x_
y_=substr(ry,j,1); yn=@.y_
s=xn+yn+carry ; carry= 0
if s== 2 then do; s=-1; carry= 1; end
if s== 3 then do; s= 0; carry= 1; end
if s==-2 then do; s= 1; carry=-1; end
#=$.s || #
end /*j*/
if carry\==0 then #=$.carry||#; return btNorm(#)
/*────────────────────────────────────────────────────────────────────────────*/
btMul: procedure; parse arg x 1 x1 2, y 1 y1 2; if x==0 | y==0 then return 0
S=1; x=btNorm(x); y=btNorm(y) /*handle: 0-xxx values.*/
if x1=='-' then do; x=btNeg(x); S=-S; end /*positate.*/
if y1=='-' then do; y=btNeg(y); S=-S; end /* " */
if length(y)>length(x) then parse value x y with y x /*optimize.*/
P=0
do until y==0 /*keep adding 'til done*/
P=btAdd(P,x) /*multiple the hard way*/
y=btSub(y,'+') /*subtract 1 from Y. */
end /*until*/
if S==-1 then P=btNeg(P) /*adjust product sign. */
return P /*return the product P.*/
/*───────────────────────────────one-line subroutines───────────────────*/
btNeg: return translate(arg(1), '-+', "+-") /*negate the bal_tern #*/
btNorm: _=strip(arg(1),'L',0); if _=='' then _=0; return _ /*normalize*/
btSub: return btAdd(arg(1), btNeg(arg(2))) /*subtract two BT args.*/
do until y==0 /*keep adding 'til done*/
P=btAdd(P,x) /*multiple the hard way*/
y=btSub(y,'+') /*subtract 1 from Y.*/
end /*until*/
if S==-1 then P=btNeg(P) /*adjust product sign. */
return P /*return the product P.*/
/*────────────────────────────────────────────────────────────────────────────*/
btNeg: return translate(arg(1), '-+', "+-") /*negate the bal_tern #*/
btNorm: _=strip(arg(1),'L',0); if _=='' then _=0; return _ /*normalize a #*/
btSub: return btAdd(arg(1), btNeg(arg(2))) /*subtract two BT args.*/
btShow: say center(arg(1),9) right(arg(2),20) @@ right(bt2d(arg(2)),9) @; return