Яке це число в Shortlex?


15

Більшість комп'ютерів зберігають цілі числа у двійковій формі, але виводять їх у десятковій частині. Однак десяткові - це лише одне подання, ми просто трапимо це для зручного.

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

Що це?
http://en.wikipedia.org/wiki/Shortlex_order

Shortlex приймає довжину послідовності цифр як основний означувач значення. Послідовність, починаючи з порожнього рядка, що представляє нуль, є ...

ε,0,1,...,8,9,00,01,...98,99,000,001,...,998,999,0000,...

(Подумайте про стовпці Excel, але використовуючи лише десяткові цифри.)

Напишіть програму або функцію, яка приймає ціле число і повертає рядок, що відповідає коротко-десятковому поданню цього цілого числа, як описано вище.

Значення тесту:

0 → "" (Порожній рядок)
1 → "0"
10 → "9"
11 → "00"
42 → "31"
100 → "89"
800 → "689"
1060 → "949"
10270 → "9159"
100501 → "89390"


2
Можливо, важливо зауважити, що послідовність 19, 20, 21, 22у десяткових картах - 08, 09, 10, 11у шортлексі. Ось чому я використав це плутати 100 -> 89!
Шон Латем


6
Зауважте, що те, що ви називаєте "коротким десятковим числом" числа, також є його біективним базовим числом десять із символами {0,1,2,3,4,5,6,7,8,9}, заміненими на звичайні цифри {1,2,3,4,5,6,7,8,9, A}. Наприклад, 2014 р. У звичайних біективних позначеннях базової десятки дорівнює 1A14, а у краткому десятковій - 0903.
res

Відповіді:


34

JavaScript (ES6) 42 74

n=>(n-~(n+'').replace(/./g,8)+'').slice(1)

Тест в консолі FireFox

;[0,1,10,11,42,100,800,1060,10270,100501]
.forEach(x => console.log(x +" -> '" + S(x) + "'"))

Вихідні дані

0 -> ''
1 -> '0'
10 -> '9'
11 -> '00'
42 -> '31'
100 -> '89'
800 -> '689'
1060 -> '949'
10270 -> '9159'
100501 -> '89390'

Як я подумав про це?

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

  1..10 -> 0..9 (delta -1)
 11..110 -> 00..99 (delta -11)
111..1110 -> 000..999 (delta -111) mmm there's a pattern here...

Але провідними 0-ми важко керувати, тому у мене є стандартний трюк, додайте першу цифру та працюю модуль (тобто виріжте першу цифру у виході). Тоді -1-> +9, -11 -> +89, -111 -> +889 тощо.
Останній крок: мені байдуже, що таке перша цифра, тому немає необхідності перевіряти, чи є номер вводу <або> 111 ... (чесно я знайшов це шляхом проб і помилок)

Тест

var F=
n=>(n-~(n+'').replace(/./g,8)+'').slice(1)

function update()
{
  var i=+I.value
  O.textContent = F(i)
}


update()
<input id=I value=99 type=number oninput='update()'><pre id=O></pre>


8
Я поняття не маю, чому це працює.
Мартін Ендер

Чому ти робиш n-~(n+'')замість просто n-~n?
Клавдіу

@Claudiu це (n+'').replace(...), замініть твори на рядках, а не на числах.
edc65

@ edc65: На жаль, я просто зараз це схопив, не збігаючись з моїми дужками. Дайум це досить геніально
Клавдіу

3
@Денніс не соромтеся портувати його. Ви вже
виграєте

13

Marbelous 177 173 170

