Во многих местах в интернете алгоритм представления числа в троичной симметричной системе счисления указан не вполне корректно. Цифра может иметь отрицательное значение, что и приводит к сложности в корректировке обычного алгоритма, основанного на последовательном делении на основание системы счисления. Постарался восполнить этот пробел.
Главная идея в том, что при получении 2 в остатке от деления на 3, его необходимо представить как две троичные цифры +1•3¹ -1. -1 — это искомая младшая цифра, а +1•3¹ — добавка к исходному числу. Так как для получения следующей цифры исходное значение предварительно нужно разделить на 3, то корректировку числа можно провести уже после деления, но соответственно на 1, а не 3. Таким образом корректировку можно свести к увеличению частного на остаток, поделенный на 2.
MODULE BalancedTernary; IMPORT Variant;
PROCEDURE From*(v: INTEGER; VAR str: ARRAY OF CHAR);
VAR i, k, t: INTEGER; digits: ARRAY 4 OF CHAR; c: CHAR;
BEGIN
IF v >= 0 THEN
digits := "0+-"
ELSE
v := -v;
digits := "0-+"
END;
i := 0;
REPEAT
t := v MOD 3;
IF Variant.One THEN
v := v DIV 3;
IF t = 2 THEN INC(v) END
ELSE
v := v DIV 3 + t DIV 2
END;
str[i] := digits[t];
INC(i)
UNTIL v = 0;
str[i] := 0X;
DEC(i); k := 0;
WHILE i > k DO
c := str[k]; str[k] := str[i]; str[i] := c;
INC(k); DEC(i)
END
END From;
END BalancedTernary.
==== Трисим(Вариант) (
== +Из(ц: Ц; →стр: [×Л]) (
л, к, т: Ц. цифры: [4 × Л]. с: Л.
?? ц ≥ 0 (
цифры ← "0+-"
::
ц ← 0 - ц.
цифры ← "0-+"
).
л ← 0.
(↺) (
т ← ц |÷| 3.
?? Вариант.Один (
ц ← ц ÷ 3.
?? т = 2 ( ц += 1 )
::
ц ← ц ÷ 3 + т ÷ 2
).
стр[л] ← цифры[т].
л += 1
) ДО ц = 0.
стр[л] ← 00л.
л -= 1. к ← 0.
(↺)? л > к (
стр[л] ↔ стр[к].
л -= 1. к += 1
)
) Из.
) Трисим.
Код в песочнице.
Примечательно, что и ChatGPT испытывает сложности с созданием алгоритма печати. Передача пояснительного абзаца позволяет ему создать правильный код.
Комментариев нет:
Отправить комментарий