Классический VCS ASCII Adventure


21

Когда я рос, моей первой консольной игровой системой был Atari 2600, и я всегда буду любить некоторые из тех игр, которые мне так нравились в детстве. Многие из графики все еще запоминаются, возможно, даже культовые.

Оказывается, что эти спрайты являются очень упрощенными растровыми изображениями, шириной 8 пикселей с переменной высотой, где двоичное представление представляет собой расположение пикселей.

Например, шестнадцатеричные байты 0x18, 0x24, 0x18 нарисуют грубый круг, например:

0x18: 00011000
0x24: 00100100
0x18: 00011000

Поскольку 8 пикселей в ширину создают довольно маленькую графику (даже по стандартам Atari 2600), было принято удваивать или увеличивать в четыре раза либо высоту, ширину или и то и другое, чтобы создать увеличенную (хотя и более блочную и искаженную) версию одного и того же изображения. Они также обычно переворачиваются вертикально или горизонтально как для спрайтов игроков, так и для игровых полей. Игра Combat является хорошим примером этого.

Задача состоит в том, чтобы написать код для отображения этих спрайтов в виде «графики» в форме ASCII, включая возможность растягивать или переворачивать их по вертикали, горизонтали или обоим. Это должно быть в виде полной программы или вызываемой функции.

Входные данные:

  • Массив байтов, каждый из которых представляет горизонтальные биты для этой строки.
  • Ненулевое целочисленное значение для каждого направления, горизонтальное и вертикальное, представляющее коэффициент масштабирования для этого измерения.
  • Отрицательное значение указывает, что измерение также должно быть перевернуто вдоль его оси.

Выход:

  • Представление ASCII в STDOUT или строку, разделенную новой строкой, с использованием пробела для черных (0) пикселей и любого печатного непробельного символа по вашему выбору для белых (1) пикселей.

Тестовые данные:

bmp1 = [ 0x06, 0x0F, 0xF3, 0xFE, 0x0E, 0x04, 0x04, 0x1E, 0x3F, 0x7F, 0xE3, 0xC3, 0xC3, 0xC7, 0xFF, 0x3C, 0x08, 0x8F, 0xE1, 0x3F ]
bmp2 = [ 0x07, 0xFD, 0xA7 ]
bmp3 = [ 0x00, 0x8E, 0x84, 0xFF, 0xFF, 0x04, 0x0E, 0x00 ]
bmp4 = [ 0x00, 0xFC, 0xFC, 0x38, 0x3F, 0x38, 0xFC, 0xFC]

Примечание. Выше приведен пример входных массивов байтов в шестнадцатеричном формате. Если ваша платформа не принимает шестнадцатеричные литералы для представления байтов, вы можете преобразовать их в собственный эквивалентный байту литерал.

Пример вывода:

f( bmp1, 1, 1 ) =>
--------
     XX 
    XXXX
XXXX  XX
XXXXXXX 
    XXX 
     X  
     X  
   XXXX 
  XXXXXX
 XXXXXXX
XXX   XX
XX    XX
XX    XX
XX   XXX
XXXXXXXX
  XXXX  
    X   
X   XXXX
XXX    X
  XXXXXX
--------

f( bmp1, -2, 1 ) =>
----------------
  XXXX          
XXXXXXXX        
XXXX    XXXXXXXX
  XXXXXXXXXXXXXX
  XXXXXX        
    XX          
    XX          
  XXXXXXXX      
XXXXXXXXXXXX    
XXXXXXXXXXXXXX  
XXXX      XXXXXX
XXXX        XXXX
XXXX        XXXX
XXXXXX      XXXX
XXXXXXXXXXXXXXXX
    XXXXXXXX    
      XX        
XXXXXXXX      XX
XX        XXXXXX
XXXXXXXXXXXX    
----------------

f( bmp2, 1, 2 ) =>
--------
     XXX
     XXX
XXXXXX X
XXXXXX X
X X  XXX
X X  XXX
--------

f( bmp2, 2, 1 ) =>
----------------
          XXXXXX
XXXXXXXXXXXX  XX
XX  XX    XXXXXX
----------------

