Переплетені струни


34

Ваша задача полягає в тому, щоб написати програму або функцію, яка при заданні двох рядків однакової довжини підміняє всі інші символи та виводить / повертає отримані рядки в будь-якому порядку.

Приклади

"Hello," "world!" --> "Hollo!" "werld,"
"code" "golf" --> "codf" "gole"
"happy" "angry" --> "hnpry" "aagpy"
"qwerty" "dvorak" --> "qvertk" "dworay"
"1, 2, 3" "a, b, c" --> "1, b, 3" "a, 2, c"
"3.141592653589" "2.718281828459" --> "3.111291623489" "2.748582858559"
"DJMcMayhem" "trichoplax" --> "DrMcMoylex" "tJichapham"
"Doorknob" "Downgoat" --> "Doonkoot" "Dowrgnab"
"Halloween" "Challenge" --> "Hhlloeegn" "Caallwnee"

Правила

  • Рядки містять лише символи ASCII (32-126).
  • Рядки завжди будуть однакової довжини і ніколи не будуть порожніми.
  • Ви можете прийняти введення в будь-якому відповідному форматі: окремі параметри, елементи в масиві, розділені одним або декількома новими рядками, навіть об'єднані. Єдине обмеження полягає в тому, що один рядок повинен повністю вийти перед іншим (наприклад, a1\nb2\nc3для "abc", "123"недійсного).
  • Вихід може бути в будь-якому порядку (тобто ви можете почати міняти з першого або другого символу), і в будь-якому дійсному форматі, згаданому вище. (2-елементний масив, розділений новими рядками, об'єднаними тощо)

Оцінка балів

Це , тому найкоротший код у байтах для кожної мови виграє.


11
+1 для DrMcMoylex. : D
DJMcMayhem

3
Анаграми "Dowrgnab" до "Downgrab" (͡ ° ͜ʖ ͡ °)
Mama Fun Roll

Вам слід чітко вказати, що правило "в будь-якому порядку" означає, що заміна може починатися з першого символу або другого.
DLosc

@DrMcMoylex Візьміть код, приклад гольфу . Якщо ми поміняємо місцями, починаючи з другого символу, отримуємо: c o d f , g o l e . Починаючи з першого символу: g o l e, c o d f.
DLosc

Відповіді:


14

Хаскелл, 37 байт

l=(,):flip(,):l
(unzip.).zipWith3($)l

Застібаючи дві струни, по черзі поміняючи символи, потім розпакуйте їх.

37-байт-рекурсивна альтернатива:

(a:b)?(c:d)=a:d?b
e?_=e
a%b=(a?b,b?a)

9

Python, 42 байти з гольф вводу / виводу

def f(a,b):a[1::2],b[1::2]=b[1::2],a[1::2]

Замінює всі інші символи двох списків. Приймає як вхід два списки символів , а виводить , змінюючи їх .

l=list('cat')
m=list('dog')    
print l,m

def f(a,b):a[1::2],b[1::2]=b[1::2],a[1::2]

f(l,m)
print l,m

дає

['c', 'a', 't'] ['d', 'o', 'g']
['c', 'o', 't'] ['d', 'a', 'g']

1
Це розумно. Чи вважаєте ви формати введення / виведення занадто гнучкими?
ETHproductions

@ETHproductions Не впевнені, що, можливо, в основному специфічні для Python, що списки настільки маніпульовані, ніж рядки.
xnor

8

Вим, 18 , 17 байт

qqyljvPkvPll@qq@q

Спробуйте в Інтернеті!

Для цього використовується інтерпретатор V через зворотну сумісність. Вводиться у такому форматі:

string1
string2

Пояснення:

 qq                 " Start recording in register 'q'
   yl               " Yank one letter
     j              " Move down a row
      vP            " Swap the yanked letter and the letter under the cursor
        k           " Move back up a row
         vP         " Swap the yanked letter and the letter under the cursor
           ll       " Move two letters to the right. This will throw an error once we're done
             @q     " Call macro 'q' recursively
               q    " Stop recording.
                @q  " Start the recursive loop

Виріжте дві літери, використовуючи xзамість, ylа потім jus Pзамість другої vP:lqqxjvPkPll@qq@q
Hauleth

@lukasz Я спробував це спочатку, але з будь-якої причини, він запускає його занадто багато разів і міняє останні букви, коли не повинен. Я ще раз
розберуся в цьому

Для мене працює v.tryitonline.net/…
Hauleth,

1
@ ŁukaszNiemier Це посилання має той самий код, що і я. Ви натиснули [save]кнопку? Так чи інакше, це не працює для мене . Справжня причина тому, що коли ви xостанній символ у рядку, він переміщує курсор ліворуч, псуючи розміщення свопу.
DJMcMayhem

6

Haskell, 41 байт

(a:b)#(c:d)=(a,c):d#b
_#_=[]
(unzip.).(#)

Повертає пару з рядками. Приклад використання: ( (unzip.).(#) ) "Hello," "world!"-> ("Hollo!","werld,").

Простий рекурсивний підхід: візьміть першу таблицю кожного рядка як пару та додайте рекурсивний виклик із заміненими (рештою) рядками. unzipробить із списку пар пару списків.


6

05AB1E , 11 10 байт

øvyNFÀ}})ø

Спробуйте в Інтернеті!

Пояснення

input = ["code", "golf"]використовується як приклад.

ø             # zip strings into list of pairs
              # STACK: ['cg', 'oo', 'dl', 'ef']
 vy           # for each pair
   NFÀ        # rotate left index times
      }}      # end-if, end-loop
              # STACK: 'cg, 'oo', 'dl', 'fe'
        )ø    # wrap in list and zip
              # OUTPUT: ['codf', 'gole']