@0@6000000@5
}0&0&0&0&0
>0@6&3
\\--\/&2
@0/\@4\/&1!!
@4@1..@2@5@3
IIIIIIIIIIII
FF&1FF&2FF&3
@1OO@2OO@3OO
:I
}1..}10001F7
=9&1++..&1&0
&0}0&1&0{1{1
{>\/{0//
:O
}0
+Z
+C
{0

Він працює лише для значень під 256, оскільки Marbelous - це 8-бітна мова.

Як це працює

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

:O
}0
+Z
+C
{0

:O- це назва дошки (якщо бути точним, О - це ім'я та: вказує інтерпретоване, що цей рядок є ім'ям. Даючи дошці ім'я, інші дошки можуть зателефонувати на них }0- це вхідний пристрій, це може розглядатися як Аргумент цієї функції. Ця комірка буде замінена на вхідний мармур (значення), коли функція викликається, +Zдодає 35 до будь-якого мармуру, який проходить по ній, і дозволяє йому провалюватися. +Cробить те саме, але додає лише 12.{0 є вихідною коміркою , коли мармур досягне цієї комірки, функція вийде і поверне значення в цьому пристрої виводу.

Отже всі разом ця дошка приймає одне значення, а потім додає до неї 47. Для нас це означає, що це перетворює будь-яке одноцифрове число в код ассії цифри -1 (це, звичайно, також працює для 10).

:I
}1 .. }1 00 01 F7
=9 &1 ++ .. &1 &0
&0 }0 &1 &0 {1 {1
{> \/ {0 //

Ця дошка виглядає дещо складніше. Ви повинні мати можливість ідентифікувати :Iназву плати та помітити деякі пристрої введення та виведення. Ви помітите, що у нас є два різних пристрої введення }0та }1. Це означає, що ця функція займає 2 входи. Ви також помітите, що у пристрої є два екземпляри }1. Після виклику функції обидві ці комірки будуть містити однакове значення. Пристрій }0введення знаходиться безпосередньо над a\/ пристроєм, він виконує функцію кошика і видаляє будь-який мармур, який потрапляє на нього негайно.

Давайте подивимось, що відбувається з одним із мармурів, що вводяться на дошку }1пристроями введення:

}1
=9 &1
&0
{>

Він впаде на перший галочку і потрапить на =9пристрій. Це порівнює значення від мармуру до 9 і дозволяє мармуру провалюватися, якщо вислів =9оцінюється до "до". Мармур відсувається вправо, якщо ні. &0і &1є синхронізаторами. Вони тримаються за мармур, що падає на них, поки &nне заповняться також і всі інші синхронізатори. Як можна очікувати, це умовно спричинить різну поведінку на якійсь іншій частині дошки.

}1 00 01 F7
++ .. &1 &0
&1 &0 {1 {1
{0 //

Якщо я скажу вам, що ++це приріст, ви вже повинні мати можливість сказати, чим будуть заповнені різні синхронізатори. Зліва &1міститиме вхідне значення }1+ 1, &0наступне - 0 ( 00є літералом мови, представленим у шістнадцятковій кількості). Другий &1буде містити значення 1, і право &0заповнюється F7символом, який віднімає 9 від значення, оскільки додавання в Marbelous є модулем 256.

// - це дефлекторний пристрій, який штовхає будь-який мармур ліворуч, а не дає йому впасти.

Якщо все це зробити разом, це дає вам таке: якщо мармуру }19, &0синхронізатори заповнюються. Це призведе до падіння значення 0 у {0висновок та F7(або -9) у {1вихід. Якщо }1немає 9, {0буде заповнено }1+ 1 і {0буде містити 1. Також є {>пристрій, це спеціальний вихід, який виводить мармур поруч із дошкою замість нього. Це заповниться, }1якщо воно дорівнює 9.

@0 @6 00 00 00 @5
}0 &0 &0 &0 &0
>0 @6 &3
\\ -- \/ &2
@0 /\ @4 \/ &1 !!
@4 @1 .. @2 @5 @3
II II II II II II
FF &1 FF &2 FF &3
@1 OO @2 OO @3 OO

Гаразд, тепер для великого. Ця плата не має явного імені, оскільки вона є основною дошкою файлу. Її неявна назва Mb. Ви повинні мати можливість розпізнавати деякі клітини. Є пристрій введення, деякі мовні літерали ( 00і FF). Є кілька синхронізаторів і є дефлектор. давайте переходити через цю частину за штукою.

@0 @6
}0 &0
>0 @6
\\ --
@0 /\ @4

Отже вхідне значення (введення командного рядка, оскільки це головна плата) починається з другої комірки зверху, де }0знаходиться. Він впаде вниз і дістанеться до >0пристрою, який є іншим пристроєм порівняння. будь-який мармур, більший за 0, провалюється, будь-який інший мармур просувається праворуч. (оскільки змінні Marbelous не підписані, праворуч натисне лише рівно 0). Це мармурове нульове значення потім потрапить на @6пристрій. Це портал і транспортує мармур на інший відповідний портал, в даному випадку прямо над ним. Потім мармур 0 надійде до &0синхронізатора і запустить деякі речі в іншому місці.