f( bmp2, -2, -2 ) =>
----------------
XXXXXX    XX  XX
XXXXXX    XX  XX
XX  XXXXXXXXXXXX
XX  XXXXXXXXXXXX
XXXXXX          
XXXXXX          
----------------

f( bmp3, 1, -1 ) =>
--------

    XXX 
     X  
XXXXXXXX
XXXXXXXX
X    X  
X   XXX 

--------

f( bmp3, 3, 3 ) =>
------------------------



XXX         XXXXXXXXX   
XXX         XXXXXXXXX   
XXX         XXXXXXXXX   
XXX            XXX      
XXX            XXX      
XXX            XXX      
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
               XXX      
               XXX      
               XXX      
            XXXXXXXXX   
            XXXXXXXXX   
            XXXXXXXXX   



------------------------

f( bmp4, -1, -1 ) =>
--------
  XXXXXX
  XXXXXX
   XXX  
XXXXXX  
   XXX  
  XXXXXX
  XXXXXX

--------

f( bmp4, 4, 2 ) =>
--------------------------------


XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
        XXXXXXXXXXXX            
        XXXXXXXXXXXX            
        XXXXXXXXXXXXXXXXXXXXXXXX
        XXXXXXXXXXXXXXXXXXXXXXXX
        XXXXXXXXXXXX            
        XXXXXXXXXXXX            
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
--------------------------------

Примечание: горизонтальные линии выше и ниже показывают начало и конец вывода. Они не требуются в выходных данных, однако требуются пустые строки (представленные всеми нулями / пробелами) в начале и / или конце, как показано.

Примечание 2: эти тестовые растровые изображения были вдохновлены и перерисованы / закодированы на основе игровых скриншотов, помеченных как «добросовестное использование» в Википедии.

Критерии победы

  • Это , поэтому выигрывает самый короткий код в байтах на язык.
  • Стандартные лазейки запрещены.

6
"Кто-нибудь убери эту чертову утку от меня!" - Сильно Плохо
AdmBorkBork

7
Ирония заключается в том, что даже самый умный гольф здесь, вероятно, не будет таким умным, как на самом деле программисты Atari 2600, если они хотят чего-то более интересного, чем клон Pong - весь экран отображается по одной строке за раз, и Процессор провел большую часть своего времени, делая это. С только 128 байтами оперативной памяти не было места для роскоши, такой как экранный буфер ... Пять целых спрайтов, которые вы получили, были роскошью.
Йерун Мостерт

Можем ли мы считать входные данные списком 8-битных двоичных строк или аналогичных форматов, где байты уже распакованы в биты?
Луис Мендо

@LuisMendo « Если ваша платформа не принимает шестнадцатеричные литералы для представления байтов, вы можете преобразовать их в собственный байтовый эквивалентный литерал. »
Кевин Круйссен

@KevinCruijssen В том-то и дело, что я не знаю, что принято считать эквивалентом . Открывает ли это дверь для непосредственного ввода растрового изображения?
Луис Мендо

Ответы:



5

05AB1E , 27 26 байт

εS²Ä×J³Äи²0‹ií]³0‹iR}˜0ð:»

Принимает входные данные в виде списка 8-битных двоичных строк и выводит их 1как непробельный символ.

-1 байт благодаря @MagicOctopusUrn .

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

ε         # Map the (implicit) input-list to:
 S        #  Convert the binary-String to a list of characters
  ²Ä      #  Take the absolute value of the second input
    ×     #  And repeat each character that many times
     J    #  And then join it back together to a single string again
 ³Ä       #  Take the absolute value of the third input
   и      #  Repeat that string as a list that many times
 ²0i     #  If the second input is negative:
     í    #   Reverse each string in the list
]         # Close both the if-statement and (outer) map
³0i }    # If the third input is negative:
    R     #  Reverse the list of lists
      ˜   # Flatten the list of lists to a list of strings
0ð:       # Replace all 0s with spaces " "
   »      # And join the strings by newlines (which is output implicitly)

Там должно быть 2 байта для 0‹i...
Волшебная Осьминога Урна

