Balanced ternary: Difference between revisions

m
No edit summary
 
(23 intermediate revisions by 13 users not shown)
Line 25:
'''Note:''' The pages [[generalised floating point addition]] and [[generalised floating point multiplication]] have code implementing [[wp:arbitrary precision|arbitrary precision]] [[wp:floating point|floating point]] balanced ternary.
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">T BalancedTernary
. -:str2dig = [‘+’ = 1, ‘-’ = -1, ‘0’ = 0]
. -:dig2str = [1 = ‘+’, -1 = ‘-’, 0 = ‘0’]
. -:table = [(0, -1), (1, -1), (-1, 0), (0, 0), (1, 0), (-1, 1), (0, 1)]
 
[Int] digits
 
F (inp)
I all(inp.map(d -> d C (0, 1, -1)))
.digits = copy(inp)
E
X.throw ValueError(‘BalancedTernary: Wrong input digits.’)
 
F :from_str(inp)
R BalancedTernary(reversed(inp).map(c -> .:str2dig[c]))
 
. F :int2ternary(n)
I n == 0
R [Int]()
V n3 = ((n % 3) + 3) % 3
I n3 == 0 {R [0] [+] .:int2ternary(n -I/ 3)}
I n3 == 1 {R [1] [+] .:int2ternary(n -I/ 3)}
I n3 == 2 {R [-1] [+] .:int2ternary((n + 1) -I/ 3)}
X.throw RuntimeError(‘’)
 
F :from_int(inp)
R BalancedTernary(.:int2ternary(inp))
 
F to_int()
R reversed(.digits).reduce(0, (y, x) -> x + 3 * y)
 
F String()
I .digits.empty
R ‘0’
R reversed(.digits).map(d -> .:dig2str[d]).join(‘’)
 
. F :neg(digs)
R digs.map(d -> -d)
 
F -()
R BalancedTernary(.:neg(.digits))
 
. F :add(a, b, =c = 0)
I !(!a.empty & !b.empty)
I c == 0
R I !a.empty {a} E b
E
R .:add([c], I !a.empty {a} E b)
E
(V d, c) = .:table[3 + (I !a.empty {a[0]} E 0) + (I !b.empty {b[0]} E 0) + c]
V res = .:add(a[1..], b[1..], c)
I !res.empty | d != 0
R [d] [+] res
E
R res
 
F +(b)
R BalancedTernary(.:add(.digits, b.digits))
 
F -(b)
R (.) + (-b)
 
F *(b)
F _mul([Int] a, b) -> [Int]
I !(!a.empty & !b.empty)
R [Int]()
E
[Int] x
I a[0] == -1 {x = .:neg(b)}
E I a[0] == 0 {}
E I a[0] == 1 {x = b}
E
assert(0B)
V y = [0] [+] @_mul(a[1..], b)
R .:add(x, y)
 
R BalancedTernary(_mul(.digits, b.digits))
 
V a = BalancedTernary.from_str(‘+-0++0+’)
print(‘a: ’a.to_int()‘ ’a)
 
V b = BalancedTernary.from_int(-436)
print(‘b: ’b.to_int()‘ ’b)
 
V c = BalancedTernary.from_str(‘+-++-’)
print(‘c: ’c.to_int()‘ ’c)
 
V r = a * (b - c)
print(‘a * (b - c): ’r.to_int()‘ ’r)</syntaxhighlight>
 
{{out}}
<pre>
a: 523 +-0++0+
b: -436 -++-0--
c: 65 +-++-
a * (b - c): -262023 ----0+--0++0
</pre>
 
=={{header|Ada}}==
Specifications (bt.ads):
<langsyntaxhighlight Adalang="ada">with Ada.Finalization;
 
package BT is
Line 74 ⟶ 175:
procedure Finalize (Object : in out Balanced_Ternary);
end BT;</langsyntaxhighlight>
 
Implementation (bt.adb):
<langsyntaxhighlight Adalang="ada">with Ada.Unchecked_Deallocation;
 
package body BT is
Line 257 ⟶ 358:
end Initialize;
 
end BT;</langsyntaxhighlight>
 
Test task requirements (testbt.adb):
<langsyntaxhighlight Adalang="ada">with Ada.Text_Io; use Ada.Text_Io;
with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;
with BT; use BT;
Line 278 ⟶ 379:
Put("a * (b - c) = "); Put(To_integer(Result), 4);
Put_Line (" " & To_String(Result));
end TestBT;</langsyntaxhighlight>
Output:
<pre>
Line 296 ⟶ 397:
To demonstrate the possibility, the ''integerFromBT'' and ''negateBT'' handlers here work by being tricksy with the characters' Unicode numbers. It's a more efficient way to deal with the characters. But I'm not sure how this'll be taken ''vis-à-vis'' not converting to native integers first, so the remaining handlers use a strictly if-then string comparison approach. Applescript's quite happy to convert automatically between integers, reals, numeric strings, and single-item lists containing numbers, so ''BTFromInteger'' accepts any of these forms, but the numbers represented must be whole-number values and must be small enough not to error AppleScript's ''as integer'' coercion. This coercion is error free for numbers in the range -(2 ^ 31) to 2 ^ 31 - 1, although actual integer class objects can only represent numbers in the range -(2 ^ 29) to 2 ^ 29 - 1. ''IntegerFromBT'' doesn't currently impose any integer-class size limit on its output.
 
<langsyntaxhighlight lang="applescript">-- Build a balanced ternary, as text, from an integer value or acceptable AppleScript substitute.
on BTFromInteger(n)
try
Line 463 ⟶ 564:
set line4 to "a * (b - c) = " & it & " or " & my integerFromBT(it)
 
return line1 & linefeed & line2 & linefeed & line3 & linefeed & line4</langsyntaxhighlight>
 
{{output}}
<langsyntaxhighlight lang="applescript">"a = 523
b = -436
c = 65
a * (b - c) = ----0+--0++0 or -262023"</langsyntaxhighlight>
 
