diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md
index 22dac9307..8d2aa0cc2 100644
--- a/1-js/06-advanced-functions/01-recursion/article.md
+++ b/1-js/06-advanced-functions/01-recursion/article.md
@@ -8,11 +8,11 @@
Рекурсія -- це паттерн, який є корисним у ситуаціях, коли завдання може бути розділено на кілька завдань того ж роду, але простіших. Або коли завдання може бути спрощене до простої дії плюс простіший варіант того ж завдання. Або, як ми побачимо найближчим часом, щоб працювати з певними структурами даних.
-Коли функція вирішує завдання, у процесі вона може викликати багато інших функцій. Частковий випадок цього є те, коли функція викликає *себе*. Це називається *рекурсія*.
+Коли функція вирішує завдання, у процесі вона може викликати багато інших функцій. Є навіть випадки, коли функція викликає *саму себе*. Коли функція викликає саму себе - це називається *рекурсія*.
## Два способи мислення
-Щоб почати з чогось простого -- давайте напишемо функцію `pow(x, n)`, що приводить `x` в натуральну степінь `n`. Іншими словами, множить `x` сам на себе `n` разів.
+Щоб почати з чогось простого -- давайте напишемо функцію `pow(x, n)`, що підносить `x` до натурального ступеня `n`. Іншими словами, множить `x` саму на себе `n` разів.
```js
pow(2, 2) = 4
@@ -53,9 +53,9 @@ pow(2, 4) = 16
alert( pow(2, 3) ); // 8
```
-Зверніть увагу, як рекурсивний варіант принципово відрізняється.
+Зверніть увагу, що рекурсивний варіант відрізняється принципово.
-Коли `pow(x, n)` викликається, виконання розділяється на дві гілки:
+Коли функція `pow(x, n)` викликається, виконання розділяється на дві гілки:
```js
if n==1 = x
@@ -65,25 +65,25 @@ pow(x, n) =
else = x * pow(x, n - 1)
```
-1. Якщо `n == 1`, то все тривіально. Це називається *база* рекурсії, оскільки вона негайно виробляє очевидний результат: `pow(x, 1)` дорівнює `x`.
-2. Інакше ми можемо представляти `pow(x, n)` як `x * pow(x, n)`. У математиці можна написати xn = x * xn-1. Це називається *рекурсивний крок*: ми перетворюємо завдання на простішу дію (множення за допомогою `x`) та на простий виклик того ж завдання (`pow` з меншим `n`). Наступні кроки спрощують його далі і далі до `n`, що дорівнює `1`.
+1. Якщо `n == 1`, то все просто. Ця гілка називається *базою* рекурсії, оскільки вона негайно дає очевидний результат: `pow(x, 1)` дорівнює `x`.
+2. Інакше ми можемо представити `pow(x, n)` як `x * pow(x, n)`. Що у математиці можна написати xn = x * xn-1. Ця гілка - *крок рекурсії*: ми зводимо задачу до більш простої дії (множеня на `x`) і до більш простої аналогічної задачі (`pow` з меншим `n`). Наступні кроки спрощують задачу все більше і більше, аж доки `n` почне дорівнювати `1`.
Ми також можемо сказати, що `pow` *рекурсивно викликає себе* до`n == 1`.

