GNU sed, 236 byte
/^0/bV
:
s/\b9/;8/
s/\b8/;7/
s/\b7/;6/
s/\b6/;5/
s/\b5/;4/
s/\b4/;3/
s/\b3/;2/
s/\b2/;1/
s/\b1/;0/
s/\b0//
/[^;-]/s/;/&&&&&&&&&&/g
t
y/;/1/
:V
s/111/3/g
s/3\b/3:/
s/311/33!/
s/31/3+/
y/3/1/
tV
s/1/+/
y/1:/!0/
/-/{s/-//
y/+!/!+/
}
y/!/-/
Cobalah online!
Penjelasan
Bagian pertama dari kode (kurang dari baris pertama) menerjemahkan desimal ke unary dan langsung berasal dari " Tips untuk bermain golf dalam sed ." Kemudian itu menerjemahkan unary ke terary seimbang satu trit pada satu waktu, yang saya akan menunjukkan dengan bekerja contoh secara manual.
Sebelum hasil akhir, terner angka -, 0dan +diwakili oleh !, :dan +masing-masing.
Untuk hasil yang menarik, kita mulai dengan -48, yang telah dikonversi menjadi unary (dengan -utuh). Untuk menghitung trit pertama (paling kanan), kita harus menghitung sisa 48 ÷ 3. Kita dapat melakukan ini dengan mengganti 111s dengan 3s:
-111111111111111111111111111111111111111111111111 │ s/111/3/g
# => -3333333333333333
48 ÷ 3 tidak memiliki sisa, jadi tidak ada 1yang tersisa, dan kami tahu trit pertama kami adalah :(untuk 0), jadi kami menggantinya:
-3333333333333333 │ s/3\b/3:/
# => -3333333333333333:
Sekarang kita memiliki "tempat" kita, jadi kita tahu sisanya 3mewakili tempat bertiga. Agar matematika tetap berfungsi, kita harus membaginya dengan 3, yaitu ganti dengan 1s:
-3333333333333333: │ y/3/1/
# => -1111111111111111:
Mari kita periksa matematika kita: Kita memiliki 16 (unary 1111111111111111) di tempat bertiga dan nol ( :) di tempat itu. Itu 3✕16 + 1✕0 = 48. Sejauh ini bagus.
Sekarang kita mulai lagi. Ganti 111s dengan 3s:
-1111111111111111: │ s/111/3/g
# => -333331:
Kali ini sisanya adalah 1, jadi kami taruh +di tempat bertiga dan ganti yang tersisa 3dengan 1s:
-333331: │ s/31/3+/; y/3/1/
# => -11111+:
Waktu cek kewarasan: Kami memiliki 5 (tidak sama 11111) di tempat sembilan, 1 ( +) di tempat bertiga, dan 0 ( :) di tempat yang: 9✕5 + 3✕1 + 1✕0 = 48. Hebat! Sekali lagi kita ganti 111s dengan 3s:
-11111+: │ s/111/3/g
# => -311+:
Kali ini sisanya adalah 2 ( 11). Itu membutuhkan dua trits ( +!), yang berarti kita memiliki carry. Sama seperti dalam aritmatika desimal itu berarti kita mengambil digit paling kanan dan menambahkan sisanya ke kolom di sebelah kiri. Dalam sistem kami, itu berarti kami menempatkan !di tempat sembilan dan menambahkan tiga di sebelah kirinya, lalu mengganti semua 3dengan 1s untuk mewakili tempat ke-27:
-311+: │ s/311/33!/; y/3/1/
# => -11!+:
Sekarang kami tidak memiliki 3 angka yang tersisa, jadi kami dapat mengganti sisa digit yang belum diketahui dengan trits yang sesuai. Dua ( 11) adalah +!:
-11!+: │ s/11/+!/
# => -+!!+:
Dalam kode aktual ini dilakukan dalam dua langkah, s/1/+/dan y/1:/!0/, untuk menghemat byte. Langkah kedua juga menggantikan :s dengan 0s, jadi ia melakukan ini:
-11!+: │ s/1/+/; y/1:/+0/
# => -+!!+0
Sekarang kami memeriksa apakah kami memiliki angka negatif. Kami melakukannya, jadi kami harus menyingkirkan tanda dan kemudian membalikkan masing-masing tanda:
-+!!+0 │ /-/ { s/-//; y/+!/!+/; }
# => !++!0
Akhirnya, kami ganti !s dengan -s:
!++!0 │ y/!/-/
# => -++-0
Itu dia!