=={{header|ATS}}==
<syntaxhighlight lang="ats">
<lang ATS>
(*
** This one is
Line 686 ⟶ 787:
//
} (* end of [main0] *)
</syntaxhighlight>
</lang>
Output:
<pre>
Line 696 ⟶ 797:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">BalancedTernary(n){
k = 0
if abs(n)<2
Line 717 ⟶ 818:
}
return r
}</langsyntaxhighlight>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">data =
(
523
Line 728 ⟶ 829:
result .= A_LoopField " : " BalancedTernary(A_LoopField) "`n"
MsgBox % result
return</langsyntaxhighlight>
Outputs:<pre>
523 : +-0++0+
Line 734 ⟶ 835:
65 : +-++-
-262023 : ----0+--0++0</pre>
 
=={{header|Bruijn}}==
The default syntax sugar for numbers in bruijn is balanced ternary. The implementation of respective arithmetic operators is in <code>std/Number/Ternary</code> and <code>std/Math</code>. Converting between bases can be accomplished using <code>std/Number/Conversion</code>. The following is a library excerpt to show how to define the most common operators (succ,pred,add,sub,mul,eq) efficiently. They can be easily converted to the notation of pure lambda calculus (as originally by Torben Mogensen in "An Investigation of Compact and Efficient Number Representations in the Pure Lambda Calculus").
 
<syntaxhighlight lang="bruijn">
:import std/Combinator .
:import std/Logic .
:import std/Pair .
 
# negative trit indicating coefficient of (-1)
t⁻ [[[2]]]
 
# positive trit indicating coefficient of (+1)
t⁺ [[[1]]]
 
# zero trit indicating coefficient of 0
t⁰ [[[0]]]
 
# shifts a negative trit into a balanced ternary number
↑⁻‣ [[[[[2 (4 3 2 1 0)]]]]]
 
# shifts a positive trit into a balanced ternary number
↑⁺‣ [[[[[1 (4 3 2 1 0)]]]]]
 
# shifts a zero trit into a balanced ternary number
↑⁰‣ [[[[[0 (4 3 2 1 0)]]]]]
 
# shifts a specified trit into a balanced ternary number
…↑… [[[[[[5 2 1 0 (4 3 2 1 0)]]]]]]
 
# negates a balanced ternary number
-‣ [[[[[4 3 1 2 0]]]]]
 
# increments a balanced ternary number (can introduce leading 0s)
++‣ [~(0 z a⁻ a⁺ a⁰)]
z (+0) : (+1)
a⁻ &[[↑⁻1 : ↑⁰1]]
a⁺ &[[↑⁺1 : ↑⁻0]]
a⁰ &[[↑⁰1 : ↑⁺1]]
 
# decrements a balanced ternary number (can introduce leading 0s)
--‣ [~(0 z a⁻ a⁺ a⁰)]
z (+0) : (-1)
a⁻ &[[↑⁻1 : ↑⁺0]]
a⁺ &[[↑⁺1 : ↑⁰1]]
a⁰ &[[↑⁰1 : ↑⁻1]]
 
# converts the normal balanced ternary representation into abstract form
→^‣ [0 z a⁻ a⁺ a⁰]
z (+0)
a⁻ [[[[[2 4]]]]]
a⁺ [[[[[1 4]]]]]
a⁰ [[[[[0 4]]]]]
 
# converts the abstracted balanced ternary representation back to normal
→_‣ y [[0 z a⁻ a⁺ a⁰]]
z (+0)
a⁻ [↑⁻(2 0)]
a⁺ [↑⁺(2 0)]
a⁰ [↑⁰(2 0)]
 
# adds two balanced ternary numbers (can introduce leading 0s)
…+… [[[c (0 z a⁻ a⁺ a⁰)] 1 →^0]]
b⁻ [1 ↑⁺(3 0 t⁻) ↑⁰(3 0 t⁰) ↑⁻(3 0 t⁰)]
b⁰ [1 ↑ (3 0 t⁰)]
b⁺ [1 ↑⁰(3 0 t⁰) ↑⁻(3 0 t⁺) ↑⁺(3 0 t⁰)]
a⁻ [[[1 (b⁻ 1) b⁻' b⁰ b⁻]]]
b⁻' [1 ↑⁰(3 0 t⁻) ↑⁻(3 0 t⁰) ↑⁺(3 0 t⁻)]
a⁺ [[[1 (b⁺ 1) b⁰ b⁺' b⁺]]]
b⁺' [1 ↑⁺(3 0 t⁰) ↑⁰(3 0 t⁺) ↑⁻(3 0 t⁺)]
a⁰ [[[1 (b⁰ 1) b⁻ b⁺ b⁰]]]
z [[0 --(→_1) ++(→_1) →_1]]
c [[1 0 t⁰]]
 
# subtracts two balanced ternary numbers (can introduce leading 0s)
…-… [[1 + -0]]
 
# multiplicates two balanced ternary numbers (can introduce leading 0s)
…⋅… [[1 z a⁻ a⁺ a⁰]]
z (+0)
a⁻ [↑⁰0 - 1]
a⁺ [↑⁰0 + 1]
a⁰ [↑⁰0]
 
# true if balanced ternary number is zero
=?‣ [0 true [false] [false] i]
 
# true if two balanced ternary numbers are equal
# → ignores leading 0s!
…=?… [[[0 z a⁻ a⁺ a⁰] 1 →^0]]
z [=?(→_0)]
a⁻ [[0 false [2 0] [false] [false]]]
a⁺ [[0 false [false] [2 0] [false]]]
a⁰ [[0 (1 0) [false] [false] [2 0]]]
 
main [[0]]
 
# --- tests/examples ---
 
:test ((-42) + (-1) =? (-43)) (true)
:test ((+1) + (+2) =? (+3)) (true)
:test ((-42) - (-1) =? (-41)) (true)
:test ((+1) - (+2) =? (-1)) (true)
:test ((-1) ⋅ (+42) =? (-42)) (true)
:test ((+3) ⋅ (+11) =? (+33)) (true)
</syntaxhighlight>
 
=={{header|C}}==
{{trans|Perl}}
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <string.h>
 
Line 938 ⟶ 1,145:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre> a: +-0++0+ 523
Line 946 ⟶ 1,153:
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Text;
using System.Collections.Generic;
Line 1,176 ⟶ 1,383:
return result;
}
}</langsyntaxhighlight>
output:
<pre>a: +-0++0+ = 523
Line 1,184 ⟶ 1,391:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <string>
#include <climits>
Line 1,396 ⟶ 1,603:
return 0;
}
</syntaxhighlight>
</lang>
 
Output
Line 1,408 ⟶ 1,615:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">;;; balanced ternary
;;; represented as a list of 0, 1 or -1s, with least significant digit first
Line 1,500 ⟶ 1,707:
(bt-integer b) (bt-string b)
(bt-integer c) (bt-string c)
(bt-integer d) (bt-string d)))</langsyntaxhighlight>output<syntaxhighlight lang="text">a 523 +-0++0+
b -436 -++-0--
c 65 +-++-
a × (b − c) = -262023 ----0+--0++0</langsyntaxhighlight>
 
=={{header|D}}==
{{trans|Python}}
<langsyntaxhighlight lang="d">import std.stdio, std.bigint, std.range, std.algorithm;
 
struct BalancedTernary {
Line 1,650 ⟶ 1,857:
const /*immutable*/ r = a * (b - c);
writeln("a * (b - c): ", r.toBint, ' ', r);
}</langsyntaxhighlight>
{{out}}
<pre>a: 523 +-0++0+
Line 1,659 ⟶ 1,866:
=={{header|Elixir}}==
{{trans|Erlang}}
<langsyntaxhighlight lang="elixir">defmodule Ternary do
def to_string(t), do: ( for x <- t, do: to_char(x) ) |> List.to_string
Line 1,732 ⟶ 1,939:
IO.puts "b = #{bs} -> #{b}"
IO.puts "c = #{cs} -> #{c}"
IO.puts "a x (b - c) = #{rs} -> #{r}"</langsyntaxhighlight>
 
{{out}}
Line 1,743 ⟶ 1,950:
 
=={{header|Erlang}}==
<langsyntaxhighlight lang="erlang">
-module(ternary).
-compile(export_all).
Line 1,833 ⟶ 2,040:
add_util(1) -> [0,1];
add_util(0) -> [0,0].
</syntaxhighlight>
</lang>
'''Output'''
<langsyntaxhighlight lang="erlang">
234> ternary:test().
A = +-0++0+ -> 523
Line 1,842 ⟶ 2,049:
A x (B - C) = 0----0+--0++0 -> -262023
ok
</syntaxhighlight>
</lang>
 
 
 
=={{header|Factor}}==
{{trans|Ruby}}
{{trans|Common Lisp}}
{{works with|Factor|0.98}}
<syntaxhighlight lang="factor">USING: kernel combinators locals formatting lint literals
sequences assocs strings arrays
math math.functions math.order ;
IN: rosetta-code.bt
CONSTANT: addlookup {
{ 0 CHAR: 0 }
{ 1 CHAR: + }
{ -1 CHAR: - }
}
 
<PRIVATE
 
: bt-add-digits ( a b c -- d e )
+ + 3 +
{ { 0 -1 } { 1 -1 } { -1 0 } { 0 0 } { 1 0 } { -1 1 } { 0 1 } }
nth first2
;
 
PRIVATE>
 
! Conversion
: bt>integer ( seq -- x ) 0 [ swap 3 * + ] reduce ;
: integer>bt ( x -- x ) [ dup zero? not ] [
dup 3 rem {
{ 0 [ 3 / 0 ] }
{ 1 [ 3 / round 1 ] }
{ 2 [ 1 + 3 / round -1 ] }
} case
] produce nip reverse
;
: bt>string ( seq -- str ) [ addlookup at ] map >string ;
: string>bt ( str -- seq ) [ addlookup value-at ] { } map-as ;
 
! Arithmetic
: bt-neg ( a -- -a ) [ neg ] map ;
:: bt-add ( u v -- w )
u v max-length :> maxl
u v [ maxl 0 pad-head reverse ] bi@ :> ( u v )
0 :> carry!
u v { } [ carry bt-add-digits carry! prefix ] 2reduce
carry prefix [ zero? ] trim-head
;
: bt-sub ( u v -- w ) bt-neg bt-add ;
:: bt-mul ( u v -- w ) u { } [
{
{ -1 [ v bt-neg ] }
{ 0 [ { } ] }
{ 1 [ v ] }
} case bt-add 0 suffix
] reduce
1 head*
;
 
[let
"+-0++0+" string>bt :> a
-436 integer>bt :> b
"+-++-" string>bt :> c
b c bt-sub a bt-mul :> d
"a" a bt>integer a bt>string "%s: %d, %s\n" printf
"b" b bt>integer b bt>string "%s: %d, %s\n" printf
"c" c bt>integer c bt>string "%s: %d, %s\n" printf
"a*(b-c)" d bt>integer d bt>string "%s: %d, %s\n" printf
]</syntaxhighlight>
<syntaxhighlight lang="text">a: 523, +-0++0+
b: -436, -++-0--
c: 65, +-++-
a*(b-c): -262023, ----0+--0++0</syntaxhighlight>
 
=={{header|FreeBASIC}}==
{{trans|Liberty BASIC}}
<syntaxhighlight lang="freebasic">
#define MAX(a, b) iif((a) > (b), (a), (b))
Dim Shared As Integer pow, signo
Dim Shared As String t
t = "-0+"
 
Function deci(cadena As String) As Integer
Dim As Integer i, deci1
Dim As String c1S
pow = 1
For i = Len(cadena) To 1 Step -1
c1S = Mid(cadena,i,1)
signo = Instr(t, c1S)-2
deci1 = deci1 + pow * signo
pow *= 3
Next i
Return deci1
End Function
 
Function ternary(n As Integer) As String
Dim As String ternario
Dim As Integer i, k
While Abs(n) > 3^k/2
k += 1
Wend
k -= 1
pow = 3^k
For i = k To 0 Step -1
signo = (n>0) - (n<0)
signo *= (Abs(n) > pow/2)
ternario += Mid(t,signo+2,1)
n -= signo*pow
pow /= 3
Next
If ternario = "" Then ternario = "0"
Return ternario
End Function
 
Function negate(cadena As String) As String
Dim As String negar = ""
For i As Integer = 1 To Len(cadena)
negar += Mid(t, 4-Instr(t, Mid(cadena,i,1)), 1)
Next i
Return negar
End Function
 
Function pad(cadenaA As String, n As Integer) As String
Dim As String relleno = cadenaA
While Len(relleno) < n
relleno = "0" + relleno
Wend
Return relleno
End Function
 
Function addTernary(cadenaA As String, cadenaB As String) As String
Dim As Integer l = max(Len(cadenaA), Len(cadenaB))
Dim As Integer i, x, y, z
cadenaA = pad(cadenaA, l)
cadenaB = pad(cadenaB, l)
Dim As String resultado = ""
Dim As Byte llevar = 0
For i = l To 1 Step -1
x = Instr(t, Mid(cadenaA,i,1))-2
y = Instr(t, Mid(cadenaB,i,1))-2
z = x + y + llevar
If Abs(z) < 2 Then
llevar = 0
Elseif z > 0 Then
llevar = 1: z -= 3
Elseif z < 0 Then
llevar = -1: z += 3
End If
resultado = Mid(t,z+2,1) + resultado
Next i
If llevar <> 0 Then resultado = Mid(t,llevar+2,1) + resultado
 
i = 0
While Mid(resultado,i+1,1) = "0"
i += 1
Wend
resultado = Mid(resultado,i+1)
If resultado = "" Then resultado = "0"
Return resultado
End Function
 
Function subTernary(cadenaA As String, cadenaB As String) As String
Return addTernary(cadenaA, negate(cadenaB))
End Function
 
Function multTernary(cadenaA As String, cadenaB As String) As String
Dim As String resultado = ""
Dim As String tS = "", cambio = ""
For i As Integer = Len(cadenaA) To 1 Step -1
Select Case Mid(cadenaA,i,1)
Case "+": tS = cadenaB
Case "0": tS = "0"
Case "-": tS = negate(cadenaB)
End Select
resultado = addTernary(resultado, tS + cambio)
cambio += "0"
Next i
Return resultado
End Function
 
 
Dim As String cadenaA = "+-0++0+"
Dim As Integer a = deci(cadenaA)
Print " a:", a, cadenaA
 
Dim As Integer b = -436
Dim As String cadenaB = ternary(b)
Print " b:", b, cadenaB
 
Dim As String cadenaC = "+-++-"
Dim As Integer c = deci(cadenaC)
Print " c:", c, cadenaC
 
'calcular en ternario
Dim As String resS = multTernary(cadenaA, subTernary(cadenaB, cadenaC))
Print "a*(b-c):", deci(resS), resS
 
Print !"\nComprobamos:"
Print "a*(b-c): ", a * (b - c)
Sleep
</syntaxhighlight>
{{out}}
<pre>
a: 523 +-0++0+
b: -436 -++-0--
c: 65 +-++-
a*(b-c): -262023 ----0+--0++0
Comprobamos:
a*(b-c): -262023
</pre>
 
=={{header|Glagol}}==
Line 1,962 ⟶ 2,384:
</pre>
'''A crude English/Pidgin Algol translation of the above [[:Category:Glagol]] code.'''
<langsyntaxhighlight lang="algol68">PROGRAM Setun+;
USES
Parameter IS "...\Departments\Exchange\"
Line 2,074 ⟶ 2,496:
Output.ChTarget(" = %d.", InNumber(), 0, 0, 0);
Remove.Memory
END Setun.</langsyntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 2,300 ⟶ 2,722:
fmt.Println("int overflow")
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,311 ⟶ 2,733:
=={{header|Groovy}}==
Solution:
<langsyntaxhighlight lang="groovy">enum T {
m('-', -1), z('0', 0), p('+', 1)
 
Line 2,470 ⟶ 2,892:
 
String toString() { value }
}</langsyntaxhighlight>
 
Test:
<langsyntaxhighlight lang="groovy">BalancedTernaryInteger a = new BalancedTernaryInteger('+-0++0+')
BalancedTernaryInteger b = new BalancedTernaryInteger(-436)
BalancedTernaryInteger c = new BalancedTernaryInteger(T.p, T.m, T.p, T.p, T.m)
Line 2,488 ⟶ 2,910:
 
println "\nDemonstrate failure:"
assert (a * (b-c)) == a</langsyntaxhighlight>
 
Output:
Line 2,513 ⟶ 2,935:
=={{header|Haskell}}==
BTs are represented internally as lists of digits in integers from -1 to 1, but displayed as "+-0" strings.
<langsyntaxhighlight lang="haskell">data BalancedTernary = Bt [Int]
 
zeroTrim a = if null s then [0] else s where
Line 2,570 ⟶ 2,992:
print $ map btInt [a,b,c]
print $ r
print $ btInt r</langsyntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
Line 2,577 ⟶ 2,999:
 
Works in both languages:
<langsyntaxhighlight lang="unicon">procedure main()
a := "+-0++0+"
write("a = +-0++0+"," = ",cvtFromBT("+-0++0+"))
Line 2,666 ⟶ 3,088:
}
return (\negate,map(mul,"+-","-+")) | mul
end</langsyntaxhighlight>
 
Output:
Line 2,682 ⟶ 3,104:
Implementation:
 
<langsyntaxhighlight lang="j">trigits=: 1+3 <.@^. 2 * 1&>.@|
trinOfN=: |.@((_1 + ] #: #.&1@] + [) #&3@trigits) :. nOfTrin
nOfTrin=: p.&3 :. trinOfN
Line 2,693 ⟶ 3,115:
add=: carry@(+/@,:)
neg=: -
mul=: trimLead0@carry@(+//.@(*/))</langsyntaxhighlight>
 
trinary numbers are represented as a sequence of polynomial coefficients. The coefficient values are limited to 1, 0, and -1. The polynomial's "variable" will always be 3 (which happens to illustrate an interesting absurdity in the terminology we use to describe polynomials -- one which might be an obstacle for learning, for some people).
Line 2,705 ⟶ 3,127:
<code>trimLead0</code> removes leading zeros from a sequence of polynomial coefficients.
 
<code>add</code> adds these polynomials.<br />
<code>neg</code> negates these polynomials. Note that it's just a name for J's <code>-</code>.<br />
<code>mul</code> multiplies these polynomials.<br />
 
Definitions for example:
 
<langsyntaxhighlight lang="j">a=: trinOfStr '+-0++0+'
b=: trinOfN -436
c=: trinOfStr '+-++-'</langsyntaxhighlight>
 
Required example:
 
<langsyntaxhighlight lang="j"> nOfTrin&> a;b;c
523 _436 65
 
Line 2,723 ⟶ 3,145:
----0+--0++0
nOfTrin a mul b (add -) c
_262023</langsyntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">
/*
* Test case
Line 2,938 ⟶ 3,360:
}
}
</syntaxhighlight>
</lang>
 
Output:
Line 2,947 ⟶ 3,369:
 
result= ----0+--0++0 -262023
</pre>
 
=={{header|jq}}==
{{Works with|jq}}
 
'''Works with gojq, the Go implementation of jq'''
 
'''Adapted from [[#Wren|Wren]]'''
<syntaxhighlight lang="jq">
### Generic utilities
 
# Emit a stream of the constituent characters of the input string
def chars: explode[] | [.] | implode;
 
# Flip "+" and "-" in the input string, and change other characters to 0
def flip:
{"+": "-", "-": "+"} as $t
| reduce chars as $c (""; . + ($t[$c] // "0") );
 
### Balanced ternaries (BT)
 
# Input is assumed to be an integer (use `new` if checking is required)
def toBT:
# Helper - input should be an integer
def mod3:
if . > 0 then . % 3
else ((. % 3) + 3) % 3
end;
 
if . < 0 then - . | toBT | flip
else if . == 0 then ""
else mod3 as $rem
| if $rem == 0 then (. / 3 | toBT) + "0"
elif $rem == 1 then (. / 3 | toBT) + "+"
else ((. + 1) / 3 | toBT) + "-"
end
end
| sub("^00*";"")
| if . == "" then "0" end
end ;
 
# Input: BT
def integer:
. as $in
| length as $len
| { sum: 0,
pow: 1 }
| reduce range (0;$len) as $i (.;
$in[$len-$i-1: $len-$i] as $c
| (if $c == "+" then 1 elif $c == "-" then -1 else 0 end) as $digit
| if $digit != 0 then .sum += $digit * .pow else . end
| .pow *= 3 )
| .sum ;
 
# If the input is a string, check it is a valid BT, and trim leading 0s;
# if the input is an integer, convert it to a BT;
# otherwise raise an error.
def new:
if type == "string" and all(chars; IN("0", "+", "-"))
then sub("^00*"; "") | if . == "" then "0" end
elif type == "number" and trunc == .
then toBT
else "'new' given invalid input: \(.)" | error
end;
 
# . + $b
def plus($b):
# Helper functions:
def at($i): .[$i:$i+1];
# $a and $b should each be "0", "+" or "-"
def addDigits2($a; $b):
if $a == "0" then $b
elif $b == "0" then $a
elif $a == "+"
then if $b == "+" then "+-" else "0" end
elif $b == "+" then "0" else "-+"
end;
def addDigits3($a; $b; $carry):
addDigits2($a; $b) as $sum1
| addDigits2($sum1[-1:]; $carry) as $sum2
| if ($sum1|length) == 1
then $sum2
elif ($sum2|length) == 1
then $sum1[0:1] + $sum2
else $sum1[0:1]
end;
{ longer: (if length > ($b|length) then . else $b end),
shorter: (if length > ($b|length) then $b else . end) }
| until ( (.shorter|length) >= (.longer|length); .shorter = "0" + .shorter )
| .a = .longer
| .b = .shorter
| .carry = "0"
| .sum = ""
| reduce range(0; .a|length) as $i (.;
( (.a|length) - $i - 1) as $place
| addDigits3(.a | at($place); .b | at($place); .carry) as $digisum
| .carry = (if ($digisum|length) != 1 then $digisum[0:1] else "0" end)
| .sum = $digisum[-1:] + .sum )
| .carry + .sum
| new;
 
def minus: flip;
 
# . - $b
def minus($b): plus($b | flip);
 
def mult($b):
(1 | new) as $one
| (0 | new) as $zero
| { a: .,
$b,
mul: $zero,
flipFlag: false }
| if .b[0:1] == "-" # i.e. .b < 0
then .b |= minus
| .flipFlag = true
end
| .i = $one
| .in = 1
| (.b | integer) as $bn
| until ( .in > $bn;
.a as $a
| .mul |= plus($a)
| .i |= plus($one)
| .in += 1 )
| if .flipFlag then .mul | minus else .mul end ;
 
 
### Illustration
 
def a: "+-0++0+";
def b: -436 | new;
def c: "+-++-";
 
(a | integer) as $an
| (b | integer) as $bn
| (c | integer) as $cn
| ($an * ($bn - $cn)) as $in
| (a | mult( (b | minus(c)))) as $i
| "a = \($an)",
"b = \($bn)",
"c = \($cn)",
"a * (b - c) = \($i) ~ \($in) => \($in|new)"
</syntaxhighlight>
{{output}}
<pre>
a = 523
b = -436
c = 65
a * (b - c) = ----0+--0++0 ~ -262023 => ----0+--0++0
</pre>
 
Line 2,953 ⟶ 3,528:
{{trans|Python}}
 
<langsyntaxhighlight lang="julia">struct BalancedTernary <: Signed
digits::Vector{Int8}
end
Line 3,037 ⟶ 3,612:
println("a * (b - c): $(Int(r)), $r")
 
@assert Int(r) == Int(a) * (Int(b) - Int(c))</langsyntaxhighlight>
 
{{out}}
Line 3,045 ⟶ 3,620:
a * (b - c): -262023, ----0+--0++0</pre>
 
=={{header|Koka}}==
Based on the OCaml version
<syntaxhighlight lang="koka">
type btdigit
Pos
Zero
Neg
 
alias btern = list<btdigit>
 
fun to_string(n: btern): string
join(
n.reverse.map fn(d)
match d
Pos -> "+"
Zero -> "0"
Neg -> "-"
)
 
fun from_string(s: string): exn btern
var sl := Nil
s.foreach fn(c)
match c
'+' -> sl := Cons(Pos, sl)
'0' -> sl := Cons(Zero, sl)
'-' -> sl := Cons(Neg, sl)
_ -> throw("Invalid Character")
sl
 
fun to_int(n: btern): int
match n
Nil -> 0
Cons(Zero, Nil) -> 0
Cons(Pos, rst) -> 1+3*rst.to_int
Cons(Neg, rst) -> -1+3*rst.to_int
Cons(Zero, rst) -> 3*rst.to_int
 
fun from_int(n: int): <exn> btern
if n == 0 then [] else
match n % 3
0 -> Cons(Zero, from_int((n/3).unsafe-decreasing))
1 -> Cons(Pos, from_int(((n - 1)/3).unsafe-decreasing))
2 -> Cons(Neg, from_int(((n+1)/3).unsafe-decreasing))
_ -> throw("Impossible")
 
fun (+)(n1: btern, n2: btern): <exn,div> btern
match (n1, n2)
([], a) -> a
(a, []) -> a
(Cons(Pos, t1), Cons(Neg, t2)) ->
val sum = t1 + t2
if sum.is-nil then [] else Cons(Zero, sum)
(Cons(Neg, t1), Cons(Pos, t2)) ->
val sum = t1 + t2
if sum.is-nil then [] else Cons(Zero, sum)
(Cons(Zero, t1), Cons(Zero, t2)) ->
val sum = t1 + t2
if sum.is-nil then [] else Cons(Zero, sum)
(Cons(Pos, t1), Cons(Pos, t2)) -> Cons(Neg, t1 + t2 + [Pos])
(Cons(Neg, t1), Cons(Neg, t2)) -> Cons(Pos, t1 + t2 + [Neg])
(Cons(Zero, t1), Cons(h, t2)) -> Cons(h, t1 + t2)
(Cons(h, t1), Cons(Zero, t2)) -> Cons(h, t1 + t2)
_ -> throw("Impossible")
 
fun neg(n: btern)
n.map fn(d)
match d
Pos -> Neg
Zero -> Zero
Neg -> Pos
 
fun (-)(n1: btern, n2: btern): <exn,div> btern
n1 + neg(n2)
 
fun (*)(n1, n2)
match n2
[] -> []
[Pos] -> n1
[Neg] -> n1.neg
(Cons(Pos, t)) -> Cons(Zero, t*n1) + n1
(Cons(Neg, t)) -> Cons(Zero, t*n1) - n1
(Cons(Zero, t)) -> Cons(Zero, t*n1)
 
fun main()
val a = "+-0++0+".from_string
val b = (-436).from_int
val c = "+-++-".from_string
val d = a * (b - c)
println("a = " ++ a.to_int.show ++ "\nb = " ++ b.to_string ++ "\nc = " ++ c.to_int.show ++ "\na * (b - c) = " ++ d.to_string ++ " = " ++ d.to_int.show )
</syntaxhighlight>
 
{{out}}
<pre>
a = 523
b = -++-0--
c = 65
a * (b - c) = ----0+--0++0 = -262023
</pre>
=={{header|Kotlin}}==
This is based on the Java entry. However, I've added 'BigInteger' support as this is a current requirement of the task description even though it's not actually needed to process the test case:
<langsyntaxhighlight lang="scala">// version 1.1.3
 
import java.math.BigInteger
Line 3,190 ⟶ 3,863:
val iResult = bResult.toBigInteger()
println("a * (b - c) = $bResult = $iResult")
}</langsyntaxhighlight>
 
{{out}}
Line 3,201 ⟶ 3,874:
 
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
<lang lb>
global tt$
tt$="-0+" '-1 0 1; +2 -> 1 2 3, instr
Line 3,339 ⟶ 4,012:
wend
end function
</syntaxhighlight>
</lang>
 
{{out}}
Line 3,354 ⟶ 4,027:
=={{header|Lua}}==
{{trans|C}}
<langsyntaxhighlight lang="lua">function to_bt(n)
local d = { '0', '+', '-' }
local v = { 0, 1, -1 }
Line 3,499 ⟶ 4,172:
end
 
main()</langsyntaxhighlight>
{{out}}
<pre> a: +-0++0+ 523
Line 3,507 ⟶ 4,180:
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight lang="mathematica">frombt = FromDigits[StringCases[#, {"+" -> 1, "-" -> -1, "0" -> 0}],
3] &;
tobt = If[Quotient[#, 3, -1] == 0,
Line 3,528 ⟶ 4,201:
btnegate@#1],
If[StringLength@#2 == 1,
"0", #0[#1, StringDrop[#2, -1]] <> "0"]] &;</langsyntaxhighlight>
Examples:
<langsyntaxhighlight lang="mathematica">frombt[a = "+-0++0+"]
b = tobt@-436
frombt[c = "+-++-"]
btmultiply[a, btsubtract[b, c]]</langsyntaxhighlight>
Outputs:
<pre>523
Line 3,545 ⟶ 4,218:
=={{header|МК-61/52}}==
{{trans|Glagol}}
<langsyntaxhighlight lang="mk-61">ЗН П2 Вx |x| П0 0 П3 П4 1 П5
ИП0 /-/ x<0 80
ИП0 ^ ^ 3 / [x] П0 3 * - П1
Line 3,556 ⟶ 4,229:
ИП2 /-/ ПП 88 1 П3 БП 10
ИП3 x#0 86 ИП2 ПП 88 ИП4 С/П
8 + ИП5 * ИП4 + П4 ИП5 1 0 * П5 В/О</langsyntaxhighlight>
 
''Note: the "-", "0", "+" denotes by digits, respectively, the "7", "8", "9".''
 
=={{header|Nim}}==
<langsyntaxhighlight Nimlang="nim">import std/[strformat, tables]
import tables
 
type
Line 3,652 ⟶ 4,324:
 
func `*`*(a, b: BTernary): BTernary =
## Multiply towtwo BTernary numbers.
 
var start: BTernary
Line 3,738 ⟶ 4,410:
echo "a × (b - c):"
echo fmt"– in ternary: {x}"
echo fmt"– in decimal: {x.toInt}"</langsyntaxhighlight>
 
{{out}}
Line 3,756 ⟶ 4,428:
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">type btdigit = Pos | Zero | Neg
type btern = btdigit list
 
Line 3,807 ⟶ 4,479:
let _ =
Printf.printf "a = %d\nb = %d\nc = %d\na * (b - c) = %s = %d\n"
(to_int a) (to_int b) (to_int c) (to_string d) (to_int d);</langsyntaxhighlight>
Output:
<pre>a = 523
Line 3,815 ⟶ 4,487:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use strict;
use warnings;
 
Line 3,889 ⟶ 4,561:
printf " c: %14s %10d\n", $c, from_bt( $c );
printf "a*(b-c): %14s %10d\n", $d, from_bt( $d );
</syntaxhighlight>
</lang>
{{out}}
<pre> a: +-0++0+ 523
Line 3,900 ⟶ 4,572:
Using strings to represent balanced ternary. Note that as implemented dec2bt and bt2dec are limited to Phix integers (~+/-1,000,000,000),
but it would probably be pretty trivial (albeit quite a bit slower) to replace them with (say) ba2bt and bt2ba which use/yield bigatoms.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function bt2dec(string bt)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
integer res = 0
<span style="color: #008080;">function</span> <span style="color: #000000;">bt2dec</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">bt</span><span style="color: #0000FF;">)</span>
for i=1 to length(bt) do
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
res = 3*res+(bt[i]='+')-(bt[i]='-')
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bt</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">*</span><span style="color: #000000;">res</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">bt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'+'</span><span style="color: #0000FF;">)-(</span><span style="color: #000000;">bt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'-'</span><span style="color: #0000FF;">)</span>
return res
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function negate(string bt)
for i=1 to length(bt) do
<span style="color: #008080;">function</span> <span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">bt</span><span style="color: #0000FF;">)</span>
if bt[i]!='0' then
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bt</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
bt[i] = '+'+'-'-bt[i]
<span style="color: #008080;">if</span> <span style="color: #000000;">bt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">bt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'+'</span><span style="color: #0000FF;">+</span><span style="color: #008000;">'-'</span><span style="color: #0000FF;">-</span><span style="color: #000000;">bt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return bt
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">bt</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function dec2bt(integer n)
string res = "0"
<span style="color: #008080;">function</span> <span style="color: #000000;">dec2bt</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
integer neg, r
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0"</span>
if n!=0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
neg = n<0
<span style="color: #004080;">integer</span> <span style="color: #000000;">neg</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span>
if neg then n = -n end if
<span style="color: #008080;">if</span> <span style="color: #000000;">neg</span> <span style="color: #008080;">then</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">n</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
res = ""
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
while n!=0 do
<span style="color: #008080;">while</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
r = mod(n,3)
<span style="color: #004080;">integer</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
res = "0+-"[r+1]&res
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0+-"</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">res</span>
n = floor((n+(r=2))/3)
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span><span style="color: #0000FF;">))/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
if neg then res = negate(res) end if
<span style="color: #008080;">if</span> <span style="color: #000000;">neg</span> <span style="color: #008080;">then</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return res
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
-- res,carry for a+b+carry lookup tables (not the fastest way to do it, I'm sure):
<span style="color: #000080;font-style:italic;">-- res,carry for a+b+carry lookup tables (not the fastest way to do it, I'm sure):</span>
constant {tadd,addres} = columnize({{"---","0-"},{"--0","+-"},{"--+","-0"},
<span style="color: #008080;">constant</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tadd</span><span style="color: #0000FF;">,</span><span style="color: #000000;">addres</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">({{</span><span style="color: #008000;">"---"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"0-"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"--0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"+-"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"--+"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-0"</span><span style="color: #0000FF;">},</span>
{"-0-","+-"},{"-00","-0"},{"-0+","00"},
<span style="color: #0000FF;">{</span><span style="color: #008000;">"-0-"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"+-"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"-00"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-0"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"-0+"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"00"</span><span style="color: #0000FF;">},</span>
{"-+-","-0"},{"-+0","00"},{"-++","+0"},
<span style="color: #0000FF;">{</span><span style="color: #008000;">"-+-"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-0"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"-+0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"00"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"-++"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"+0"</span><span style="color: #0000FF;">},</span>
{"0--","+-"},{"0-0","-0"},{"0-+","00"},
<span style="color: #0000FF;">{</span><span style="color: #008000;">"0--"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"+-"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"0-0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-0"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"0-+"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"00"</span><span style="color: #0000FF;">},</span>
{"00-","-0"},{"000","00"},{"00+","+0"},
<span style="color: #0000FF;">{</span><span style="color: #008000;">"00-"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-0"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"000"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"00"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"00+"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"+0"</span><span style="color: #0000FF;">},</span>
{"0+-","00"},{"0+0","+0"},{"0++","-+"},
<span style="color: #0000FF;">{</span><span style="color: #008000;">"0+-"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"00"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"0+0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"+0"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"0++"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-+"</span><span style="color: #0000FF;">},</span>
{"+--","-0"},{"+-0","00"},{"+-+","+0"},
<span style="color: #0000FF;">{</span><span style="color: #008000;">"+--"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-0"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"+-0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"00"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"+-+"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"+0"</span><span style="color: #0000FF;">},</span>
{"+0-","00"},{"+00","+0"},{"+0+","-+"},
<span style="color: #0000FF;">{</span><span style="color: #008000;">"+0-"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"00"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"+00"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"+0"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"+0+"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-+"</span><span style="color: #0000FF;">},</span>
{"++-","+0"},{"++0","-+"},{"+++","0+"}})
<span style="color: #0000FF;">{</span><span style="color: #008000;">"++-"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"+0"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"++0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-+"</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"+++"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"0+"</span><span style="color: #0000FF;">}})</span>
 
 
function bt_add(string a, string b)
<span style="color: #008080;">function</span> <span style="color: #000000;">bt_add</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
integer pad = length(a)-length(b)
<span style="color: #004080;">integer</span> <span style="color: #000000;">padding</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">),</span>
integer carry = '0'
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ch</span>
if pad!=0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">padding</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
if pad<0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">padding</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
a = repeat('0',-pad)&a
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">padding</span><span style="color: #0000FF;">)&</span><span style="color: #000000;">a</span>
else
<span b style="color: repeat('0',pad)&b#008080;">else</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">padding</span><span style="color: #0000FF;">)&</span><span style="color: #000000;">b</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for i=length(a) to 1 by -1 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
{a[i],carry} = addres[find(a[i]&b[i]&carry,tadd)]
<span style="color: #004080;">string</span> <span style="color: #000000;">cc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">addres</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">carry</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tadd</span><span style="color: #0000FF;">)]</span>
end for
<span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">cc</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
if carry!='0' then
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">cc</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
a = carry&a
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
else
<span style="color: #008080;">if</span> <span style="color: #000000;">carry</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">then</span>
while length(a)>1 and a[1]='0' do
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">carry</span><span style="color: #0000FF;">&</span><span style="color: #000000;">a</span>
a = a[2..$]
<span style="color: #008080;">else</span>
end while
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)></span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">do</span>
end if
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]</span>
return a
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
<span style="color: #008080;">return</span> <span style="color: #000000;">a</span>
function bt_mul(string a, string b)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
string pos = a, neg = negate(a), res = "0"
integer ch
<span style="color: #008080;">function</span> <span style="color: #000000;">bt_mul</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
for i=length(b) to 1 by -1 do
<span style="color: #004080;">string</span> <span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">neg</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0"</span>
ch = b[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
if ch='+' then
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
res = bt_add(res,pos)
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'+'</span> <span style="color: #008080;">then</span>
elsif ch='-' then
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bt_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">)</span>
res = bt_add(res,neg)
<span style="color: #008080;">elsif</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bt_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">neg</span><span style="color: #0000FF;">)</span>
pos = pos&'0'
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
neg = neg&'0'
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pos</span><span style="color: #0000FF;">&</span><span style="color: #008000;">'0'</span>
end for
<span style="color: #000000;">neg</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">neg</span><span style="color: #0000FF;">&</span><span style="color: #008000;">'0'</span>
return res
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
string a = "+-0++0+", b = dec2bt(-436), c = "+-++-"
 
<span style="color: #004080;">string</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"+-0++0+"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dec2bt</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">436</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"+-++-"</span><span style="color: #0000FF;">,</span>
?{bt2dec(a),bt2dec(b),bt2dec(c)}
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bt_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bt_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)))</span>
 
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%7s: %12s %9d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"a"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bt2dec</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)})</span>
string res = bt_mul(a,bt_add(b,negate(c)))
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%7s: %12s %9d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"b"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bt2dec</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)})</span>
?{res,bt2dec(res)}</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%7s: %12s %9d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"c"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bt2dec</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%7s: %12s %9d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"a*(b-c)"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bt2dec</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
a: +-0++0+ 523
{523,-436,65}
b: -++-0-- -436
{"----0+--0++0",-262023}
c: +-++- 65
a*(b-c): ----0+--0++0 -262023
</pre>
Proof of arbitrary large value support is provided by calculating 1000! and 999! and using a naive subtraction loop to effect division.
Line 4,000 ⟶ 4,677:
show it manages a 5000+digit multiplication and subtraction in about 0.2s, which I say is "reasonable", given that I didn't try very hard,
as evidenced by that daft addition lookup table!
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>atom t0 = time()
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
string f999 = dec2bt(1)
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
for i=2 to 999 do
<span style="color: #004080;">string</span> <span style="color: #000000;">f999</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dec2bt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
f999 = bt_mul(f999,dec2bt(i))
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">999</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">f999</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bt_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f999</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dec2bt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">))</span>
string f1000 = bt_mul(f999,dec2bt(1000))
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #004080;">string</span> <span style="color: #000000;">f1000</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bt_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f999</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dec2bt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1000</span><span style="color: #0000FF;">))</span>
printf(1,"In balanced ternary, f999 has %d digits and f1000 has %d digits\n",{length(f999),length(f1000)})
 
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"In balanced ternary, f999 has %d digits and f1000 has %d digits\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f999</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f1000</span><span style="color: #0000FF;">)})</span>
integer count = 0
f999 = negate(f999)
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
while f1000!="0" do
<span style="color: #000000;">f999</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f999</span><span style="color: #0000FF;">)</span>
f1000 = bt_add(f1000,f999)
<span style="color: #008080;">while</span> <span style="color: #000000;">f1000</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">"0"</span> <span style="color: #008080;">do</span>
count += 1
<span style="color: #000000;">f1000</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bt_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f1000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f999</span><span style="color: #0000FF;">)</span>
end while
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
printf(1,"It took %d subtractions to reach 0. (%3.2fs)\n",{count,time()-t0})</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"It took %d subtractions to reach 0. (%3.2fs)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">count</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 4,023 ⟶ 4,703:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(seed (in "/dev/urandom" (rd 8)))
 
(setq *G '((0 -1) (1 -1) (-1 0) (0 0) (1 0) (-1 1) (0 1)))
Line 4,144 ⟶ 4,824:
(println 'R (trih R) R) )
 
(bye)</langsyntaxhighlight>
 
=={{header|Prolog}}==
Line 4,151 ⟶ 4,831:
'''The conversion.'''<br>
Library '''clpfd''' is used so that '''bt_convert''' works in both ways Decimal => Ternary and Ternary ==> Decimal.
<langsyntaxhighlight Prologlang="prolog">:- module('bt_convert.pl', [bt_convert/2,
op(950, xfx, btconv),
btconv/2]).
Line 4,218 ⟶ 4,898:
R1 #= R - 3 * C1, % C1 #= 1,
convert(N1, C1, [R1 | LC], LF).
</langsyntaxhighlight><br>
'''The addition.''' <br>
The same predicate is used for addition and substraction.
<langsyntaxhighlight Prologlang="prolog">:- module('bt_add.pl', [bt_add/3,
bt_add1/3,
op(900, xfx, btplus),
Line 4,344 ⟶ 5,024:
strip_nombre(L) -->
L.
</syntaxhighlight>
</lang>
'''The multiplication.''' <br>
We give a predicate '''euclide(?A, +B, ?Q, ?R)''' which computes both the multiplication and the division, but it is very inefficient.<br>
The predicates '''multiplication(+B, +Q, -A)''' and '''division(+A, +B, -Q, -R)''' are much more efficient.
<langsyntaxhighlight Prologlang="prolog">:- module('bt_mult.pl', [op(850, xfx, btmult),
btmult/2,
multiplication/3
Line 4,519 ⟶ 5,199:
; mult_(B, Q1, A1, R, Resultat, Ajout)) .
 
</syntaxhighlight>
</lang>
Example of output :
<pre> ?- A btconv "+-0++0+".
Line 4,538 ⟶ 5,218:
=={{header|Python}}==
{{trans|Common Lisp}}
<langsyntaxhighlight lang="python">class BalancedTernary:
# Represented as a list of 0, 1 or -1s, with least significant digit first.
 
Line 4,632 ⟶ 5,312:
print "a * (b - c):", r.to_int(), r
 
main()</langsyntaxhighlight>
{{out}}
<pre>a: 523 +-0++0+
Line 4,640 ⟶ 5,320:
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">#lang racket
 
;; Represent a balanced-ternary number as a list of 0's, 1's and -1's.
Line 4,715 ⟶ 5,395:
[description (list 'a 'b 'c "a×(b−c)")])
(printf "~a = ~a or ~a\n" description (bt->integer bt) (bt->string bt))))
</syntaxhighlight>
</lang>
 
{{output}}
Line 4,728 ⟶ 5,408:
(formerly Perl 6)
{{Works with|rakudo|2017.01}}
<syntaxhighlight lang="raku" perl6line>class BT {
has @.coeff;
 
Line 4,790 ⟶ 5,470:
say 'b == ', $b.Int;
say 'c == ', $c.Int;
say "a × (b − c) == ", ~$x, ' == ', $x.Int;</langsyntaxhighlight>
{{out}}
<pre>a == 523
Line 4,799 ⟶ 5,479:
=={{header|REXX}}==
The REXX program could be optimized by using &nbsp; (procedure) with &nbsp; '''expose''' &nbsp; and having the &nbsp; <big>'''$.'''</big> &nbsp; and &nbsp; <big>'''@.'''</big> &nbsp; variables set only once.
<langsyntaxhighlight lang="rexx">/*REXX program converts decimal ◄───► balanced ternary; it 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 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
d2bt: procedure; parse arg x 1; px= 0x / 1; p= 0; $.= '-'; $.1= "+"; $.0= 0; #=
do until x==0; _= (x // (3** (p+1) ) ) % 3**p
x=x / 1
do if until x_==0; 2 then _= (x // (3** (p+-1) ) ) % 3**p
else if _== -2 then _= -1
x= x - _ * (3**p); else if _= p= -2p + then1; _ #= 1$._ || #
x=x end - _ /* (3until**p)/; p= p+1; #= $._ ||return #
end /*until*/; return #
/*──────────────────────────────────────────────────────────────────────────────────────*/
bt2d: procedure; parse arg x; r= reverse(x); #= 0; $.= -1; $.0= 0; #= 0; _= '+'; $._= 1
do j=1 for length(x); _= substr(r, j, 1); #= # + $._ * 3 ** (j-1); end; return #
end /*j*/; 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) )
$.= '-'; $.0= 0; $.1= '+'
#=; dox_= substr(rx, j=, 1); for max( length(x), length(y) ) xn= @.x_
x_y_= substr(rxry, j, 1); xn yn= @.x_y_
s= xn + y_= substr(ry,yn j,+ 1)carry; yncarry= @.y_0
if s== xn2 + ynthen + carrydo; s=-1; carry= 1; carry= 0end
if s== 23 then do; s=-1 0; carry= 1; end
if s== 3-2 then do; s= 01; carry= -1; end
if s#==-2 then do; $.s= 1; carry=-1; || end#
end #= $.s || #/*j*/
if carry\==0 then #= $.carry || #; return end /*j*/btNorm(#)
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; P=0
S= 1; x= btNorm(x); y= btNorm(y); Lx= length(x); Ly= length(y) /*handle: 0-xxx values.*/
if x1=='-' then do; x= btNeg(x); S= -S; end /*positate the number. */
if y1=='-' then do; y= btNeg(y); S= -S; end /* " " " */
if length(y)Ly>length(x)Lx then parse value x y with y x /*optimize " " */
do until y==0 /*keep adding 'til done*/
P=0
P= dobtAdd(P, x until) y==0 /*keepmultiple addingthe 'tilhard doneway*/
Py= btAddbtSub(Py, x'+') /*multiplesubtract 1 thefrom hard wayY.*/
y= btSub(y, '+')end /*subtract 1 from Y.until*/
if S==-1 then P= btNeg(P); return P /*adjust the product's sign; end /*untilreturn.*/
if S==-1 then P=btNeg(P); return P /*adjust the product sign; return. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
btNeg: return translate( arg(1), '-+', "+-") /*negate bal_ternary #.*/
btNorm: _= strip(arg(1), 'L', 0); if _=='' then _=0; return _ /*normalize the number.*/
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</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
Line 4,859 ⟶ 5,537:
 
[a*(b-c)] ----0+--0++0 balanced ternary = -262023 (decimal)
</pre>
 
=={{header|RPL}}==
{{trans|Nim}}
{{works with|RPL|HP-48}}
« "-0+" SWAP POS 2 -
» '<span style="color:blue">CH→TR</span>' STO
« "-0+" SWAP 2 + DUP SUB
» '<span style="color:blue">TR→CH</span>' STO
« '''WHILE''' DUP SIZE OVER HEAD "0" == AND '''REPEAT''' TAIL '''END'''
» '<span style="color:blue">NOZEROS</span>' STO
« DUP SIZE → bt len
« 0
1 len '''FOR''' j
bt j DUP SUB <span style="color:blue">CH→TR</span>
3 len j - ^ * +
'''NEXT'''
» » '<span style="color:blue">BT→I</span>' STO
« DUP "" "0" IFTE
'''WHILE''' OVER '''REPEAT'''
OVER 3 MOD
1 ≤ LASTARG NEG IFTE <span style="color:grey>''@ convert 2 into -1''</span>
DUP <span style="color:blue">TR→CH</span> ROT - 3 / IP SWAP
'''END'''
SWAP DROP
» '<span style="color:blue">I→BT</span>' STO
« '''IF''' OVER SIZE OVER SIZE < '''THEN''' SWAP '''END'''
'''WHILE''' OVER SIZE OVER SIZE > '''REPEAT''' "0" SWAP + '''END'''
→ a b
« "" 0
a SIZE 1 '''FOR''' j
a j DUP SUB <span style="color:blue">CH→TR</span> + b j DUP SUB <span style="color:blue">CH→TR</span> +
'''IF''' DUP ABS 2 ≥ '''THEN'''
DUP 3 MOD 1 ≤ LASTARG NEG IFTE
SWAP SIGN
'''ELSE''' 0 '''END'''
SWAP <span style="color:blue">TR→CH</span> ROT + SWAP
-1 '''STEP'''
'''IF THEN''' LASTARG <span style="color:blue">TR→CH</span> SWAP + '''END'''
<span style="color:blue">NOZEROS</span>
» » '<span style="color:blue">ADDBT</span>' STO
« ""
1 3 PICK SIZE '''FOR''' j
OVER j DUP SUB
<span style="color:blue">CH→TR</span> NEG <span style="color:blue">TR→CH</span> +
'''NEXT'''
SWAP DROP
» '<span style="color:blue">NEGBT</span>' STO
« "" → a b shift
« "0"
a SIZE 1 '''FOR''' j
a j DUP SUB
'''IF''' DUP "0" ≠ '''THEN'''
b
'''IF''' SWAP "-" == '''THEN''' <span style="color:blue">NEGBT</span> '''END'''
'''END'''
shift + <span style="color:blue">ADDBT</span>
'shift' "0" STO+
-1 '''STEP'''
<span style="color:blue">NOZEROS</span>
» » '<span style="color:blue">MULBT</span>' STO
« "+-0++0+" -436 <span style="color:blue">I→BT</span> "+-++-" → a b c
« a <span style="color:blue">BT→I</span> b <span style="color:blue">BT→I</span> c <span style="color:blue">BT→I</span> 3 →LIST
a b c <span style="color:blue">NEGBT ADDBT MULBT</span>
» » '<span style="color:blue">TASK</span>' STO
{{out}}
<pre>
3: { 523 -436 65 }
2: "----0+--0++0"
1: -262023
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">class BalancedTernary
include Comparable
def initialize(str = "")
Line 4,984 ⟶ 5,740:
val = eval(exp)
puts "%8s :%13s,%8d" % [exp, val, val.to_i]
end</langsyntaxhighlight>
 
{{out}}
Line 4,995 ⟶ 5,751:
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">use std::{
cmp::min,
convert::{TryFrom, TryInto},
Line 5,252 ⟶ 6,008:
}
}
</syntaxhighlight>
</lang>
 
