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/!/-/
Try it online!
Explanation
The first half of the code (less the first line) translates decimal to unary and comes straight from "Tips for golfing in sed." Then it translates unary to balanced ternary one trit at a time, which I'll demonstrate by working an example manually.
最终输出之前,三元位数-
,0
和+
由下式表示!
,:
和+
分别。
为了获得有趣的结果,我们从开始-48
,将其转换为一元(-
完整无缺)。要计算第一个(最右边的)三重奏,我们必须计算其余的48÷3。我们可以通过将111
s 替换为s来实现3
:
-111111111111111111111111111111111111111111111111 │ s/111/3/g
# => -3333333333333333
48÷3没有余数,所以也没有余数,1
我们知道我们的第一个trit是:
(对于0),因此我们将其替换:
-3333333333333333 │ s/3\b/3:/
# => -3333333333333333:
现在我们有了“一个地方”,因此我们知道其余的3
s代表三个地方。为了使数学有效,我们必须将它们除以3,即用1
s 代替它们:
-3333333333333333: │ y/3/1/
# => -1111111111111111:
Let's double-check our math: We have 16 (unary 1111111111111111
) in the threes place and zero (:
) in the ones place. That's 3✕16 + 1✕0 = 48. So far so good.
Now we start again. Replace 111
s with 3
s:
-1111111111111111: │ s/111/3/g
# => -333331:
This time our remainder is 1
, so we put +
in the threes place and replace the remaining 3
s with 1
s:
-333331: │ s/31/3+/; y/3/1/
# => -11111+:
Sanity check time: We have a 5 (unary 11111
) in the nines place, 1 (+
) in the threes place, and 0 (:
) in the ones place: 9✕5 + 3✕1 + 1✕0 = 48. Great! Again we replace the 111
s with 3
s:
-11111+: │ s/111/3/g
# => -311+:
这次我们的余数是2(11
)。这需要两个trits(+!
),这意味着我们有一个进位。就像十进制算术一样,这意味着我们采用最右边的数字并将其余部分添加到左侧的列中。在我们的系统中,这意味着我们将放!
第九个位置,并在其左边再添加三个,然后将所有3
s 替换为1
s来代表第27个位置:
-311+: │ s/311/33!/; y/3/1/
# => -11!+:
现在我们没有3了,因此我们可以用任何剩余的一进制数字替换其对应的Trit。两个(11
)为+!
:
-11!+: │ s/11/+!/
# => -+!!+:
在实际代码中,分两个步骤完成,s/1/+/
和y/1:/!0/
以节省字节。第二步还将:
s 替换为0
s,因此实际上是这样的:
-11!+: │ s/1/+/; y/1:/+0/
# => -+!!+0
Now we check if we have a negative number. We do, so we have to get rid of the sign and then invert each trit:
-+!!+0 │ /-/ { s/-//; y/+!/!+/; }
# => !++!0
Finally, we replace !
s with -
s:
!++!0 │ y/!/-/
# => -++-0
That's it!