5

Perl, 48 байт

В число рахунків входить 47 байт коду та -pпрапора.

say<>=~s%.\K(.)%"s/.{$-[0]}\\K(.)/$1/;\$1"%geer

Бігти з -pі -Eпрапор. Очікуйте кожного рядка в іншому рядку:

perl -pE 'say<>=~s%.\K(.)%"s/.{$-[0]}\\K(.)/$1/;\$1"%geer' <<< "Hello
World"

Пояснення :

-p: захоплює вхід $_і друкує його наприкінці. (щоб отримати та надрукувати перший рядок)
<>: отримайте рядок введення. (щоб отримати другий рядок).
=~: застосувати регулярний вираз до <>:, s%%%geerде завдяки rзміненому рядку повертається (а потім надрукується завдяки say).
Регекс:
.\K(.)знаходить два символи і замінить другий результатом оцінки цього коду "s/.{$-[0]}\\K(.)/$1/;\$1":
Перша частина s/.{$-[0]}\\K(.)/$1/застосовує регекс до $_: .{$-[0]}пропускає перші символи, щоб дістатися до тієї ж точки, що і зовнішній регекс (оскільки $-[0]містить індексу першої групи захоплення, тож у такому випадку індекс символів, що підлягає заміні), а потім ми фіксуємо знак з(.)і замініть його символом зовнішнього регулярного вираження ( $1). І тоді ми додаємо, $1тому результатом "s/.{$-[0]}\\K(.)/$1/;\$1"є характер, якого ми захопили у внутрішній вираз.
Можливо, ви помітили, що $1посилання на символ, якого ми хочемо замінити в обох рядках (так це два різних символи), тому ми граємо з /eeмодифікатором регулярного виразу, який двічі оцінює праву частину регулярного виразу: перший замінить лише те, $1що не є не передує \.


5

Пітон, 55 байт

lambda a,b:[(-~len(a)/2*s)[::len(a)+1]for s in a+b,b+a]

Нарізання!

58 байт:

def f(a,b):n=len(a);print[(s*n)[:n*n:n+1]for s in a+b,b+a]

64 байти:

f=lambda a,b,s='',t='':a and f(b[1:],a[1:],s+a[0],t+b[0])or[s,t]

Рекурсивно накопичує символи двох рядків у sта tта виводить їх пару в кінці. Чергування здійснюється перемиканням вхідних рядків кожного рекурсивного виклику. Виведення рядка, розділеного пробілом, було однакової довжини:

lambda a,b,s='',t=' ':a and f(b[1:],a[1:],s+a[0],t+b[0])or s+t

Це вузько вибиває різну рекурсивну стратегію по черзі приймати символи з кожної струни, причому кожна з двох можливих рядків є першою. (65 байт)

