Козак Вус і програмування
Усім відомо, що у Козака є його улюблений робот Атлас, з яким він багато грався у дитинстві. Сьогодні Вус зрозумів, що ще ніколи не намагався запрограмувати робота на якісь інші дії, і тому почав читати інструкцію. З'ясувалося, що у пам'яті Атласа зберігаються пронумерованих з одиниці регістрів, кожний із яких містить біти. Це означає, що кожен регістр складається з -ох нулів та одиниць:
Вус також зрозумів, що для програмування робота можна використовувати наступні команд, які виконують операції над регістрами. Для зручності будемо регістром називати регістр під номером , а також "— число, яке записане в -му регістрі
setValue(i, j)
"— замінити регістр на регістр . Тобто кожен біт першого регістра замінити на відповідний біт у другому регістрі. Іншими словами, виконати операцію присвоєння .setXor(i, j, k)
"— замінити регістр на побітовийxor
регістрів та . Тобто кожен біт регістра замінити наxor
відповідних бітів у регістрів та . Про операціюxor
буде зазначено нижче.setAnd(i, j, k)
"— замінити регістр на побітовийand
регістрів та . Тобто кожен біт регістра замінити наand
відповідних бітів у регістрів та . Про операціюand
буде зазначено нижче.setOr(i, j, k)
"— замінити регістр на побітовийor
регістрів та . Тобто кожен біт регістра замінити наor
відповідних бітів у регістрів та . Про операціюor
буде зазначено нижче.shiftLeft(i, x)
"—зсунути
всі біти регістру на позицій вліво. Про операціюзсуву
буде зазначено нижче.shiftRight(i, x)
"—зсунути
всі біти регістру на позицій вправо. Про операціюзсуву
буде зазначено нижче.setNot(i, j)
"— замінити регістр наінвертований
регістр . Тобто кожен біт регістра замінити на , якщо на відповідній позиції регістра записане , і замінити на , якщо на відповідній позиції регістра записане .
Результатом операції xor
двох бітів є , якщо біти однакові, та , якщо різні.
Результатом операції and
двох бітів є , якщо обидва біти є рівними , та , якщо хоча б один біт рівний .
Результатом операції or
двох бітів є , якщо обидва біти є рівними , та , якщо хоча б один біт рівний .
Результатом операції зсув
регістру на позицій уліво є регістр, у якому кожний біт рівний біту, що був записаний у початковому регістрі на позицій правіше, та рівний , якщо не існувало у початковому регістрі позиції на правіше.
Результатом операції зсув
регістру на позицій управо є регістр, у якому кожний біт рівний біту, що був записаний у початковому регістрі на позицій лівіше, та рівний , якщо не існувало у початковому регістрі позиції на лівіше.
Прочитавши інструкцію, Козак Вус одразу ж придумав досить цікавих задач. Ще трохи подумавши, Козак зрозумів, що для того, щоб запрограмувати робота на конкретну задачу, потрібно лише ввести роботу набір команд, який би вирішував цю задачу. Припустимо, що "— кількість команд, яку ви виконали в певній задачі.
А ось і самі задачі:
Підзадача 1:
(до балів) у регістрі записане число . Усі інші регістри повністю складаються з -ів. Нехай число дорівнює , якщо число парне, і дорівнює , якщо непарне. Задача полягає в тому, щоб після виконання роботом операцій у регістрі було записане число . Ви отримаєте балів.
Підзадача 2:
(до балів) у регістрі записане , а в регістрі записане . Усі інші регістри повністю складаються з -ів. Нехай . Задача полягає в тому, щоб після виконання роботом операцій у регістрі було записане число . Потрібно зазначити, що якщо двійковий запис числа потребує більше ніж розряди, то в регістрі мають бути записані лише перші розряди. Ви отримаєте балів.
Підзадача 3:
(до балів) у регістрі записане . Нехай число "— це кількість одиниць у двійковому записі числа . Тоді після виконання роботом операцій у регістрі має бути записане . Ви отримаєте балів.
Підзадача 4:
(до балів) у регістрах та записані два різні числа та відповідно. Нехай якщо , то , а якщо , то . Задача полягає в тому, щоб після виконання роботом операцій у регістрах та були записані числа та відповідно. Ви отримаєте балів.
Підзадача 5:
(до балів) у регістрі записане число . Нехай число "— це кількість одиниць у двійковому записі числа . Тоді після виконання роботом операцій у регістрі має бути записане число . Ви отримаєте балів.
Підзадача 6:
(до балів) нехай "— це масив, який містить невід'ємних цілих попарно різних чисел. Тоді для кожного від -ого до -и у -ому регістрі записане . Нехай "— це відсортований за зростанням масив . Тоді після виконання роботом операцій, для кожного від -ого до -и у -ому регістрі має бути записане . Потрібно зазначити, що нумерація у масивах та починається з одиниці. Ви отримаєте балів.
Якщо про початкове значення регістру нічого не сказано, тоді на початку він повністю складається з нулів. Усі числа від до .
Козак Вус якимось чином дізнався кількість команд, яка необхідна для вирішення кожної задачі, проте він ще не знає, які саме команди потрібно використати, і тому звернувся по допомогу до вас. Він просить вас знайти таку послідовність команд, яка розв'яже задачу для будь-яких можливих вхідних даних.
Зверніть увагу, що ви можете виконати не більше команд. Якщо ви виконаєте більше, то ви отримаєте балів та вердикт Неправильна відповідь
. Якщо ви виконаєте неправильний запит, то ви отримаєте балів та вердикт Помилка виконання
. Результатом вашого рішення в кожній підзадачі будуть ті регістри, у яких мають бути записані рішення. В усіх інших регістрах можуть бути будь-які числа.
Протокол взаємодії
Для кожної підзадачі вам потрібно окремо реалізувати одну функцію:
void solve()
ця функція не приймає ніяких параметрів та нічого не повертає.
Ви можете використовувати наступні функції:
void setValue(integer i, integer j)
ця функція надає регістру () значення регістра ().
void setXor(integer i, integer j, integer k)
ця функція надає регістру () значення операції
xor
регістрів () та ().
void setAnd(integer i, integer j, integer k)
ця функція надає регістру () значення операції
and
регістрів () та ().
void setOr(integer i, integer j, integer k)
ця функція надає регістру () значення операції
or
регістрів () та ().
void shiftLeft(integer i, integer x)
ця функція реалізовує
зсув
регістру () на () позицій уліво.
void shiftRight(integer i, integer x)
ця функція реалізовує
зсув
регістру () на () позицій управо.
void setNot(integer i, integer j)
ця функція надає регістру () значення
інвертованого
регістру ().
Приклади
Припустимо, що в регістрі записане число , а в регістрі число , тоді якщо виконаємо такі команди:
setValue(3, 1) setXor(4, 1, 2) setAnd(5, 1, 2) setOr(6, 2, 1) shiftLeft(2, 3) shiftRight(1, 2) setNot(7, 2)
то перші сім чисел масиву будуть виглядати так: , , , , , , .