@MagicOctopusUrn Для действительно должен быть 1 байт 0‹. У нас есть 1 байт для >=0, то есть d. Но у нас также должен быть 1 байт для проверки на наличие отрицательных значений. Теперь я просто использую 0‹или d_.
Кевин Круйссен

Все, что я мог придумать, было: „íR³²‚0‹Ï.V(полный код εε²Ä×}J³Äи0ð:}„íR³²‚0‹Ï.V˜»), который не является улучшением, но избавляет от одной из этих негативных проверок.
Волшебная Урна Осьминога

1
Кроме того, уверен, что εS²Ä×J³Äи²0‹ií]³0‹iR}˜0ð:»сохраняет байт. Если вы можете взять в 2D-массив, вы можете удалить Sполностью для 25 байтов.
Волшебная Урна Осьминога

@MagicOctopusUrn Ну, конечно, S²Ä×вместо ε²Ä×}. Благодарность! Хм, если нам разрешено принимать двоичные входы в виде списка 0 и 1, дополнительный байт можно сохранить, пропустив S. Спросит у ОП, разрешено ли это. Мне нравится твой „íR³²‚0‹Ï.Vдругой комментарий. :)
Кевин Круйссен

3

MATL , 24 19 байт

B,!i|1&Y"2M0<?XP]Zc

Входные данные представляют собой массив десятичных чисел, горизонтальный масштаб, вертикальный масштаб.

Попробуйте онлайн!

объяснение

B        % Implicit input: array of numbers. Convert to binary. Gives a zero-one
         % matrix, each row containing the binary expansion of a number
,        % Do twice
  !      %   Transpose
  i      %   Input: number
  |      %   Absolute value
  1&Y"   %   Repeat each row that many times
  2M     %   Push the latest input again
  0<     %   Is it negative?
  ?      %   If so:
    XP   %     Flip vertically
  ]      %   End
  Zc     %   Convert each nonzero into '#'. Zeros are displayed as space
         % Implicit end. Implicit display

3

Dyalog APL, 46 42 33 байта

' #'[⍉⊃{⊖⍣(0>⍺)⍉⍵/⍨|⍺}/⎕,⊂⎕⊤⍨8/2]

Попробуйте онлайн!

-9 благодаря ngn!


каждый -> уменьшить: {' #'[⊃{⌽⍣(0>⍺)⊢(|⍺)/⍉⍵}/⍺,⊂⍉⍵⊤⍨8/2]}DFN -> Программы:' #'[⊃{⌽⍣(0>⍺)⊢(|⍺)/⍉⍵}/⎕,⊂⍉⎕⊤⍨8/2]
СППЫ

короче: ' #'[⍉⊃{⊖⍣(0>⍺)⍉⍵/⍨|⍺}/⎕,⊂⎕⊤⍨8/2]. Кстати, вывод для второго теста кажется обратным в вашем исходном решении
ngn

@ngn спасибо! входные данные для 2-го примера должны были быть изменены на противоположные, чтобы соответствовать 2-му тестовому случаю в вопросе.
Дзайма

3

Пролог (SWI) , 252 байта

N+E+R:-N<1,R=[];N-1+E+S,R=[E|S].
N*E*R:-R=E,E=[];N<0,reverse(E,F),-N*F*R;[H|T]=E,N+H+S,N*T*U,append(S,U,R).
N/E/R:-N<1,R=[];(E<N,D=E,F=32;D=E-N,F=35),N/2/D/C,R=[F|C].
[H|T]^X^Y^R:-128/H/A,X*A*B,Y*[[10|B]]*C,append(C,D),(T=[],R=D;T^X^Y^S,append(D,S,R)).

Попробуйте онлайн!

объяснение

N+E+R:-N<1,R=[];N-1+E+S,R=[E|S].   Make `R` a list containing `E` repeated `N` times
       N<1,R=[]                    If `N<1`, let `R` be the empty list
       N-1+E+S                     Else recurse with `N-1`, `E` and `S`
           R=[E|S]                 Let `R` be a new list with `E` as head and `S` as tail