g=lambda a,b:a and a[0]+g(b[1:],a[1:])
lambda a,b:(g(a,b),g(b,a))

4

MATL , 11 10 9 8 байт

Завдяки ETHproductions за 1 байт!

"@X@YS&h

Вхідний є 2D масив , що містить два рядки, такі як: ['Halloween'; 'Challenge']. Вихідні рядки у зворотному порядку.

Спробуйте в Інтернеті!

Пояснення

        % Input 2D array implicitly
"       % For each column
  @     %   Push current column
  X@    %   Push iteration index, starting at 1
  YS    %   Circularly shift the column by that amount
  &h    %   Concatenate horizontally with (concatenated) previous columns
        % End implicitly
        % Display implicitly

Стара версія: 9 байт

tZyP:1&YS

Пояснення

        % Take input implicitly
t       % Duplicate 
        % STACK: ['Halloween'; 'Challenge'], ['Halloween'; 'Challenge']
Zy      % Size
        % STACK: ['Halloween'; 'Challenge'], [2 9]
P       % Flip array
        % STACK: ['Halloween'; 'Challenge'], [9 2]
:       % Range. Uses first element of the array as input
        % STACK: ['Halloween'; 'Challenge'], [1 2 3 4 5 6 7 8 9]
1&YS    % Circularly shift each column by those amounts respectively
        % STACK: [Caallwnee';'Hhlloeegn']
        % Display implicitly

@ETHproductions Так! Дякую!
Луїс Мендо

4

Желе , 5 байт

żṚż¥/

Введення є окремими аргументами, вихід об'єднаний.

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

żṚż¥/  Main link. Left argument: s (string). Right argument: t (string)

ż      Zipwith; yield the array of pairs of corresponding characters of s and t.
   ¥   Combine the two links to the left into a dyadic chain:
 Ṛ         Reverse the chain's left argument.
  ż        Zip the result with the chain's right argument.
    /  Reduce the return value of the initial ż by the quicklink Ṛż¥.

4

Желе , 9 8 6 байт

Дякуємо Деннісу за збереження 2-х байт!

Zṙ"J$Z

Використовує кодування Jelly .

Спробуйте в Інтернеті!


Ви можете використовувати ṙ"J$замість Ėṙ@/€. Крім того, розділяти рядок не потрібно, тому ви можете скинути Y.
Денніс

@Dennis Ahh, це акуратно. Спасибі! :)
Аднан



3

JavaScript (ES6), 51 54

Відредагуйте 3 байти, збережені thx @Neil

Функція з входом / виходом масиву

p=>p.map((w,i)=>w.replace(/./g,(c,j)=>p[i+j&1][j]))

Мені це подобається ще один, але це 55 (2 рядки на вході, масив у виході)

(a,b)=>[...a].reduce(([p,q],c,i)=>[q+c,p+b[i]],['',''])

Тест

f=
p=>p.map((w,i)=>w.replace(/./g,(c,j)=>p[i+j&1][j]))

function go() {
  var a=A.value, b=B.value
  if (a.length == b.length)
    O.textContent = f([a,b]).join('\n')
  else
    O.textContent = '- different length -'
    
}

go()
<input id=A value='Hello,'><input id=B value='world!'>
<button onclick='go()'>go</button><pre id=O></pre>


replaceекономить вам 3 байта: p=>p.map((w,i)=>w.replace(/./g,(c,j)=>a[i+j&1][j])).
Ніл

2

Pyth, 8 байт

C.e_FbkC

Спробуйте в Інтернеті: Демонстрація

Транспортує слова, перевертає кожну пару літер «поточний індекс»-разів, переносить знову.


2

JavaScript (ES6), 55 байт

f=([c,...s],[d,...t],o="",p="")=>c?f(t,s,o+c,p+d):[o,p]

Я хотів зробити щось розумніше, використовуючи regexp для заміни альтернативних символів, але це в результаті взяло 67 57 байт:

a=>a.map((s,i)=>a[+!i].replace(/.(.?)/g,(_,c,j)=>s[j]+c))

Приємно. У мене була f=([a,...A],[b,...B])=>a?[a+f(B,A)[0],b+f(A,B)[0]]:[""]однакова довжина.
ETHproductions

Я сподівався зробити набагато краще, але ніяк, просто на 1 менше. Час для публікації нерекурсивної відповіді
edc65