Якщо мармур не дорівнює 0, він падає вниз, відхиляється праворуч \\ударами, --які зменшують його на один, а потім падають на /\клон. Цей пристрій бере мармур і видає одну його копію праворуч і одну ліворуч. Лівий буде піднесений вгору до іншого, @0де мармур знову пройде через ту саму послідовність. Ліву перенесуть в інше місце. Це дає нам цикл, який зменшує введення командного рядка один раз за цикл і запускає деяку поведінку в кожному циклі, поки він не досягне 0. Потім він запускає іншу поведінку.

Давайте подивимось, що відбувається з мармуром, просунутим у @4кожну петлю.

@4 @1 .. @2 @5 @3
II II II II II II
FF &1 FF &2 FF &3
@1 OO @2 OO @3 OO

Тут є 3 мовні літерали ( FF), які одразу потраплять на портали. Ці портали перейдуть на три IIпристрої. IIстосується дошки, яку :Iми визначили далі вниз по файлу. Оскільки :Iмає 2 різних пристрої введення, його представлення на іншій дошці має бути шириною 2 комірки. Оскільки у нас є 6 комірок II, ми розповідаємо, що на дошці є 3 екземпляри цієї функції.

FF(Або 256 або -1 , якщо ви будете) мармури сидітимуть у вхідних осередках :Iфункції чекає до тих пір поки є достатньо введення мармур STO запустити функцію (більш , що один). Ось де виходить @4портал. Копія зменшеного вводу командного рядка потрапляє туди на кожен цикл. Це запустить крайню ліву :Iдошку. Початково зі значеннями 256 (або -1) і будь-яким введенням командного рядка було -1. Лівий мармур буде покладений у }0пристрої :Iдошки, а правий - у }1. Якщо ви пригадуєте, що робила ця рада, ви зможете сказати, який результат це має. Він виведе нарощений варіант правого вводу на лівому виході (і він перетворить 9 на 0, а не 10) і виведе або 1, або -9 праворуч.

Нарощене значення буде повернуто порталом правого вхідного осередку, а праворуч потрапить у синхронізатор. Якщо синхронізатор вже тримає мармур, два мармури зіткнуться. Мармурований мармур, що стикається, додається разом по модулю 256. Значення синхронізаторів будуть виконувати наступні дії: вони починаються порожніми, потім переходять до 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, а потім до 1 раз (оскільки до 247 додано модуль 256).

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

Ви можете також пам’ятати, що :Oфункція перетворює значення у значення ascii цифри, що представляє значення -1. Вихід цих OOкомірок потім випаде з плати, яка друкує відповідні символи до STDOUT.

00 00 00 @5
&0 &0 &0
&3
\/ &2
   \/ &1 !!
      @5

То що відбувається, коли мармур введення командного рядка досягає 0 і заповнює &0синхронізатори? добре, кілька мармурів значення 0 падають вниз і спрацьовують три синхронізатори, які містять цифри (+ 1) короткого номера в нижній частині дошки. &3спрацював перший, так як він містить найбільш значну цифру, потім приходить &2потім &1. Потім цей мармур телепортується на інший @5пристрій, перш ніж врешті-решт потрапить на !!осередок, який припиняє дошку.


4
Виглядає так, ніби це також може бути дійсним код Perl
Doorknob

12

CJam, 14 11 байт

l40f-Ab)s1>

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

Як це працює

Цей підхід ґрунтується на відповіді edc65його явним дозволом ):