Output
Line 5,264 ⟶ 6,020:
=={{header|Scala}}==
This implementation represents ternaries as a reversed list of bits. Also, there are plenty of implicit convertors
<langsyntaxhighlight lang="scala">
object TernaryBit {
val P = TernaryBit(+1)
Line 5,351 ⟶ 6,107:
implicit def intToTernary(i: Int): Ternary = valueOf(i)
}
</syntaxhighlight>
</lang>
 
Then these classes can be used in the following way:
<langsyntaxhighlight lang="scala">
object Main {
 
Line 5,369 ⟶ 6,125:
 
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 5,379 ⟶ 6,135:
 
Besides, we can easily check, that the code works for any input. This can be achieved with ScalaCheck:
<langsyntaxhighlight lang="scala">
object TernarySpecification extends Properties("Ternary") {
 
Line 5,395 ⟶ 6,151:
 
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 5,405 ⟶ 6,161:
=={{header|Tcl}}==
This directly uses the printable representation of the balanced ternary numbers, as Tcl's string operations are reasonably efficient.
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
proc bt-int b {
Line 5,461 ⟶ 6,217:
- { return [bt-sub $sub $b] }
}
}</langsyntaxhighlight>
Demonstration code:
<langsyntaxhighlight lang="tcl">for {set i 0} {$i<=10} {incr i} {puts "$i = [int-bt $i]"}
puts "'+-+'+'+--' = [bt-add +-+ +--] = [bt-int [bt-add +-+ +--]]"
puts "'++'*'++' = [bt-mul ++ ++] = [bt-int [bt-mul ++ ++]]"
Line 5,472 ⟶ 6,228:
puts "a = [bt-int $a], b = [bt-int $b], c = [bt-int $c]"
set abc [bt-mul $a [bt-sub $b $c]]
puts "a*(b-c) = $abc (== [bt-int $abc])"</langsyntaxhighlight>
Output:
<pre>
Line 5,494 ⟶ 6,250:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<langsyntaxhighlight lang="vbnet">Imports System.Text
 
Module Module1
Line 5,681 ⟶ 6,437:
End Class
 
End Module</langsyntaxhighlight>
{{out}}
<pre>a: +-0++0+ = 523
Line 5,692 ⟶ 6,448:
{{libheader|Wren-big}}
{{libheader|Wren-trait}}
<langsyntaxhighlight ecmascriptlang="wren">import "./big" for BigInt
import "./trait" for Comparable
 
class BTernary is Comparable {
Line 5,816 ⟶ 6,572:
var bResult = a * (b - c)
var iResult = bResult.toBigInt
System.print("a * (b - c) = %(bResult) = %(iResult)")</langsyntaxhighlight>
 
{{out}}
1,453

edits