@ edc65 Приємна ідея використання map , вона 10 байтів від моєї відповіді на регулярний вираз Ще занадто довго, хоча.
Ніл

2

Perl, 40 байт

Включає +1 для -n

Надайте рядки як рядки на STDIN

interlace.pl
hello
world
^D

interlace.pl

#!/usr/bin/perl -n
s/./${1&$.+pos}[pos]=$&/seg}{print@0,@1

2

Java, 132 103 100 байт

Дякуємо Kevin Cruijssen за пропозицію повернути масив (серед інших вдосконалень) та зберегти 29 байт! Також Олів'є Грегоар на 3 байти!

char[]c(char[]s,int l){for(int o=l;o-->0;)if(o%2>0){char t=s[o];s[o]=s[l+o+1];s[l+o+1]=t;}return s;}

Називається так:

public static void main(String[] args) {
    System.out.println(c("Hello,world!".toCharArray(), 5)); // 5 is the length of each "String"
}

Вихід:

Hollo,werld!

Скористається тим, що вхід може бути відформатований будь-яким способом (у цьому випадку єдиний масив рядків рядків, які розділені комою), а також досить м'які правила виведення.


Привіт, оригінальний формат введення у вас є. Ви можете пограти ще трохи: char[]c(char[]s,int l){for(int o=l,t;o-->0;)if(l%2>0){t=s[l];s[l]=s[l+o+1];s[l+o+1]=(char)t;}return s;}( 103 байти ), а вихід буде повернутий замість надрукованого безпосередньо. Приклад введення System.out.println(c("Hello,world!".toCharArray(), 5));:; Приклад виведення: Hollo,werld!.
Кевін Кройсейсен

Щоправда, я чомусь не думав просто повертати масив char. Це чудово!
Hypino

Результат повинен бути, Hollo!werld,а не Hollo,werld!(пунктуація неправильна). Я вважаю, що це можна виправити за допомогою вхідного значення 6 замість 5.
Олів'є Грегоар

Оскільки ви звертаєтесь tдо цього char, чому б ви не оголосили його у циклі for прямо як char? Ви запасите кілька байт, роблячи це.
Олів'є Грегоар

На жаль, ти не можеш оголосити знак char в ініціалізаторі for-loop, але ти надихнув мене перевірити, чи буде декларування символу окремо коротше, ніж вказівник, і це дійсно на 1 байт.
Hypino

1

C, 124 байти

main(c,v)char**v;{char a[99],b[99];for(c=0;v[1][c]^0;++c){a[c]=v[1+c%2][c];b[c]=v[2-c%2][c];}a[c]=0;b[c]=0;puts(a);puts(b);}

Телефонуйте за допомогою:

program.exe string1 string2

Довжина рядка обмежена 98 символами.



1

Ракетка 208 байт

(let((sl string->list)(ls list->string)(r reverse))(let p((s(sl s))(t(sl t))(u'())(v'())(g #t))(if(null? s)
(list(ls(r u))(ls(r v)))(p(cdr s)(cdr t)(cons(car(if g s t))u)(cons(car(if g t s))v)(if g #f #t)))))

Безголівки:

(define (f s t)
  (let ((sl string->list)                ; create short names of fns
        (ls list->string)
        (r reverse))
    (let loop ((s (sl s))                ; convert string to lists
               (t (sl t))
               (u '())                   ; create empty new lists
               (v '())
               (g #t))                   ; a boolean flag
      (if (null? s)                      ; if done, return new lists converted back to strings
          (list (ls (r u))
                (ls (r v)))
          (loop (rest s)
                (rest t)                 ; keep adding chars to new lists alternately
                (cons (first (if g s t)) u) 
                (cons (first (if g t s)) v)
                (if g #f #t))            ; alternate the boolean flag
          ))))

Тестування:

(f "abcdef" "123456")

Вихід:

'("a2c4e6" "1b3d5f")

Вище - рекурсивна версія.

Ітеративна версія:

(let*((sl string->list)(ls list->string)(r reverse)(s(sl s))(t(sl t))(l'())(k'())(p(λ(a b g)(set! l(cons(if g a b)l))
(set! k(cons(if g b a)k)))))(for((i s)(j t)(n(in-naturals)))(p i j(if(= 0(modulo n 2)) #t #f)))(list(ls(r l))(ls(r k))))

Безголівки:

(define (f s t)
  (let* ((sl string->list)              ; create short form of fn names
         (ls list->string)
         (r reverse)

         (s (sl s))                     ; convert strings to lists
         (t (sl t))

         (l '())                        ; create empty lists for new sequences
         (k '())

         (p (λ(a b g)                   ; fn to add chars to one or other list
              (set! l (cons (if g a b) l))
              (set! k (cons (if g b a) k)))))

    (for ((i s)(j t)(n (in-naturals)))  ; loop with both strings
          (p i j                        ; add to new lists alternately
             (if (= 0 (modulo n 2)) #t #f)))

    (list (ls (r l))                  ; convert reversed lists to strings
          (ls (r k)))))

1

PowerShell v2 +, 82 байти

param($a,$b)$i=0;[char[]]$a|%{$c+=($_,$b[$i])[$i%2];$d+=($b[$i],$_)[$i++%2]};$c;$d

Ще гольф ... Ні. Не може здатися, що це полегшено без використання регексу, як інші відповіді (бу на алгоритмах копіювання).

Таким чином , ми приймаємо $aі $bяк рядки, заданий індекс $iдо 0, гіпсі $aяк char-array, і відправити його через петлю |%{...}. Кожну ітерацію ми об'єднуємо на рядок $cі $dіндексуємо у масив вибору (тобто, таким чином, він чергується вперед і назад). Тоді, ми залишаємо $cі $dна конвеєрі, і вихід через неявне Write-Outputвідбувається при завершенні програми.


1

Літп , 120 символів (+3 для -v1 прапор)

Розділення рядків на 2 для читабельності:

#P::((invoke P "map" (js-bridge #W,I::(replace W (regex "." "g")
     (js-bridge #C,J::(index (index P (& (+ I J) 1)) J))))))

Потрібен -v1прапор, run.jsоскільки деякі функції ще не є частиною стандартної бібліотеки.

Використання зразка:

(
    (def f #P::((invoke P "map" (js-bridge #W,I::(replace W (regex "." "g")
                (js-bridge #C,J::(index (index P (& (+ I J) 1)) J)))))))
    (print (f (list "Hello," "world!")))
)

Такого роду основні моменти, що я не витратив достатньо часу на стандартну бібліотеку. Необхідність використовувати js-bridge/1двічі та довгу форму регулярного вираження, а також використовувати карту, використовуючи invoke/*все, сприяють цьому набагато довше, ніж потрібно.

Час більше працювати над моєю стандартною бібліотекою, я думаю.


1

PHP, 79 байт

for(;$i<=strlen(($a=$argv)[1]);$y.=$a[2-$i%2][$i++])echo$a[1+$i%2][+$i]??" $y";

Попередня версія PHP, 82 байти

for(;$i<strlen(($a=$argv)[1]);$y.=$a[2-$i%2][$i++])$x.=$a[1+$i%2][$i];echo"$x $y";

for(...)echo$a[1+$i%2][$i];echo" $y";(-2)
Тит

for(;$i<=strlen(($a=$argv)[1]);$y.=$a[2-$i%2][$i++])echo$a[1+$i%2][$i]??" $y";складання коментаря Тіта - це ще -2, хоча для цього потрібен php 7
user59178

@ user59178 приємно, але вам потрібно ще 1 байт
Jörg Hülsermann

чи ти? це працює для мене, ви просто отримуєтеNotice: String offset cast occurred in Command line code on line 1
user59178

@ user59178 Так, щоб надрукувати першу букву першого слова
Jörg Hülsermann

1

C, 54 52 байти

f(char*a,char*b,char*c){while(*c++=*a++,*c++=*b++);}

Припускає, що вихід cмає вже бажану довжину.

Використання:

main(){
 char a[]="123456";
 char b[]="abcdef";
 char c[sizeof(a)+sizeof(b)-1];
 f(a,b,c);
 puts(c);

}

Якщо ви наполягаєте на створенні виводу, ось рішення на 91 байт :

char*g(char*a,char*b){char*c=malloc(2*strlen(a)),*d=c;while(*c++=*a++,*c++=*b++);return d;}

Використання:

main(){
 char a[]="123456";
 char b[]="abcdef";
 puts(g(a,b));
}

0

C, 150 байт

Я використав типові упущення файлів заголовків і main() тип повернення та оператор return. Він кидає попередження, але складається без випуску. Я також застосував специфічний для GCC трюк, який дозволяє декларації масиву зі змінними виразами.

Програма очікує рядки з командного рядка, і як таку програму слід запускати ./a.out string1 string2.

main(int a,char**v){int x=strlen(v[1]);char s[x],t[x],c;strcpy(s,v[1]);strcpy(t,v[2]);for(a=0;a<x;++a)if(a%2)c=s[a],s[a]=t[a],t[a]=c;puts(s),puts(t);}

Або більш розбірливо,

main(int a,char**v){
    int x=strlen(v[1]);
    char s[x],t[x],c;
    strcpy(s,v[1]);strcpy(t,v[2]);
    for(a=0;a<x;++a)
        if(a%2)c=s[a],s[a]=t[a],t[a]=c;
    puts(s),puts(t);
}

0

Математика, 51 байт

Приймає вхід як масив з двох масивів символів, з виведенням в одному форматі. Функція просто будує новий масив за допомогою операції (mod 2).

Table[#[[Mod[j+i,2]+1,j]],{i,2},{j,Length@#[[1]]}]&

0

QBasic 4,5, 172 байти

О, це стає боляче з ol 'QBasic ...

DEFSTR A-D:INPUT A,B
IF LEN(A)MOD 2=1 THEN A=A+" ":B=B+" "
FOR x=1 TO LEN(A) STEP 2
C=C+MID$(A,x,1)+MID$(B,x+1,1):D=D+MID$(B,x,1)+MID$(A,x+1,1):NEXT:?RTRIM$(C),RTRIM$(D)

Факт забави: Використання DEFSTRзбереженого більше байтів, ніж коштувало, тому що тепер я міг би використовувати Aзамість a$.


0

QBIC , 112 байт

QBIC може впорядкувати багато котлових панелей QBasic, але основний MID$двигун все ж повинен бути виконаний у QBasic, оскільки QBIC не має функції підрядки. Все-таки економить мені 60 байт.

;;_LA|~a%2=1|A=A+@ | B=B+C][1,a,2|X=X+$MID$(A$,b,1)+MID$(B$,b+1,1):Y$=Y$+MID$(B$,b,1)+MID$(A$,b+1,1)|]?_tX|,_tY|

MIND$=> MIN$в тексті.
Не те, що Чарльз

0

Java, 68 байт

(a,b)->{for(int i=a.length;--i>0;){char t=a[--i];a[i]=b[i];b[i]=t;}}

Безгольовий і тестування

import java.util.Arrays;
import java.util.Collection;
import java.util.function.BiConsumer;

public class Main {

  static BiConsumer<char[], char[]> func = (left, right) -> {
      for (int i = left.length; --i > 0;) {
        char temp = left[--i];
        left[i] = right[i];
        right[i] = temp;
      }
    };

  public static void main(String[] args) {
    test("Hello,","world!", "Hollo!", "werld,");
    test("code", "golf", "codf", "gole");
    test("happy", "angry", "hnpry", "aagpy");
  }

  private static void test(String left, String right, String x, String y) {
    char[] leftChars = left.toCharArray();
    char[] rightChars = right.toCharArray();
    func.accept(leftChars, rightChars);
    Collection mixed = Arrays.asList(new String(leftChars), new String(rightChars));
    if (mixed.containsAll(Arrays.asList(x, y))) {
      System.out.println("OK");
    } else {
      System.out.printf("NOK: %s, %s -> %s%n", left, right, mixed);
    }
  }
}

0

APL, 12

{↓(⍳⍴⊃⍵)⊖↑⍵}

Пояснення: {...} визначає функцію, ⍵ - правильний аргумент. Take (↑) створює матрицю з двох рядків, потім обертає кожен стовпець (⊖) n разів, де n - це частина в круглих дужках (⍳⍴⊃⍵). Це визначається як йота тривалості першого аргументу. (Наприклад: довжина = 5 ==> 1 2 3 4 5). Отже, перший стовпчик обертається один раз, другий двічі (повертається до вихідних позицій), третій стовпець три рази і т.д. ...

Спробуйте це на tryapl.org

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.