Домашнє завдання #10: ASCII-майстерня і таємні послання
Цикли зазвичай тренують на таблиці множення. Нудно. Ми зробимо інакше: спершу цикли малюватимуть — прямо в консолі браузера. А потім ти напишеш шифр, яким Юлій Цезар кодував військові накази дві тисячі років тому, — і зламаєш його методом повного перебору, як справжній криптоаналітик.
Частина 1: ASCII-майстерня
Три функції, кожна малює фігуру в консолі (кожен рядок — окремий console.log). Символи: █ (заповнено) і ░ (порожньо).
pyramid(n) — піраміда з n рівнів
pyramid(4);
// █
// ███
// █████
// ███████
Рівень i містить 2*i - 1 блоків, а перед ними — пробіли, щоб піраміда була по центру.
christmasTree(n) — ялинка: крона з n рівнів + стовбур
christmasTree(3);
// █
// ███
// █████
// █
Стовбур — один блок по центру. Не дублюй код крони — у тебе вже є pyramid.
chessboard(size) — шахівниця size × size
chessboard(4);
// █░█░
// ░█░█
// █░█░
// ░█░█
Лівий верхній кут — завжди █. Тут знадобиться цикл у циклі: зовнішній — по рядках, внутрішній — по клітинках. Клітинка █ чи ░ — залежить від суми номера рядка і номера стовпця (парна чи непарна).
Частина 2: Шифр Цезаря
Ідея шифру: кожна літера зсувається по абетці на shift позицій. Зсув 3: a → d, b → e, а з кінця абетки — по колу: x → a, y → b, z → c.
encrypt(text, shift) та decrypt(text, shift)
Працюють з латиницею. Правила:
- Великі літери залишаються великими, малі — малими
- Все, що не літера (пробіли, коми, цифри), — не змінюється
- Кінець абетки загортається на початок (
z+ 1 →a) decryptповертає текст у вихідний вигляд:decrypt(encrypt(text, s), s) === text
Тест-кейси:
| Виклик | Результат |
|---|---|
encrypt("Hello, World!", 3) | "Khoor, Zruog!" |
encrypt("xyz", 3) | "abc" |
encrypt("Java Script 101", 13) | "Wnin Fpevcg 101" |
decrypt("Khoor, Zruog!", 3) | "Hello, World!" |
decrypt("Wnin Fpevcg 101", 13) | "Java Script 101" |
bruteForce(encrypted) — злам перебором
Ти перехопив шифровку, але не знаєш зсув. Не біда: зсувів усього 25 — перебери всі (ще один цикл у циклі: зовнішній — по зсувах, всередині — розшифровка). Виведи кожен варіант у консоль у форматі Зсув N: текст:
bruteForce("Fdhvdu");
// Зсув 1: Ecguct
// Зсув 2: Dbftbs
// Зсув 3: Caesar ← око одразу чіпляється за осмислене слово
// ...
// Зсув 25: Geiwev
Всередині bruteForce використай готовий decrypt — не дублюй логіку.
Бонус (+15): Українська абетка
Розшир encrypt/decrypt, щоб вони шифрували й українські літери (латиниця при цьому має продовжувати працювати). В українській абетці 33 літери: абвгґдеєжзиіїйклмнопрстуфхцчшщьюя — тож я із зсувом 1 загортається в а.
| Виклик | Результат |
|---|---|
encrypt("Привіт", 1) | "Рсігїу" |
encrypt("яблуко", 2) | "бгнхмр" |
decrypt("Рсігїу", 1) | "Привіт" |
Підказка: для української не вийде рахувати через коди символів так само просто, як для латиниці, — простіше тримати абетку рядком і працювати з indexOf.
Підказки
Рівень 1: напрямок думки
- Кожна фігура — це цикл, який будує рядок-змінну символ за символом, а в кінці ітерації віддає її в
console.log - Рядок із повторених символів: пробіли + блоки — порахуй, скільки кого треба на рівні
i - Для шифру: літера → її номер в абетці → номер + зсув (по колу) → нова літера
Рівень 2: які інструменти використати
"█".repeat(5)— рядок із 5 блоків;" ".repeat(n - i)— відступ- Залишок від ділення
%— і для «парна/непарна клітинка» у шахівниці, і для загортання абетки по колу:(index + shift) % 26 - Код літери:
text.charCodeAt(i), назад у літеру:String.fromCharCode(code). Коди:a-z— 97–122,A-Z— 65–90 - Перевірка «чи це літера»: код у діапазоні 97–122 (мала) або 65–90 (велика)
decryptне обов'язково писати з нуля: розшифровка зсувомs— це шифрування зсувом26 - s
Рівень 3: псевдокод encrypt
функція encrypt(text, shift):
result = порожній рядок
для кожного символа ch у text:
code = код символа ch
якщо code у діапазоні малих літер:
result += літера з кодом 97 + (code - 97 + shift) % 26
інакше якщо code у діапазоні великих літер:
result += літера з кодом 65 + (code - 65 + shift) % 26
інакше:
result += ch // пробіли, цифри, розділові знаки — як є
повернути result
Як здати
- Робота — в публічному GitHub-репозиторії курсу
my-web-course, у папціhw-10/ - У папці:
script.jsз усіма функціями і демо-викликами (фігури + всі тест-кейси шифру +bruteForce("Fdhvdu")) таindex.html-обгортка:
<!DOCTYPE html>
<html lang="uk">
<head><meta charset="UTF-8"><title>HW-10</title></head>
<body>
<script src="script.js"></script>
</body>
</html>
- Відкрий
index.html→ консоль (F12): там мають красуватися піраміда, ялинка, шахівниця і зламана шифровка - У папці —
README.md: 2-3 речення що зроблено + як запустити - Мінімум 3 коміти з осмисленими повідомленнями (не «fix» та «update»)
- Надішли посилання на репозиторій у форму на цій сторінці
Критерії оцінки
| Критерій | Тип | Бали |
|---|---|---|
pyramid(n) — центрована піраміда, збігається з прикладом | [код] | 15 |
christmasTree(n) — крона + стовбур, повторно використовує pyramid | [код] | 15 |
chessboard(size) — вкладені цикли, правильне чергування █/░ | [код] | 15 |
encrypt/decrypt — регістр зберігається, не-літери не змінюються, абетка загортається; усі тест-кейси проходять | [код] | 25 |
bruteForce — 25 варіантів у форматі Зсув N: текст, використовує decrypt | [код] | 15 |
Демо-виклики всіх функцій у script.js — консоль показує результати | [код] | 10 |
| Контракт здачі: 3+ осмислені коміти, README | [код] | 5 |
| Бонус: підтримка української абетки (33 літери, латиниця не зламалась) | [код] | +15 |
Що далі
Збережи encrypt/decrypt — коли в Block 5 дійдемо до форм та подій, ці функції легко перетворяться на сторінку-шифрувальник: поле вводу, кнопка і таємні послання для друзів.