N*E*R:-R=E,E=[];N<0,reverse(E,F),-N*F*R;[H|T]=E,N+H+S,N*T*U,append(S,U,R).
                                   Let `R` be a list
                                   with each element in `E` repeated `N` times
                                   e.g. 2*[3, 6] -> [3, 3, 6, 6]
       R=E,E=[]                    Let `R` be `E` if `E` is the empty list
       N<0,reverse(E,F)            Else if `N<0`, let `F` be the reverse of `E`
           -N*F*R                  Recurse with `-N`, `F` and `R`
       [H|T]=E                     Else let `H` be the head and `T` be the tail of `E`
           N+H+S                   Let `S` be `N+H+S` (our function, not addition)
           N*T*U                   Recurse with `N`, `T` and `U`
           append(S,U,R)           let `R` be the concatenation of `S` and `U`
N/E/R:-N<1,R=[];(E<N,D=E,F=32;D=E-N,F=35),N/2/D/C,R=[F|C].
                                   Make `R` the binary representation of `E`
                                   with `N` as the value of the current bit
                                   where 0 and 1 are space and hash respectively
    N<1,R=[]                       If `N<1` let `R` be the empty list
    (
        E<N,D=E,F=32               If `E<N` the bit isn't set, so `D=E`, `F=space`
        D=E-N,F=35                 Else `D=E-N`, `F=hash`
    )
        N/2/D/C                    Recurse with `N/2`, `D` and `C`
        R=[F|C]                    Let `R` be a new list with `F` as head and `C` as tail
[H|T]^X^Y^R:-128/H/A,X*A*B,Y*[[10|B]]*C,append(C,D),(T=[],R=D;T^X^Y^S,append(D,S,R)).
                                   Make `R` the result,
                                   with inputs being the list `[H|T]`
                                   and the scales `X` and `Y`
   128/H/A                         Let `A` be the binary representation of `H` (8 bits)
   X*A*B                           Let `B` be `A` with each element repeated `X` times
   Y*[[10|B]]*C                    Let `C` be `B` with a newline prepended,
                                   repeated `Y` times
   append(C,D)                     Let `D` be `C` flattened by one level (joining lines)
   (
       T=[],R=D                    If `T` is empty, let `R` be `D` 
       T^X^Y^S                     Else recurse with `T`, `X`, `Y` and `S`
           append(D,S,R)           Let `R` be the concatenation of `D` and `S`
   )

2

Древесный уголь , 28 байт

FθE↔ζ⭆⮌↨ι²×§ Xμ↔ηF›η⁰‖F‹ζ⁰‖↓

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

Fθ

Цикл по списку байтов.

E↔ζ

Карта по вертикальному коэффициенту масштабирования, таким образом, умножая выходные строки.

⭆⮌↨ι²×§ Xμ↔η

Преобразуйте входные данные в базу 2, переверните их, сопоставьте цифры с пробелом, а Xзатем умножьте каждый символ на коэффициент горизонтального масштабирования.

F›η⁰‖

Если коэффициент горизонтального масштабирования был положительным, подумайте, чтобы снова получить правильное изображение.

F‹ζ⁰‖↓

Отразите вертикально, если коэффициент вертикального масштабирования был отрицательным.


Не то, чтобы это сохраняло байты, но мне просто любопытно: почему вы использовали F( For) вместо ¿( If) для проверок?
Кевин Круйссен

1
@KevinCruijssen В кратком режиме Charcoal elseподразумевается, так что я могу использовать только один раз, ifесли это последний оператор в блоке.
Нил

Ах, хорошо, не знал об этом. Таким образом, использование двух Ifздесь будет на самом деле If ... Else If ...вместо двух свободных If. Хм, приятно знать.
Кевин Круйссен


2

Common Lisp , 157 байт

