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 -
, 0
dan +
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 111
s dengan 3
s:
-111111111111111111111111111111111111111111111111 │ s/111/3/g
# => -3333333333333333
48 ÷ 3 tidak memiliki sisa, jadi tidak ada 1
yang 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 3
mewakili tempat bertiga. Agar matematika tetap berfungsi, kita harus membaginya dengan 3, yaitu ganti dengan 1
s:
-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 111
s dengan 3
s:
-1111111111111111: │ s/111/3/g
# => -333331:
Kali ini sisanya adalah 1
, jadi kami taruh +
di tempat bertiga dan ganti yang tersisa 3
dengan 1
s:
-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 111
s dengan 3
s:
-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 3
dengan 1
s 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 0
s, 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!