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/!/-/
Provalo online!
Spiegazione
La prima metà del codice (meno la prima riga) traduce i decimali in unari e deriva direttamente da " Suggerimenti per giocare a golf in sed ". Quindi traduce unario in ternario bilanciato un trit alla volta, che dimostrerò lavorando manualmente un esempio.
Prima l'output finale, le cifre ternarie -, 0e +sono rappresentati da !, :e +, rispettivamente.
Per un risultato interessante, iniziamo con -48, che è stato convertito in unario (con -intatto). Per calcolare il primo tratto (quello più a destra), dobbiamo calcolare il resto di 48 ÷ 3. Possiamo farlo sostituendo la 111s con 3s:
-111111111111111111111111111111111111111111111111 │ s/111/3/g
# => -3333333333333333
48 ÷ 3 non ha resto, quindi non 1rimangono s e sappiamo che il nostro primo trit è :(per 0), quindi lo sostituiamo:
-3333333333333333 │ s/3\b/3:/
# => -3333333333333333:
Ora abbiamo i nostri "un posto", quindi sappiamo che i rimanenti 3rappresentano il terzo posto. Per far funzionare la matematica dobbiamo dividerli per 3, cioè sostituirli con 1s:
-3333333333333333: │ y/3/1/
# => -1111111111111111:
Ricontrolliamo la nostra matematica: ne abbiamo 16 (unari 1111111111111111) al terzo posto e zero ( :) al primo posto. È 3✕16 + 1✕0 = 48. Finora tutto bene.
Ora ricominciamo. Sostituisci 111s con 3s:
-1111111111111111: │ s/111/3/g
# => -333331:
Questa volta il resto è 1, quindi inseriamo +i tre e sostituiamo le rimanenti 3s con 1s:
-333331: │ s/31/3+/; y/3/1/
# => -11111+:
Tempo di controllo della sanità mentale: abbiamo un 5 (unario 11111) al posto dei nove, 1 ( +) al posto dei tre e 0 ( :) al posto dei: 9✕5 + 3✕1 + 1✕0 = 48. Fantastico! Sostituiamo di nuovo la 111s con 3s:
-11111+: │ s/111/3/g
# => -311+:
Questa volta il resto è 2 ( 11). Questo occupa due trits ( +!), il che significa che abbiamo un carry. Proprio come nell'aritmetica decimale ciò significa che prendiamo la cifra più a destra e aggiungiamo il resto alla colonna a sinistra. Nel nostro sistema, ciò significa che mettiamo !il posto dei nove e ne aggiungiamo altri tre alla sua sinistra, quindi sostituiamo tutte le 3s con 1s per rappresentare il posto dei 27:
-311+: │ s/311/33!/; y/3/1/
# => -11!+:
Ora non ci sono ancora 3 secondi, quindi possiamo sostituire le cifre unarie rimanenti con i rispettivi tratti corrispondenti. Due ( 11) è +!:
-11!+: │ s/11/+!/
# => -+!!+:
Nel codice effettivo questo viene fatto in due passaggi s/1/+/e y/1:/!0/, per salvare byte. Il secondo passaggio sostituisce anche :s con 0s, quindi effettivamente fa questo:
-11!+: │ s/1/+/; y/1:/+0/
# => -+!!+0
Ora controlliamo se abbiamo un numero negativo. Lo facciamo, quindi dobbiamo sbarazzarci del segno e invertire ogni tratto:
-+!!+0 │ /-/ { s/-//; y/+!/!+/; }
# => !++!0
Infine, sostituiamo !s con -s:
!++!0 │ y/!/-/
# => -++-0
Questo è tutto!