-Наприклад, для розрахунку `pow(2, 4)` рекурсивний варіант виконує ці кроки:
+Наприклад, для розрахунку `pow(2, 4)` рекурсивний варіант виконує такі кроки:
1. `pow(2, 4) = 2 * pow(2, 3)`
2. `pow(2, 3) = 2 * pow(2, 2)`
3. `pow(2, 2) = 2 * pow(2, 1)`
4. `pow(2, 1) = 2`
-Отже, рекурсія робить виклик функції простішим, а потім -- ще більш простішим, і так далі, доки результат стане очевидним.
+Отже, рекурсію використовують, коли обчислення функції можна звести до її ж більш простого виклику, а той - до ще простішого і так далі, аж доки значення не стане максимально простим (очевидним).
-````smart header="Рекурсія зазвичай коротша"
-Рекурсивне рішення, як правило, коротше, ніж ітераційне.
+````smart header="Рекурсійне рішення зазвичай коротше"
+Рекурсивне рішення, як правило, коротше за ітераційне.
Ми можемо переписати те ж саме, використовуючи умовний оператор `?` замість `if`, щоб зробити `pow(x, n)` більш лаконічним і зберегти легкість читання:
@@ -96,7 +96,7 @@ function pow(x, n) {
Максимальна кількість вкладених викликів (включаючи перший) називається *глибина рекурсії*. У нашому випадку вона буде точно дорівнювати `n`.
-Максимальна глибина рекурсії обмежена рушієм JavaScript. Ми можемо покластися, що вона може дорівнювати 10000, деякі рушії дозволяють отримати більшу глибину, але 100000, ймовірно, не підтримується більшістю з них. Є автоматичні оптимізації, які допомагають пом’якшити це ("оптимізація хвостових викликів"), але вони ще не підтримуються скрізь і працюють лише у простих випадках.
+Максимальна глибина рекурсії обмежена рушієм JavaScript. Кількість вкладених викликів, на яку точно можна розраховувати - 10 000. Деякі рушії дозволять працювати з ще більшою глибиною. Але навіть більшість з них можуть осилити не більше 100 000 викликів. Є багато автоматичних оптимізацій, які допомагають уникнути переповнення стеку викликів ("оптимізація хвостових викликів", англ. tail calls optimizations), але вони підтримуються далеко не всюди і працюють тільки в простих випадках.
Це обмежує застосування рекурсії, але вона все ще залишається дуже широко поширеною. Є багато завдань, де рекурсивний спосіб мислення дає простіший код, який легше підтримувати.
@@ -114,7 +114,7 @@ function pow(x, n) {
- Поточна функція зупиняється.
- Контекст виконання, пов’язаний з нею, запам’ятовується в спеціальній структурі даних, що називається *стек контекстів виконання*.
-- Вкладений виклик виконується.
+- Виконуються вкладені виклики і для кожного з них створюється свій контекст виконання.
- Після закінчення, старий контекст виконання витягується з стека, і зовнішня функція відновлюється з того місця, де вона зупинилася.
Давайте подивимося, що відбувається під час виклику `pow(2, 3)`.
@@ -132,7 +132,7 @@ function pow(x, n) {
-Ось тоді, функція починає виконуватися. Умова `n == 1` -- хибна, тому потік продовжується у другій гілці `if`:
+Це стан на початку виконання. Так як умова `n == 1` -- хибна, то виконується друга гілка `if`:
```js run
function pow(x, n) {
@@ -158,17 +158,17 @@ alert( pow(2, 3) );
-Для розрахунку `x * pow(x, n - 1)`, ми повинні зробити підвиклик `pow` з новими аргументами `pow(2, 2)`.
+Для розрахунку `x * pow(x, n - 1)` треба зробити підвиклик `pow` з новими аргументами `pow(2, 2)`.
### pow(2, 2)
-Щоб зробити вкладений виклик, JavaScript пам’ятає контекст поточного виконання в *стеці контексту виконання*.
+Щоб зробити вкладений виклик, JavaScript запам'ятовує контекст поточного виконання в *стеці контексту виконання*.
Тут ми викликаємо ту ж функцію `pow`, але це абсолютно не має значення. Цей процес однаковий для всіх функцій:
1. Поточний контекст "запам’ятовується" на вершині стека.
-2. Новий контекст створюється для підвиклику.
-3. Коли закінчиться підвиклик -- попередній контекст дістається зі стека, і його виконання продовжується.
+2. Створюється новий контекст для вкладеного виклику.
+3. Коли закінчиться виконання вкладеного виклику -- попередній контекст дістається зі стека, і його виконання продовжується.
Ось контекстний стек, коли ми увійшли до підвиклику `pow(2, 2)`:
@@ -183,9 +183,9 @@ alert( pow(2, 3) );
-Новий поточний контекст виконання знаходиться на вершині (виділений жирним шрифтом), а попередні контексти знаходяться в пам’яті нижче.
+Новий поточний контекст виконання знаходиться на малюнку вище (підпис виділений жирним шрифтом), а попередні контексти, які все ще бережуть в пам'яті, зображені на тому ж малюнку нижче.
-Коли ми закінчимо підвиклик, легко відновити попередній контекст, оскільки він зберігає як змінні, так і точне місце коду, де він зупинився.
+Коли виконання підвиклику закінчиться, можна буде легко повернутись назад. Бо контекст зберігає як значення змінних, так і точне місце в коді, де він зупинився.
```smart
Тут, на малюнку, ми використовуємо "на рядку", так як у нашому прикладі є лише один підвиклик в рядку, але, як правило, один рядок коду може містити декілька підвикликів, як `pow(…) + pow(…) + somethingElse(…)`.
@@ -197,7 +197,7 @@ alert( pow(2, 3) );
Процес повторюється: новий підвиклик здійснюється на рядку `5`, тепер з аргументами `x=2`, `n=1`.
-Створено новий контекст виконання, попередній витиснуто на вершину стека:
+Створено новий контекст виконання, попередній витиснуто вище по стеку:
@@ -234,7 +234,7 @@ function pow(x, n) {
Немає більше вкладених викликів, тому функція закінчується, повертаючи `2`.
-Оскільки функція завершується, то контекст виконання більше не потрібний, тому він видаляється з пам’яті. Попередній контекст відновлюється з вершини стека:
+Оскільки цей виклик функції завершується, то контекст виконання для цього виклику більше не потрібний, тому він видаляється з пам’яті. Попередній контекст відновлюється з вершини стека:
@@ -263,7 +263,7 @@ function pow(x, n) {
Глибина рекурсії в цьому випадку була: **3**.
-Як ми бачимо з наведених вище ілюстрацій, глибина рекурсії дорівнює максимальній кількості контексту у стеці.
+Як ми бачимо з наведених вище ілюстрацій, глибина рекурсії дорівнює максимальній кількості контекстів у стеку.
Зверніть увагу на вимоги до пам’яті. Зберігання контекстів потребує пам’яті. У нашому випадку, підведення до степеня `n` фактично вимагає пам’яті для `n` контекстів, для всіх значень, що нижче `n`.
@@ -281,7 +281,7 @@ function pow(x, n) {
}
```
-Ітеративний `pow` використовує єдиний контекст, змінюючи `i` and `result` у процесі. Його вимоги до пам’яті невеликі, фіксовані та не залежать від `n`.
+Ітеративний `pow` використовує єдиний контекст, змінюючи `i` й `result` у процесі. Його вимоги до пам’яті невеликі, фіксовані та не залежать від `n`.
**Будь-яка рекурсія може бути переписана за допомогою циклу. Варіант з використанням циклу зазвичай може бути більш ефективним.**
@@ -315,7 +315,7 @@ let company = {
}],
internals: [{
- name: 'Евген',
+ name: 'Євген',
salary: 1300
}]
}
@@ -328,18 +328,18 @@ let company = {
- Або відділ може бути розділеним на підрозділи, наприклад, `development` має дві гілки: `sites` та `internals`. Кожна з них має свій персонал.
- Можливо також, що коли відділ зростає, він розділяється на субвідділи (або команди).
- Наприклад, відділ `sites` у майбутньому може бути розділений на команди для `siteA` і `siteB`. І вони, потенційно, можуть бути розділені в подальшому. Це не зображено на малюнку, просто слід мати це на увазі.
+ Наприклад, відділ `sites` у майбутньому може бути розділений на команди для `siteA` і `siteB`. І І вони, потенційно, можуть бути розділені в подальшому. Це не зображено на малюнку, просто слід мати це на увазі.
-Тепер припустимо, що ми хочемо, щоб функція отримала суму всіх зарплат. Як ми можемо це зробити?
+Тепер припустімо, що ми хочемо, щоб функція отримала суму всіх зарплат. Як ми можемо це зробити?
-Ітеративний підхід нелегкий, тому що структура не проста. Перша ідея може полягати в тому, щоб зробити `for` цикл через `company` з вкладеним підциклами через 1-ий рівень відділів. Але тоді нам потрібно більше вкладених циклів, щоб ітеруватися через персонал у 2-му рівні, такому як `sites`... А потім ще один підцикл всередині них для 3-го рівня, який міг би з’явитися в майбутньому? Якщо ми поставимо 3-4 вкладені цикли у коді, щоб пройти один об’єкт, це стає досить потворним.
+Ітеративний підхід нелегкий, бо структура не проста. Перша ідея може полягати в тому, щоб зробити `for` цикл через `company` з вкладеним підциклами через 1-ий рівень відділів. Але тоді нам потрібно більше вкладених циклів, щоб ітеруватися через персонал у 2-му рівні, такому як `sites`... А потім ще один підцикл всередині них для 3-го рівня, який міг би з’явитися в майбутньому? Якщо ми поставимо 3-4 вкладені цикли у коді, щоб пройти один об’єкт, це стає досить потворним.
Давайте спробуємо рекурсію.
Як ми бачимо, коли наша функція отримує відділ для підрахунку суми зарплат, є два можливі випадки:
1. Або це "простий" відділ з *масивом* людей -- тоді ми можемо підсумувати зарплату в простому циклі.
-2. Або це *об’єкт* з `n` підвідділами -- тоді ми можемо зробити `n` рекурсивних викликів, щоб отримати суму для кожного з підвідділів та поєднати результати.
+2. Або це *об’єкт* з `n` підвідділів -- тоді ми можемо зробити `n` рекурсивних викликів, щоб отримати суму для кожного з підвідділів та сумувати результати.
1-й випадок є базою рекурсії, тривіальним випадком, коли ми отримуємо масив.
@@ -375,7 +375,7 @@ function sumSalaries(department) {
alert(sumSalaries(company)); // 7700
```
-Код короткий і його легко зрозуміти (сподіваюся?). Це сила рекурсії. Він також працює для будь-якого рівня вкладеного підвідділу.
+Код короткий і його легко зрозуміти (сподіваюся). Це сила рекурсії. Він також працює для будь-якого рівня вкладеного підвідділу.
Ось діаграма викликів:
@@ -383,7 +383,7 @@ alert(sumSalaries(company)); // 7700
Ми можемо легко побачити принцип: для об’єкта `{...}` зроблені підвиклики, а масиви` `[...]` -- "листя" рекурсійного дерева, вони дають негайний результат.
-Зауважте, що код використовує розумні функції, які ми розглянули раніше:
+Зауважте, що код використовує пруткі можливості, які ми вже розглядали раніше:
- Метод `arr.reduce` пояснено в розділі , щоб отримати суму масиву.
- Цикл `for(val of Object.values(obj))` для ітерування значень об’єкта: `Object.values` повертає їх масив.
@@ -404,7 +404,7 @@ alert(sumSalaries(company)); // 7700
У HTML-документі *HTML-тег* може містити список:
- частини тексту.
- HTML-коментарі.
-- Інших *HTML-тегів* (що, у свою чергу, можуть містити частини тексту/коментарі або інші теги тощо).
+- Інші *HTML-теги* (що, у свою чергу, можуть містити частини тексту/коментарі або інші теги тощо).
Це ще одне рекурсивне визначення.
@@ -414,7 +414,7 @@ alert(sumSalaries(company)); // 7700
Уявіть, що ми хочемо зберегти впорядкований список об’єктів.
-Очевидним вибором буде масивом:
+Очевидним вибором буде масив:
```js
let arr = [obj1, obj2, obj3];
@@ -424,7 +424,7 @@ let arr = [obj1, obj2, obj3];
Єдині структурні модифікації, які не потребують масової перенумерації об’єктів, є ті, які працюють з кінцем масиву: `arr.push/pop`. Таким чином, масив може бути досить повільним для великих черг, коли ми повинні працювати з його початком.
-Крім того, якщо нам дійсно потрібна швидка вставка/видалення, ми можемо вибрати іншу структуру даних, яка називається [зв’язаний список](https://uk.wikipedia.org/wiki/Зв'язаний_список).
+Крім того, якщо нам дійсно потрібні швидкі вставка/видалення, ми можемо вибрати іншу структуру даних, яка називається [зв’язаний список](https://uk.wikipedia.org/wiki/Зв'язаний_список), англ. linked list.
*Елемент зв’язаного списку* рекурсивно визначається як об’єкт з:
- `value`.
@@ -473,7 +473,7 @@ list.next.next = null;

-To join:
+Для об'єднання:
```js
list.next.next = secondList;
@@ -497,7 +497,7 @@ list = { value: "new item", next: list };

-Щоб видалити значення з середини, змінити `next` попереднього:
+Щоб видалити значення з середини, міняємо `next` попереднього:
```js
list.next = list.next.next;
@@ -505,11 +505,11 @@ list.next = list.next.next;

-Ми зробили `list.next` стрибає через `1` на значення `2`. Значення `1` зараз виключається з ланцюга. Якщо воно не зберігається ніде, то воно буде автоматично видалено з пам’яті.
+Ми зробили так, що тепер `list.next` стрибає через `1` на значення `2`. Значення `1` зараз виключається з ланцюга. Якщо воно не зберігається ніде, то воно буде автоматично видалено з пам’яті.
На відміну від масивів, немає массових перенумерацій, ми можемо легко переставляти елементи.
-Звичайно, списки не завжди краще, ніж масиви. Інакше кожен буде використовувати лише списки.
+Звичайно, списки не завжди краще, ніж масиви. Інакше кожен використовував би лише списки.
Основний недолік полягає в тому, що ми не можемо легко отримати доступ до елемента за його номером. У масиві це легко: `arr[n]` є прямим посиланням. А в списку ми повинні почати з першого елемента і піти `next` `N` разів, щоб отримати n-ий елемент.
@@ -517,13 +517,13 @@ list.next = list.next.next;
Списки можуть бути покращені:
- Ми можемо додати властивість `prev` на доповнення до `next`, для посилання на попередній елемент, щоб легко переміщатися.
-- Ми також можемо додати змінну названу `tail`, що посилається на останній елемент списку (і оновлювати його при додаванні/видалення елементів з кінця).
+- Ми також можемо додати змінну названу `tail`, що посилається на останній елемент списку (і оновлювати його при додаванні/видаленні елементів з кінця).
- ...Структура даних може відрізнятися залежно від наших потреб.
## Підсумки
Терміни:
-- *Рекурсія* це термін програмування, який означає, що функція викликає саму себе. Рекурсивні функції можуть бути використані для вирішення завдань у елегантний спосіб.
+- *Рекурсія* - це термін програмування, який означає, що функція викликає саму себе. Рекурсивні функції можуть бути використані для вирішення завдань у елегантний спосіб.
Коли функція викликає себе, це називається *рекурсійний крок*. *База* рекурсії є функціональними аргументами, які роблять завдання таким простим, що функція не робить додаткових викликів.
diff --git a/1-js/06-advanced-functions/01-recursion/recursion-pow.svg b/1-js/06-advanced-functions/01-recursion/recursion-pow.svg
index 2b970a04a..f63bed101 100644
--- a/1-js/06-advanced-functions/01-recursion/recursion-pow.svg
+++ b/1-js/06-advanced-functions/01-recursion/recursion-pow.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file