" Read a line L from STDIN. ";

l

" edc65's answer now forms an integer N by replacing each digit in L by an 8 and computes
  L - ~N = L + N + 1. Instead of adding L and N, we subtract 40 from each char code of L.
  Since the char code of the digit `D` is `D + 48`, this basically adds 8 to each digit.  ";

40f-

" Turn the resulting array into an integer by considering its elements a base 10 number.
  This is implemented as A ↦ A[-1] + 10 * A[-2] + 100 * A[-3] + ⋅⋅⋅, so it won't choke
  on digits greater than the base.                                                        ";

Ab

" Increment the integer on the stack to complete the calculation of L + N + 1.            ";

)

" Push the integers string representation and discard its first character.                ";

s1>

Приклад виконання

$ for i in 0 1 10 11 42 100 800 1060 10270 100501
> do echo $i: $(cjam <(echo 'l40f-Ab)s1>') <<< $i)
> done
0:
1: 0
10: 9
11: 00
42: 31
100: 89
800: 689
1060: 949
10270: 9159
100501: 89390

1
Це нецензурно
Клавдіу

3
+1 за те, щоб знайти спосіб скоротити його ще більше
edc65

6

Пітон 2 (38) (43)

f=lambda n:n*'_'and f(~-n/10)+`~-n%10`

Без підстановки символів, просто арифметична.

Безголівки:

def f(n):
    if n==0: return ''
    else: return f((n-1)//10) + str((n-1)%10)

У мене немає вагомих причин, чому працює рекурсія, я просто вписую цю схему в список значень. Якщо ви змінили кожен n-1To n, ви отримаєте чергове значне уявлення.

Для гольфу я використовую ~-nдля обчислення n-1з більш високим пріоритетом ніж /10або %10, економлячи на паренах. Це n*'_'просто створити порожній рядок, коли n=0і будь-який інший рядок інакше. Для '_'цієї мети може бути будь-який рядок.


4

Рубі, 70 68 66 64 57 байт

f=->n{i=-1;n-=10**i while n>=10**i+=1;i<1?'':"%0#{i}d"%n}

Визначає функцію, яку слід називати подібною f[42]. Ось приблизна розбивка алгоритму:

  • Лікуйте 0окремо.
  • Віднімання потужностей 10 до наступної потужності 10 вже не вписується в число.
  • Перетворіть число в рядок з нулями, ліворуч.

Кредити на ідею використання рядка формату йдуть до Фалько!


Крім того, використовуючи підхід edc65:

f=->n{"#{n-~n.to_s.tr('^.',?8).to_i}"[1..-1]}

Це 45 байт, і я лише включаю його, тому що я його не б'ю. ;)


Звичайно. Напевно, я все одно не спіймаю тебе своїм довгим кодом Python. ;)
Фалько

@Optimizer Я впевнений, що хтось застосував цей підхід в одній із мов для гри в гольф, він отримав би менше 20-ти (але, як було сказано, я не можу досягти 44 у Рубі з таким підходом ... зараз у 45)
Мартін Ендер

2
@Optimizer Я не згоден з цим. Для початківців J та APL - це не гольф-мови, і вони виграють так часто, як GolfScript і CJam. Але більше того, гольф - це не про зелену галочку, а про побиття подань "у вашій лізі". Якщо я напишу подання Ruby, яке перемагає всі, крім цих 4-х мов, я можу бути дуже радий з цього приводу, і мені не потрібно, щоб вони були заборонені, щоб насолоджуватися гольфом на більш багатослівних мовах. Насправді, розумний гольф на "нормальній" мові, як Edc, набагато більше шансів отримати багато оновлень, ніж наївна (але коротша) реалізація мовою гольфу.
Мартін Ендер

3

Haskell, 67 байт

n('9':x)='0':n x
n(c:x)=succ c:x
n""="0"
f x=reverse$iterate n""!!x

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

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

>f 9
"8"
>f 100
"89"

3

CJam, 16 байт

