Треки
/
Elm
Elm
/
Вправи
/
Секрети
Секрети

Секрети

Навчальна вправа

Вступ

Побітові операції

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

Elm надає кілька побітових операторів у своєму модулі Bitwise

Основні операції

Зміну окремих бітів числа називають маскуванням. Маскою називають число, у якому певні біти встановлено в особливий спосіб, щоб маніпулювати іншим числом за допомогою побітових операторів, як-от and, or і xor.

and

and поєднує два числа, залишаючи лише ті біти, які є 1 в обох. Це корисно для перевірки, чи встановлено окремий біт. Наприклад, щоб перевірити, чи встановлено 4-й біт числа в 1, застосуймо до нього and з маскою 01000 (8 у десятковій системі) і подивімося, чи результат не дорівнює нулю:

Bitwise.and 13 8 --> 8
--  13 = 01101
--   8 = 01000
-- and = 01000 = 8
or

or поєднує два числа, встановлюючи кожен біт у 1, якщо він є 1 в одному чи обох числах. Це корисно для встановлення конкретного біта в 1. Наприклад, щоб встановити 2-й біт у 10101, застосуймо до нього or з маскою 00010:

Bitwise.or 21 2 --> 23
-- 21 = 10101
--  2 = 00010
-- or = 10111 = 23
Виключне або (xor)

xor поєднує два числа, встановлюючи кожен біт у 1, якщо він є 1 в одному числі, але 0 в іншому. Це корисно для перемикання біта на протилежне значення:

Bitwise.xor 20 5 --> 17
--  20 = 10100
--   5 = 00101
-- xor = 10001 = 17
Доповнення

complement інвертує кожен біт числа (0 стає 1, 1 стає 0).

Зауважмо, що в результаті додатні числа стануть відʼємними, а відʼємні - додатними. Це тому, що відʼємні числа в двійковому записі представлено з 1 у найлівішій позиції.

Bitwise.complement 21 --> -22
--         21 = 00000000000000000000000000010101
-- complement = 11111111111111111111111111101010 = -22
Побітовий зсув

Наведені далі оператори зсувають біти ліворуч або праворуч на вказану кількість позицій, фактично множачи або ділячи на степені 2.

shiftLeftBy зсуває біти ліворуч, заповнюючи 0 з правого боку. Наприклад, щоб зсунути 21 ліворуч на 3 позиції:

Bitwise.shiftLeftBy 3 21 --> 168
--  21 = 10101
-- shiftLeftBy 3 = 10101000 = 168

Це те саме, що сказати 21 * 2^3 = 21 * 2 * 2 * 2 = 168

shiftRightBy: зсуває біти праворуч:

Bitwise.shiftRightBy 2 21 --> 5
--  21 = 10101
-- shiftRightBy 2 = 00101 = 5

Зсув праворуч на 2 позиції дорівнює цілочисельному діленню на 4.

Зауважмо, що ця функція дублює те значення, яке міститься в найлівішому біті. Тож відʼємні числа залишаться відʼємними:

Bitwise.shiftRightBy 3 -21 --> -3
--  -21 = 111...101011
-- shiftRightBy 3 = 111...11101 = -3

Якщо потрібно зсунути праворуч і заповнити нулями, використаймо shiftRightZfBy:

Bitwise.shiftRightZfBy 3 -21 --> 536870909
--  -21 = 111...101011
-- shiftRightZfBy 3 = 00111...11101 = 536870909

Вказівки

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

1. Зсуваємо біти назад

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

Реалізуйте функцію shiftBack, яка приймає кількість позицій для зсуву та значення й виконує зсув.

shiftBack 2 42 --> 10

2. Встановлюємо деякі біти

Далі є біти, які потрібно встановити в 1.

Реалізуйте функцію setBits, яка приймає маску та значення й повертає результат встановлення бітів у значенні в 1. Біт зі значення потрібно встановити в 1 там, де біт у масці також 1. Усі інші біти залишаються без змін.

setBits 66 212 --> 64

3. Перевертаємо окремі біти

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

Реалізуйте функцію flipBits, яка приймає маску та значення. Маска вказує, які біти у значенні потрібно перевернути. Якщо біт у масці дорівнює 1, відповідний біт у значенні перевертається. Усі інші біти залишаються без змін.

flipBits 23 157 --> 138

4. Очищаємо окремі біти

Є також певні біти, які завжди розшифровуються в 0.

Реалізуйте функцію clearBits, яка приймає маску та значення. Біти у value потрібно встановити в 0 там, де біт у масці дорівнює 1. Усі інші біти залишаються без змін.

clearBits 2 15 --> 13

5. Розшифровуємо повідомлення

Тепер, коли в нас є всі потрібні функції, ми можемо декодувати повідомлення друга. Реалізуйте функцію decrypt, яка виконує такі операції:

  1. Встановити біти з року, коли народився наш друг (1996)
  2. Перевернути результат із роком, коли ми вперше зустрілися (2009)
  3. Зсунути біти назад на кількість спільних занять (5)
  4. Очистити перший і пʼятий біти.
decrypt 380182 --> 11840

Будь ласка, реалізуйте decrypt за допомогою всіх функцій, які ми реалізували в попередніх завданнях.

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Elm Exercism

Час розпочати Секрети?

Зареєструйтеся на Exercism, щоб вивчати й опановувати Elm, а також 28 концепцій110 вправ та справжнє наставництво від людей, і все це безкоштовно.