(lambda(l x y)(dolist(i(if(< y 0)(reverse l)l))(dotimes(j(abs y))(dotimes(n 8)(dotimes(k(abs x))(princ(if(logbitp(if(< x 0)n(- 7 n))i)"#"" "))))(princ"
"))))

Попробуйте онлайн!

объяснение

(lambda(l x y)                           ; Lambda with parameters `l`, `x`, `y`
    (dolist
        (i                               ; For `i` in the list  
            (if(< y 0)(reverse l)l)      ; The reverse of `l` if `y<0` else `l`
        )
        (dotimes(j(abs y))(dotimes(n 8)(dotimes(k(abs x))
                                         ; Do `y` times, for `n` from 0 to 7, do `x` times
        (princ(if(logbitp(if(< x 0)n(- 7 n))i)"#"" "))))
                                         ; If `x<0` and the `n`th bit is 1
                                         ; or `x>0` and the `7-n`th bit is 1
                                         ; print "#", else print " "
        (princ"
")                                       ; After every `y` loop, print a newline
        )
    )
)

2

Tcl , 192 байта

proc f {l x y} {lmap i [if $y<0 {lreverse $l} {lindex $l}] {time {lmap n {0 1 2 3 4 5 6 7} {time {puts -nonewline [expr $i&1<<($x<0?$n:7-$n)?{#}:{ }]} [expr abs($x)]};puts {}} [expr abs($y)]}}

Попробуйте онлайн!

proc f {l x y}                           Define a function `f` with arguments `l`, `x`, `y`
{lmap i                                  For each `i` in
    [if $y<0 {lreverse $l} {lindex $l}]  The reverse of `l` if `y<0` else `l`
    {
        time {                           Do `abs(y)` times
            lmap n {0 1 2 3 4 5 6 7} {   For `n` from 0 to 7
                time {                   Do `abs(x)` times
                    puts -nonewline      Print without newline
                         [expr $i&1<<($x<0?$n:7-$n)?{#}:{ }]
                                         If `x<0` and the `n`th bit is 1 or
                                         `x>0` and the `7-n`th bit is 1
                                         then return "#" else return " "
                } [expr abs($x)]
            };
            puts {}                      Print a newline
        } [expr abs($y)]
    }
}

2

Машинный код 8088, IBM PC DOS, 77 71 байт

Собранный:

B402 84FF 7906 FD03 F14E F6DF 518A CFAC 5051 B108 8AF3 84F6 7902 F6DE
518A CEB2 2384 DB79 04D0 C8EB 02D0 C072 02B2 2050 CD21 58E2 FA59 E2E4
B20D CD21 B20A CD21 5958 E2CC 59E2 C5

Листинг:

    PR_BMP  MACRO BMP, SZBMP, ZX, ZY
            LOCAL LOOP_Y, LOOP_Y2, LOOP_X, LOOP_X2, X_POS, X_NEG
B4 02   MOV  AH, 2          ; DOS display char function 
84 FF   TEST ZY, ZY         ; is Y scale negative?
79 06   JNS  LOOP_Y         ; if positive, start Y LOOP
FD      STD                 ; direction flag start from end
03 F1   ADD  BMP, CX        ; advance input byte array to end
4E      DEC  BMP            ; zero adjust index
F6 DF   NEG  ZY             ; make counter positive
     LOOP_Y:    
51      PUSH CX             ; save outer byte loop counter
8A CF   MOV  CL, ZY         ; set up repeat counter (Y scale factor)
AC      LODSB               ; load byte into AL
     LOOP_Y2:
50      PUSH AX             ; save original AL
51      PUSH CX             ; save outer loop
B1 08   MOV  CL, 8          ; loop 8 bits
8A F3   MOV  DH, ZX         ; DH is positive X scale used as counter
84 F6   TEST ZX, ZX         ; is X scale negative?
79 02   JNS  LOOP_X         ; if so, make counter positive
F6 DE   NEG  DH             ; compliment X counter 
    LOOP_X:
51      PUSH CX             ; save bit counter
8A CE   MOV  CL, DH         ; set repeat counter (X scale factor)
B2 23   MOV  DL, '#'        ; by default, display a #
84 DB   TEST ZX, ZX         ; is X scale negative?
79 04   JNS  X_POS          ; if so, rotate left 1 bit
D0 C8   ROR  AL, 1          ; else rotate right LSB into CF
EB 02   JMP  X_NEG          ; jump to examine CF
    X_POS:
D0 C0   ROL  AL, 1          ; rotate left MSB into CF
    X_NEG:
72 02   JC   LOOP_X2        ; is a 1?   
B2 20   MOV  DL, ' '        ; if not, display a space
    LOOP_X2:    
50      PUSH AX             ; save AL (since silly DOS overwrites it)
CD 21   INT  21H            ; display char
58      POP  AX             ; restore AL
E2 FA   LOOP LOOP_X2        ; loop repeat counter
59      POP  CX             ; restore bit counter
E2 E4   LOOP LOOP_X         ; loop bit counter
B2 0D   MOV  DL, 0DH        ; display CRLF
CD 21   INT  21H
B2 0A   MOV  DL, 0AH
CD 21   INT  21H
59      POP  CX             ; restore outer loop
58      POP  AX             ; restore original AL
E2 CC   LOOP LOOP_Y2        ; loop row display
59      POP  CX             ; restore byte counter
E2 C5   LOOP LOOP_Y         ; loop byte counter
    ENDM

В ASM это оказалось более унылым, чем я изначально думал. Многочисленные параллельные циклы и множество ветвлений if / else могут вызвать головную боль.

Это реализовано как MACRO, так как оно позволяет передавать функциональные параметры для тестирования.

Выход

Вот тестовая программа для DOS, которая запрашивает масштабный коэффициент X и Y и рисует на экране. Обратите внимание, что слишком большое масштабирование дракона будет прокручиваться за верх, так как окно DOS по умолчанию всего 24 строки.

введите описание изображения здесь

А вот и наш маленький дракончик (утка):

введите описание изображения здесь

Попробуйте онлайн!

Вы можете протестировать виртуальную машину DOS с помощью DOSBox или VirtualConsoles.com, выполнив следующие действия:

  1. Скачать VCS.ZIP (содержит все четыре исполняемых файла)
  2. Перейдите на https://virtualconsoles.com/online-emulators/DOS/.
  3. Загрузите ZIP-файл, который вы только что загрузили, нажмите Пуск
  4. Введите PLANE, KEY, TANKили DRAGON.



1

APL (Dyalog Extended) , 23 байта SBCS

метод Дзаймы

(v,час,В)vчасВ⎕IO←0

' x'⊇⍨∘⊃{⊖⍣(>⍺)⍉⍵/⍨|⍺}/

Попробуйте онлайн!

{}/ Уменьшить справа налево, используя следующую анонимную лямбду:

|⍺ величина левого аргумента (коэффициент масштабирования)

⍵/⍨ используйте это, чтобы воспроизвести правильный аргумент по горизонтали

 транспонирования

⊖⍣(... ) перевернуть, если:

  >⍺ коэффициент масштабирования меньше нуля

 раскрыть (поскольку сокращение включено, чтобы уменьшить ранг тензора с 1 до 0)

' x'⊇⍨ выбрать элементы из строки "x", используя эту матрицу



1

T-SQL, 216 байт

Перед выполнением этого MS-SQL Studio Management нажмите CRTL-t, чтобы отобразить данные в виде текста. Высота не может быть отрегулирована так, чтобы превышать количество элементов на входе.

Из-за ужасной реализации STRING_AGG переменная высоты будет работать только в MSSM. MS должен был сделать третий необязательный параметр, чтобы включить порядок сцепляемых элементов.

Онлайн-версия может поддерживать только настройку ширины. Высота приведет к броскому результату с несколькими формами укладки.

USE master
DECLARE @ table(v int,i int identity)
INSERT @ values
(0x06),(0x0F),(0xF3),(0xFE),(0x0E),(0x04),
(0x04),(0x1E),(0x3F),(0x7F),(0xE3),(0xC3),
(0xC3),(0xC7),(0xFF),(0x3C),(0x08),(0x8F),
(0xE1),(0x3F)
-- @  = width
-- @h = height
DECLARE @s INT=1,@h INT=1

SELECT iif(@s>0,reverse(x),x)FROM(SELECT
string_agg(replicate(iif(v&n=0,' ','X'),abs(@s)),'')x,i,j
FROM(values(1),(2),(4),(8),(16),(32),(64),(128))x(n)
,@,(SELECT top(abs(@h))i j FROM @)g GROUP BY i,j)f
ORDER BY i*@h

Этот скрипт не будет отображать правильные фигуры в онлайн-версии, поэтому я внес некоторые незначительные корректировки, чтобы компенсировать это. Попробуйте онлайн

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.