GNU sed, 236 bytes
/^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/!/-/
Experimente online!
Explicação
A primeira metade do código (menos a primeira linha) converte decimal em unário e vem diretamente de " Dicas para jogar golfe no sed ". Em seguida, ele traduz unário para ternário equilibrado, um trit de cada vez, o que demonstrarei trabalhando um exemplo manualmente.
Antes da saída final, os dígitos ternários -, 0e +são representados por !, :e +, respectivamente.
Para um resultado interessante, começamos com -48, que foi convertido em unário (com o -intacto). Para calcular o primeiro trit (mais à direita), temos que calcular o restante de 48 ÷ 3. Podemos fazer isso substituindo 111s por 3s:
-111111111111111111111111111111111111111111111111 │ s/111/3/g
# => -3333333333333333
48 ÷ 3 não tem resto, então não há mais 1s, e sabemos que nosso primeiro ponto é :(para 0), então o substituímos:
-3333333333333333 │ s/3\b/3:/
# => -3333333333333333:
Agora, temos o nosso "local de quem", para que saibamos que os 3s restantes representam o terceiro lugar. Para manter a matemática funcionando, precisamos dividi-los por 3, ou seja, substituí-los por 1s:
-3333333333333333: │ y/3/1/
# => -1111111111111111:
Vamos verificar novamente nossa matemática: temos 16 (unário 1111111111111111) nos três lugares e zero ( :) nos mesmos . Isso é 3✕16 + 1✕0 = 48. Até agora tudo bem.
Agora vamos começar de novo. Substitua 111s por 3s:
-1111111111111111: │ s/111/3/g
# => -333331:
Desta vez, o restante é 1, então colocamos +em três lugares e substituímos os 3s restantes por 1s:
-333331: │ s/31/3+/; y/3/1/
# => -11111+:
Tempo de verificação da sanidade: Temos um 5 (unário 11111) no lugar dos noves, 1 ( +) no :terceiro e 0 ( ) no primeiro: 9✕5 + 3✕1 + 1✕0 = 48. Ótimo! Novamente, substituímos 111s por 3s:
-11111+: │ s/111/3/g
# => -311+:
Desta vez, o restante é 2 ( 11). Isso ocupa dois trits ( +!), o que significa que temos um carry. Assim como na aritmética decimal, significa que pegamos o dígito mais à direita e adicionamos o restante à coluna à esquerda. Em nosso sistema, isso significa que colocamos !o lugar dos noves e adicionamos outros três à sua esquerda e substituímos todos os 3s por 1s para representar o lugar dos 27s:
-311+: │ s/311/33!/; y/3/1/
# => -11!+:
Agora não temos mais 3s, para que possamos substituir os dígitos unários restantes pelos seus trits correspondentes. Dois ( 11) são +!:
-11!+: │ s/11/+!/
# => -+!!+:
No código real, isso é feito em duas etapas s/1/+/e y/1:/!0/, para salvar bytes. O segundo passo também substitui :s por 0s, portanto, ele realmente faz isso:
-11!+: │ s/1/+/; y/1:/+0/
# => -+!!+0
Agora verificamos se temos um número negativo. Como fazemos, temos que nos livrar do sinal e depois inverter cada trit:
-+!!+0 │ /-/ { s/-//; y/+!/!+/; }
# => !++!0
Finalmente, substituímos !s por -s:
!++!0 │ y/!/-/
# => -++-0
É isso aí!