li_)9*,{`1>}%_&=

Спробуйте в Інтернеті. Потрібно принаймні O (n) часу та пам'яті, тому залиште 100501 автономному перекладачеві ...

Як це працює

Основна ідея цього підходу - обчислити принаймні N коротких десяткових знаків у їх природному порядку та відкинути всі, крім N-го. Не дуже ефективний, але короткий.

li                " Read an integer N from STDIN.                                   ";
  _)9*            " Push M := (N + 1) * 9.                                          ";
      ,           " Push A := [ 0 1 ... M - 1 ].                                    ";
       {   }%     " For each I ∊ A:                                                 ";
       {`1>}%     " Push its string representation and discard the first character. ";
             _&   " Remove duplicates from the resulting array.                     ";
               =  " Retrieve the Nth element.                                       ";

Приклад виконання

$ for i in 0 1 10 11 42 100 800 1060 10270 100501
> do echo $i: $(cjam <(echo 'li_)9*,{`1>}%_&=') <<< $i)
> done
0:
1: 0
10: 9
11: 00
42: 31
100: 89
800: 689
1060: 949
10270: 9159
100501: 89390

3

Bash + coreutils, 27 байт

Розумний відповідь порту @ edc65 з поліпшеннями @ Dennis :

cut -b2-<<<$[$1-~${1//?/8}]

Вихід:

$ for n in 0 1 10 11 42 100 110 111 800 1060 1110 1111 10270 100501; do echo "./shortlex.sh $n = \"$(./shortlex.sh $n)\""; done
./shortlex.sh 0 = ""
./shortlex.sh 1 = "0"
./shortlex.sh 10 = "9"
./shortlex.sh 11 = "00"
./shortlex.sh 42 = "31"
./shortlex.sh 100 = "89"
./shortlex.sh 110 = "99"
./shortlex.sh 111 = "000"
./shortlex.sh 800 = "689"
./shortlex.sh 1060 = "949"
./shortlex.sh 1110 = "999"
./shortlex.sh 1111 = "0000"
./shortlex.sh 10270 = "9159"
./shortlex.sh 100501 = "89390"
$ 

Попередня відповідь:

Bash + coreutils, 71 54 байт

Ось дещо інший спосіб зробити це:

jot -w%x $1$1|tr 0-9a a0-9|grep -P ^\\d+$|sed $1!d 2>-
  • jot виводить збільшення шестинадцяткових цілих чисел
  • tr перетворює це в (0,1, ..., 8,9, b, ... f, 0a, 00,01, ..., 99,9b, ..., ff, 0aa, ..., 000 , ...)
  • grep просто фільтруйте всі рядки, що містять цифри, щоб дати (0,1, ..., 8,9,00, ..., 99000 ....)
  • sed видаляє всі, крім n-го рядка
  • STDERR переспрямовується на викидний файл '-', так що ми просто отримуємо порожній рядок при передачі 0 ( sedрахує номери рядків, починаючи з 1, тому помилки, якщо 0 передано)
  • Оскільки ми фільтруємо числа за допомогою grep, нам потрібно генерувати більше базових цілих чисел із seq/ dcніж вхідне число. Повторення цифр n більш ніж достатньо.

Зауважте, що після того, як друкується короткий номер, я seqпродовжую генерувати числа до $1$1, що сповільнюється, особливо для більших вхідних чисел - O (n²), я думаю. Ми можемо прискорити роботу, seqприпинивши відразу після друку вартістю 7 байт:

jot -w%x $1$1|tr 0-9a a0-9|grep -P ^\\d+$|sed -n $1{p\;q} 2>-

У запитанні немає вимоги щодо швидкості, тому для основної відповіді я переходжу з коротшою версією.


@Optimizer nope: спробуйте s='jot -w%x $1$1|tr 0-9a a0-9|grep -P ^\\d+$|sed $1!d 2>-'; echo ${#s}. Я підозрюю, що ви можете використовувати python для вимірювання довжини рядка, яка розглядає "\\" як один символ.
Цифрова травма

2
Моя відповідь змінилася на сьогодні, але якщо я зробив щось розумне в першій редакції, це було зовсім випадково. Це була пряма відповідь edc65; 8-ті - всі його ... - Допоміжна змінна, $aздається, непотрібна; cut -b2-<<<$[$1-~${1//?/8}]повинен працювати просто чудово.
Денніс

1
@Dennis Правильно бачу. Дякую за пропозицію!
Цифрова травма

2

Пітон 2 - 84, 70 66

n=input()
i=0
while n>=10**i:n-=10**i;i+=1
print"%%0%dd"%i%n*(i>0)

Альтернативний підхід (однакова довжина):

n=input()
k=len(`9*(n+1)/10`)
print"%%0%dd"%k%(n-int('1'*k))*(n>0)

Використовувати рядок формату розумно! Я сподіваюся, що ви не заперечуєте, якщо і я цим користуюся. :)
Мартін Ендер

2

Python 3, 107 символів

Це не закінчилося перемогою, але я подумав, що це розумно:

def G():yield'';yield from(r+c for r in G()for c in'0123456789')
S=lambda n:list(zip(range(n+1),G()))[n][1]

Я визначаю генератор для всієї послідовності в 64 символах. На жаль, мені доводиться проходити деякі викривлення, щоб отримати n-й елемент генератора ... якби тільки я міг це зробити S=lambda n:G()[n].


2

Піт , 12

Ще один порт відповіді @ edc65, який є явним переможцем (IMO):

t`+hQv*l`Q\8

Тестовий пакет (завдяки @DigitalTrauama):

$ for n in 0 1 10 11 42 100 110 111 800 1060 1110 1111 10270 100501; do echo "shortlex.pyth $n = \"$(pyth programs/shortlex.pyth <<< $n)\""; done
shortlex.pyth 0 = ""
shortlex.pyth 1 = "0"
shortlex.pyth 10 = "9"
shortlex.pyth 11 = "00"
shortlex.pyth 42 = "31"
shortlex.pyth 100 = "89"
shortlex.pyth 110 = "99"
shortlex.pyth 111 = "000"
shortlex.pyth 800 = "689"
shortlex.pyth 1060 = "949"
shortlex.pyth 1110 = "999"
shortlex.pyth 1111 = "0000"
shortlex.pyth 10270 = "9159"
shortlex.pyth 100501 = "89390"

Пояснення:

Q = eval(input())             Implicit.
t`                            All but the first digit of
  +hQ                         Q+1 + 
   v                          eval(
    *l`Q                      len(repr(Q)) * 
     \8                       "8"

CJam vs Pyth; битва триває. : P
Денніс

Я спробував дати Pyth для цього виклику, але я не міг знайти спосіб перетворити список у ціле число (наприклад, [8, 8, 9] -> 889). Як ти це робиш?
Денніс

@Dennis Щоб потрапити зі списку до int, вам в основному потрібно пройти рядок. jkперетворить ваш список у рядок і vперетворить його на int. Так vjk[8 8 9]дамо число 889.
isaacg

Добре, дякую. На жаль, перетворення рядків робить деякі хитрощі неможливими. З базовим перетворенням CJam / GolfScript [2 -1] -> 19та [1 11] -> 21.
Денніс

1
@Dennis Так, як тільки я фактично додаю базову конверсію до Pyth, це спрацює. Але я ще цього не зробив.
isaacg


1

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

((g=<<[0..])!!)
g 0=[""]
g n=[c:s|c<-['0'..'9'],s<-g$n-1]

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

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



0

Excel, 37 байт

Використовуючи підхід @ edc65:

=REPLACE(REPT(8,LEN(A1))+A1+1,1,1,"")

0

Желе , 5 байт

ḃ⁵ịØD

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

Я дуже новачок у Jelly, тому, якщо ви можете покращити це, будь ласка, прокоментуйте!

Пояснення:

ḃ⁵ịØD   Main link.
ḃ       Convert to bijective base ...
 ⁵      10.
  ị     Each number (1 - 10) is converted to the character at its index in the string...
   ØD   “0123456789” (digits)

(Відповідно до коментаря res вище, проблема еквівалентна перетворенню числа в біективну базу 10)

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