Уявіть ці рядки


42

Натхненний цим ланцюжком коментарів ...

Я хочу enklactвирішити цю проблему, але не можу ...

@ETHproductions to enklact (v): реалізувати таблицю пошуку за допомогою підрозділу, що складається з унікальних елементів.


Залучення - це дуже корисний спосіб стиснення таблиці пошуку. Наприклад, скажімо, у вас був такий список кольорів:

red
green
blue
yellow
purple
orange

Якщо ви хочете мати можливість взяти колір у якості введення та повернути його індекс у цьому списку, очевидно, є простий спосіб:

["red", "green", "blue", "yellow", "purple", "orange"].index(input())

Але є спосіб, як ми могли це зробити набагато менше байтів:

"rgbypo".index(input()[0])

Це працює, тому що перший (або 0'-й) індекс кожного рядка є унікальним. Цей приклад очевидний, але іноді це трохи складніше. Що робити, якщо ми хотіли скласти таблицю пошуку для цього списку?

Sweet Onion Chicken Teriyaki
Oven Roasted Chicken
Turkey Breast
Italian BMT
Tuna
Black Forest Ham
Meatball Marinara

У цьому випадку ми не можемо цього зробити:

"SOTITBM".index(input()[0])

тому що є два різних входи, які починаються з а 'T', а саме "тунець" та "Туреччина". Треба подивитися на інший показник. Якщо ви подивитесь на 4-й індекс кожного рядка, ви помітите, що всі вони унікальні. Тож ми можемо це зробити ...

"enklact".index(input()[3])

У цьому випадку "рядок прокляття" - це "інклакт".

Це призводить нас до сьогоднішнього виклику ...

Подаючи список рядків, поверніть будь-яку дійсну рядок обкладинки. Або іншими словами, задавши список рядків, повертайте будь-яку нову рядок, де кожна літера є унікальною, а рядок формується приєднанням до i-ї літери кожного рядка.

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

Кожна рядок містить лише ASCII для друку, і це завдання залежить від регістру.

Це , тому постарайтеся написати найкоротшу можливу програму мовою на ваш вибір!

Тестові справи

Input:
Programming
Puzzles
Code
Golf

Output (any one of these):
"ozdl"
"gzef"


Input:
the quick
brown fox
jumped over
lazy dogs

Output:
"tbjl"
"hrua"
"eomz"
" wpy"
"qne "
"if o"
"kxvs"

Note that "u dd" and "coog" are not valid.


Input:
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

Output:
""


Input:
AbC
aBc
bbC

Output:
"Aab"


Input:
@#$%^_
Hello_World
How are you?

Output:
"#eo"
"$lw"
"%l "
"^oa"


Input:
a
ab
ac

Output:
""

Чи можемо ми повернути список дійсних рядків?
LyricLy

@LyricLy Хм, тепер, коли я думаю про це, це мало б більше сенсу. Але оскільки відповіді вже є, і повернути першу не дуже багато, я збираюся сказати «ні», це має бути будь-який дійсний рядок.
DJMcMayhem

Чи можемо ми гарантувати, що жодна із введених рядків не буде порожньою?
музикант523

6
Чи може значення послідовного помилки бути помилкою послідовного типу?
Стюі Гріффін

2
Вибачте, але я вважаю, що правильне дієслово є складовим .
Ерік Аутгольфер

Відповіді:


8

Python3, 59 байт

lambda l:{len({*d}):''.join(d)for d in zip(*l)}.get(len(l))

Повертає рядок із закликом, інакше


8

Пітон 2 , 68 67 61 байт

lambda a:`{0:j for j in zip(*a)if len(set(j))==len(j)}`[6::5]

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

Поліпшення


Якщо для виводу не повинно бути рядок:

Python 3 , 49 байт

lambda a:[j for j in zip(*a)if len({*j})==len(j)]

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



@JoKing Елегантний та реалізований.
Ніл

Я думаю, що max(`j`[2::5]for j in[""]+zip(*a)if len(set(j))==len(j))працює, щоб зберегти байт.
Лінн

@Lynn спасибі та оновлено.
Ніл

7

Сітківка , 43 32 байти

+/^(.).+^\1|^$/ms&m`^.

|""Lm`^.

Спробуйте в Інтернеті! Редагувати: Збережено 11 байт завдяки @MartinEnder. Пояснення:

+

Повторіть, коли вхід змінюється ...

/^(.).+^\1|^$/ms&

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

m`^.

... видалити перший символ кожного рядка. Отже, повтор припиняється, якщо або: а) всі рядки починаються з різних символів; у цьому випадку умова не вдається, а вхід не змінюється, або б) принаймні один рядок стає порожнім, і в цьому випадку всі символи з часом видаляються, в який момент вхід припиняє змінюватися.

|""L`^.

Зберіть перший символ кожного рядка. (Якщо не було рішення, вищевказаний цикл видалив би все, і нічого не буде збирати.)


Параметри Regex також приймають модифікатори регулярних виразів (записуючи їх безпосередньо після закритого роздільника): tio.run/##K0otycxLNPz/…
Мартін Ендер

Насправді це дозволяє повністю позбутися другого етапу: tio.run/##K0otycxLNPz/X1s/… (якимось чином тут не можна застосувати mдо групи, схоже, умовний етап не поширює цей параметр).
Мартін Ендер

Ну, звичайно, циклічне циклічне замість умовного циклу, яке вирішує нескінченну помилку циклу у вашій першій версії. Дуже акуратно!
Ніл

5

Haskell , 71 байт

f x|elem""x=""|y<-head<$>x,and[filter(==a)y==[a]|a<-y]=y|1<2=f$tail<$>x

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

BMO зберегло 3 байти за допомогою any null xelem""x.

Ørjan Johansen врятував байт з sum[1|b<-y,a==b]<2filter(==a)[y]==[a].

Пояснення

f x|elem""x=""                      -- Once any of the strings is empty, return "".
   |y<-head<$>x                     -- Otherwise, let y be all the first letters...
   ,and[                 |a<-y]     -- If, for all a in y,
        filter(==a)y==[a]           -- a occurs just once in y:
                               =y   -- return y.
   |1<2=f$tail<$>x                  -- Else, chop off all the first letters and recurse.

Якщо помилка кидання ( Prelude.head: empty list), коли рішення не в порядку, |elem""x=""може бути стерто на 61 байт .


1
Коротше випробування:filter(==a)y==[a]
Ørjan Johansen

4

Рубін , 38 байт

->x,*y{x.zip(*y).find{|z|z==z-[p]|[]}}

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

Завдяки GB за вказівку на помилку.


Виходить з ладу, якщо немає відповідності, і перший рядок не найкоротший.
ГБ

@GB Чи можете ви надати приклад? Я змінив свій останній тест відповідно до вашого опису, і він спрацював.
Кирило Л.

Спробуйте ["abc", "ac", "acd"]
GB

Тепер я бачу, ти маєш рацію. Слід виправити.
Кирило Л.

4

Pyth , 6 байт

>1{I#C

Тестовий набір.

Вихід є однотонним списком, як це дозволено за замовчуванням ; список [] (порожній список, фальшивий) повертається у випадку, якщо рядок не можна просвічувати .

Пояснення

> 1 {I # C - Повна програма.
     C - Перенесіть введення, обрізаючи прогули.
    # - Фільтрувати за:
  {Я - інваріант під дедуплікацією.
> 1 - Зріз до 1. списку [: 1] в Python.

Pyth , 5 байт

Це було б дійсно, якби збій вважався б фальшивим значенням.

h{I#C

Тестовий набір.


3

Haskell , 76 74 байт

f t=last$"":(id=<<foldr(zipWith(#))([[]]<$t)t)
x#[s]=[x:s|all(/=x)s]
x#e=e

Спробуйте в Інтернеті! Повертає останній дійсний рядок пошуку або порожній рядок, якщо такої рядки не існує.


71 69 байт

Якщо викинути послідовний виняток, оскільки значення фальшивого дозволено:

f t=head$id=<<foldr(zipWith(#))([[]]<$t)t
x#[s]=[x:s|all(/=x)s]
x#e=e

Спробуйте в Інтернеті! Викидає empty listвиняток, якщо жодної рядки не знайдено, повертається перша дійсна рядок інакше.

-2 байти завдяки Ørjan Johansen


1
notElem x можна скоротити до all(/=x).
Ørjan Johansen

2

Желе , 7 байт

z0Q€fZḢ

Повертає ціле число 0, якщо рядки не можуть бути підкреслені.

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

Як це працює

z0Q€fZḢ  Main link. Argument: A (string array)

z0       Zip/transpose, filling shorter rows with 0.
  Q€     Unique each deduplicate resulting string.
     Z   Zip/transpose, without using a filler.
    f    Filter; keep only string that appear in the results to both sides.
      Ḣ  Head; extract the first string. Returns 0 if the array is empty.


2

Стакс , 9 8 байт

åτIⁿs↓µg

Запустіть і налагоджуйте його

Пояснення (розпаковано):

M{c0-u=}j Full program, implicit input
          e.g. ["Programming", "Puzzles", "Code", "Golf"]
M         Transpose
                ["PPCG", "ruoo", "ozdl", "gzef", "rl\0\0", "ae\0\0", "ms\0\0", "m\0\0\0", "i\0\0\0", "n\0\0\0", "g\0\0\0"]
 {     }j Find first matching element:
            e.g. "PPCG"
  c0-       Copy and remove zero bytes (padding)
                 "PPCG" "PPCG"
     u      Unique
                 "PPCG" "PCG"
      =     Check if equal:
                 1
          First matching here: "ozdl". If none is found, the stack is empty
          Implicit output if anything on stack

2

R , 127 байт

function(S,s=sapply(S,substring,x<-1:max(nchar(S)+1),x))cat(rbind(s[!apply(s,1,anyDuplicated)&!rowSums(s==""),],"")[1,],sep="")

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

sapplyзазвичай повертає a, matrixколи всі length(FUN(X[[i]]))рівні рівні, за винятком випадків, коли length(FUN(X[[i]]))==1в такому випадку він повертає a vector. Для того, щоб використовувати матричні операції, тоді нам потрібно зробити ще substringодну, ніж нам потрібно гарантувати a matrix, через що xпоширюється і на max(nchar(S)+1).

Потім фільтруємо рядки, у яких немає дублікатів і порожніх рядків. Оскільки ми можемо повернути лише один рядок, ми беремо першу, за винятком випадків, коли немає рядків, які відповідають критеріям, ми б видали помилку, тому додаємо додатковий рядок ""до кінця.

Потім ми роздруковуємо enklactіфікований рядок або порожній рядок.


2

R , 116 107 95 байт

R + прир

pryr::f(for(i in 1:min(nchar(v)))`if`(anyDuplicated(t<-substr(v,i,i)),0,{cat(t,sep="")
break}))

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

база R

function(v)for(i in 1:min(nchar(v)))`if`(anyDuplicated(t<-substr(v,i,i)),0,{cat(t,sep="")
v=0})

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

Ці два варіанти заощаджують 9 байт завдяки Джузеппе .

Пояснення:

Це ефективно обрізає всі струни у векторі vдо найкоротшої довжини і повторюється за допомогою наступних індексів. Потім перевіряє, чи є дублікати у вибраних літерах, а якщо ні, вставляє їх разом і друкує cat. Якщо всі індекси повертають дублювані результати, це друкує порожній рядок.
Усі обернені анонімною pryrфункцією з breakзупинкою циклу або базовою функцією R, обнулення вектора для розриву циклу.


1
Хороший! Це може бути golfed до 107 байтів в R+pryrчи 107 байтів в базовій R.
Giuseppe

2

Japt, 9 байт

Приймає введення як масив символьних масивів, повертає масив символів або undefined

y æ_f eZâ

Спробуйте (Додайте новий рядок на початку програми з кодом, qR mqщоб прийняти введення як відокремлений рядок у новому рядку, щоб врятувати вам клопоту щодо створення масивів.)


Пояснення

y             :Transpose
  æ_          :Pass each array Z through a function and return the first that returns true
    f         :  Filter nulls (used for padding when transposing)
      e       :  Test for equality with
       Zâ     :  Z deduplicated

Я спробував вирішити проблему, перш ніж прочитати ваше рішення, і отримав майже однакове рішення:z æ_¬eZ¬â
Nit

Точно однаковий, крім формату введення.
Кудлатий


1

Python 3 , 75 байт

def f(t):c=[s.pop(0)for s in t];return all(t)and(f(t),c)[len(t)==len({*c})]

Працює у списках символів замість рядків. Повертає помилково, якщо не існує дійсної рядка обкладинки.

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


Я думаю, що це повторюється, що зробило б його недійсним, якщо тільки f=в число байтів не включено.
LyricLy

@LyricLy Fixed :)
musicman523

1

C (gcc) , 161 байт

f(s,i)char**s;{char**t,a[255],*u=a;for(i=0;memset(a,0,255),u&&~i;i+=!!~i&&u)for(t=s;(u=u?*t++:0)&&~(i=u[i]?i:-1)&&!a[u[i]]++;);while(~i&&(u=*s++))putchar(u[i]);}

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

Кожна позиція символів перевіряється на дублювання та пропускається, якщо виявлений дублікат; це продовжується, поки не закінчиться найкоротший рядок. Це тільки ASCII, на жаль: рядки DBCS / UTF-8 погано порушують цю функцію!



1

Japt , 12 байт

Повернення undefinedдля неклактичних рядків.

y ·æ_¬n ä¦ e

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

Пояснення:

y ·æ_¬n ä¦ e
y             // Split the input at newlines and transpose
  ·           // Join on newlines 
   æ_         // Return the first item that returns truthy when ran through:
     ¬n       //   Sort
        ä¦    //   Reduce with !=
           e  //   All items are truthy (unique)

Ви повинні бути в змозі зберегти 2 байти, взявши введення як масив символьних масивів і викопавши два splits.
Кудлатий

1

Мова Вольфрама (Mathematica) , 54 байти

#&@@Select[PadRight@#,#~FreeQ~0&&Union@#==Sort@#&]&

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

Бере список списку символів як вхідний, повертає список символів. Містить U + F3C7, що відповідає оператору "Transpose".

Повертає #1та кидає купу невідомих помилок, коли немає відповідного рядка.

Пояснення:

PadRight@#

Прокладіть вхід так, щоб кожна "рядок" (список символів) була однакової довжини. До цього додається ціле число 0s (не рядок "0"s). Потім перенесіть.

Select[ ... ,#~FreeQ~0&&Union@#==Sort@#&]

Виберіть рядки, у яких немає цілих 0s, і всі унікальні символи.

#&@@

Отримайте перший.


1

JavaScript (ES6), 66 байт

Повертає або рядок, або undefinedякщо рішення не існує.

f=(a,i=0)=>a.every(s=>(o[k+=c=s[i],c]^=1)&&c,o=k=[])?k:c&&f(a,i+1)

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

Прокоментував

f = (           // f = recursive function taking:
  a,            //   a[] = input array
  i = 0         //   i   = pointer
) =>            //
  a.every(s =>  // for each string s in a[]:
    (o[k +=     //   append to the key string k
      c = s[i], //   the character c at position i in s
      c] ^= 1   //   and toggle o[c] (undefined -> 1 -> 0)
    ) && c,     //   additionally, make sure that c is defined
    o = k = []  //   start with o = k = empty array
  ) ?           // every() is true if all characters were distinct and defined:
    k           //   in which case we return k
  :             // else:
    c &&        //   provided that every() didn't fail because of an undefined character,
    f(a, i + 1) //   try again at the next position

1

Вугілля деревне , 23 21 байт

-2 байти завдяки @Neil !

§ΦE⌊EθLι⭆θ§λι⬤ι⁼¹№ιλ⁰

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


Так, коли а) qперестала завжди бути рядком b) StringMap почав працювати над не-рядками? У будь-якому випадку, ваше Rangeнепотрібне, заощаджуючи 2 байти.
Ніл

@Neil a) Коли я додав вхід масиву / об'єкта b)> _> Я не впевнений. ймовірно, приблизно в той час, коли я виправляв цикл while (вибачте, забув згадати будь-який із них)
лише ASCII

1

Лушпиння , 9 байт

ḟS=UḞz:∞ø

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

Пояснення

fS=UḞz:∞ø
    Ḟz:∞ø  Transpose the input dropping characters of longer strings
    Ḟ        Fold right
     z:      Zip with prepend
       ∞ø    Infinite list of empty lists
ḟS=U       Find the first string without duplicates, returns an empty string if none
ḟ            Return first value satisfying predicate
  =          Equal
 S U         to itself with duplicates removed

Використання " ←ġLTover" Ḟz:∞øмає зберегти байт.
ბიმო

1

Сітківка , 81 56 байт

m`$
$.=*£¢
N$`.
$.%`
¶

~`(.*?¢)+
L`.{$#1}
A`(.).*\1|£|¢

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

-25 байт завдяки @Neil


Транспонування прямокутного тексту в Retina напрочуд складно.


Я б хотів, щоб я знав кращий спосіб виконання прямокутної транспозиції, але в той же час заощадити 25 байт .
Ніл

@Neil Ahh ... eval stage. Я завжди забуваю, що retina 1.0 має всі ці цікаві нові функції
TwiNight

1

Perl 6 , 27 байт

{([Z] $_).first:{.Set==$_}}

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

Побачивши, що версія рубіну було схвалено, я скопіював підхід та використав списки символів замість рядків. Мені це не подобається.

Мої старші та правильніші подання:

Perl 6 , 38 байт

Розділіть, застебніть, перевірте унікальність, приєднуйтесь.

{[~] ([Z] @_>>.comb).first:{.Set==$_}}

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


1

C (gcc) , 121 113 110 байт

i;d;f(s)char**s;{char**_=s,x[255]={0},y[99]={0};for(d=i=0;*_;)d+=x[y[i++]=*(*_++)++]++;d=d?*x?0:f(s):puts(y);}

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

Безумовно

void enklactify(char *strings[]) {
    int quit = 0;
    while (!quit) {
        char **arg = strings;      // current row
        int exists[255] = {0};     // which characters exist in the column
        char output[99] = {0};     // will hold output string
        int index = 0;             // where to insert in output
        int duplicates = 0;        // have we found any duplicates?
        while (*arg != NULL) {
            char *word = *arg;     // current word
            char first = *word;    // first letter of current word
            if (exists[first])
                duplicates = 1;    // we found a duplicate
            exists[first] = 1;     // mark it as in our string
            output[index] = first; // add it to our output
            index++;
            (*arg)++;              // advances the current word to the next
                                   // character by reference (chops first char)
            arg++;                 // advance to next whole argument
        }

        if (!duplicates) {         // This is a valid solution
            puts(output);
            quit = 1;
        }

        if (exists[0]) {           // We hit the null terminator of one of the
                                   // input strings, so we failed
            quit = 1;
        }
    }
}

-3 завдяки плафоні

Це зловживає можливістю просто додати 1 до рядкового вказівника на C, щоб отримати "хвіст" рядка. Основними збереженнями байтів є:

  • d+=x[y[i++]=*(*_)++]++який додає перший символ першого рядка _до y, просуває перший рядок _для видалення першого символу, додає xзапис до цього символу dта збільшує вказаний xзапис
  • q=d?*x:puts(y)який друкує, yякщо dне є нульовим під час встановлення qненульового значення, або встановлює qне-нульове, якщо перший елемент xдорівнює нулю (якби ми були в кінці одного з рядків, тоді зазначений елемент був би не- нуль)

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


Запропонуйте for(d=i=0;*_;)замість цього for(d=0,i=0;*_;++_)і *(*_++)++]++;d=d?!*x*f(s)замість нього*(*_)++]++;d=d?*x?0:f(s)
roofcat

0

Pyth, 13 байт

e+kf{IT@.TQ.t

Спробуйте тут

e+kf{IT@.TQ.t
           .tQ   Transpose the (implicit) input with padding.
        .TQ      Transpose the input without padding.
       @         Take the strings in both.
   f{IT          Find the ones that have no duplicates.
e+k              Get the last, or an empty string.

1
Здається, що повернення списку всіх дійсних рядків недійсне.
LyricLy

@LyricLy Виправлено.
Мнемонічна

0

Червоний , 139 байт

func[b][m: length? first b foreach a b[m: min m length? a]repeat n m[c: copy[]foreach a b[append c a/(n)]if c = unique c[return rejoin c]]]

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

Пояснення:

Приймає вхід як блок (список) рядків. Повертає рядок інклаксації чи noneіншим чином.

f: func[b][
    m: length? first b                   ; the minimal length of the first string  
    foreach a b[m: min m length? a]      ; find the minimal length of all strings
    repeat n m[                          ; limit the search to the minimal length
        c: copy[]                        ; an empty block  
        foreach a b[append c a/(n)]      ; for each string append the current char
        if c = unique c[return rejoin c] ; if all chars are unique, return the block
    ]  
]

0

Roda , 80 77 байт

f a{a|seq 0,#_|try{{|i|a|[_[i:i+1]]|orderedUniq|concat|[_]if[#_1=#a]}_|head}}

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

-1 байт завдяки кряканню корів

Пояснення:

f a{
  a|         /* Push the strings in a to the stream */
             /* For each string (_): */
  seq 0,#_|     /* Push a range from 0 to the length of _ to the stream */
  try{       /* Ignore errors during the following block */
    {|i|        /* For each i in the stream: */
      a|           /* Push strings in a to the stream */
      [_[i:i+1]]|  /* For each string, push the ith character to the stream */
      orderedUniq| /* Remove duplicate characters */
      concat|      /* Join the characters into a string */
      [_]if        /* Push the string to the stream if */
      [#_1=#a]     /* Its length is the length of a */
    }_|
    head        /* Take the first string in the stream and return it */
  }
}

tryВикористовується ключове слово , щоб відхилити помилки , які виникають , якщо iбільше , ніж довжина найменшої рядки в a, або немає відповіді і headвикликає помилку.


Ви можете видалити паролі, seqщоб зберегти байт
Kritixi Lithos

@Cowsquack Дякую!
fergusq

0

Java 10, 106 байт

a->{for(int i=0;;i++){var r="";for(var s:a)r+=s[i];if(r.length()==r.chars().distinct().count())return r;}}

Буде помилка замість повернення порожнього рядка, якщо не знайти рішення. Введення - це матриця символів.

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

Пояснення:

a->{                  // Method with character-matrix parameter and String return-type
  for(int i=0;;i++){  //  Loop `i` upwards
    var r="";         //   Result-String, starting empty
    for(var s:a)      //   Loop over the character-arrays of the input
      r+=s[i];        //    And append every `i`'th character to `r`
    if(r.length()==r.chars().distinct().count())
                      //   If `r` only contains unique characters
      return r;}}     //    Return `r` as result

ОП, схоже, не хотіло допускати помилок, хоча, правда, ніколи не ставило їх на посаду.
Ørjan Johansen

0

Clojure, 59 байт

#(for[s(apply map list %):when(=(count(set s))(count %))]s)

Повертає список списків символів.


0

APL + WIN, 35 33 байт

2 байти збережено завдяки Adám

Підказки до рядків тексту як матриця символів:

⊃((↑⍴¨a)=+/¨((a⍳¨a)=⍳¨⍴¨a))/a←,⌿⎕

Спробуйте в Інтернеті! Надано Dyalog Classic

Пояснення:

a←,⌿⎕ prompts for input and creates a nested vector of the input matrix columns

((a⍳¨a)=⍳¨⍴¨a) creates a binary vector for each nested element with a 1 for each unique element

((↑⍴¨a)=+/¨ sums each binary vector and compares to number of characters in each element

(...)/a←⊂[1]⎕ selects only those elements where number of uniques = column length

⊃ converts nested vector back to a matrix of each valid enklaction string 

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