исчезал.
5 | */
6 |
7 | const buttonNode = document.getElementById('hider')
8 | const textNode = document.getElementById('text')
9 |
10 | buttonNode.addEventListener('click', () => textNode.style.display = 'none')
11 |
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/2.1. Introduction-browser-events/src/2-hide-self.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Спрятать себя (важность: 5)
3 | *
4 | * Создайте кнопку, которая будет скрывать себя по нажатию.
5 | */
6 |
7 | document.getElementById('button').addEventListener('click', function() {
8 | this.style.display = 'none'
9 | })
10 |
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/2.1. Introduction-browser-events/src/3-which-handler-will-emit.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Какой обработчик запустится? (важность: 5)
3 | *
4 | * В переменной button находится кнопка. Изначально на ней нет обработчиков.
5 | * Который из обработчиков запустится? Что будет выведено при клике после выполнения кода?
6 | */
7 |
8 | button.addEventListener("click", () => alert("1"));
9 |
10 | button.removeEventListener("click", () => alert("1"));
11 |
12 | button.onclick = () => alert(2);
13 |
14 | // Решение:
15 | // 1. Сначала выведется alert("1"), затем alert(2)
16 | // alert("1") - не удалится, так как там стрелочная функция при удалении. А надо ссылку на функцию
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/2.1. Introduction-browser-events/src/5-create-expandable-menu.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Создать раскрывающееся меню (важность: 5)
3 | *
4 | * Создать меню, которое по нажатию открывается либо закрывается:
5 | */
6 |
7 |
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/2.3. Event Delegation/README.md:
--------------------------------------------------------------------------------
1 | # Делегирование событий
2 |
3 | Вместо того, чтобы назначать обработчик каждому - можно ставить один обработчик на их общего предка.
4 | Далее, в зависимости от `event.target`, определяем что нужно выполнить.
5 |
6 | ### Плюсы:
7 | - Упрощает процесс инициализации и экономит память: не нужно вешать много обработчиков.
8 | - Меньше кода: при добавлении и удалении элементов не нужно ставить или снимать обработчики.
9 | - Удобство изменений DOM: можно массово добавлять или удалять элементы путём изменения innerHTML и ему подобных.
10 |
11 | ### Минусы:
12 | - Событие должно всплывать
13 | - делегирование создаёт дополнительную нагрузку на браузер (но она незначительна)
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/2.3. Event Delegation/src/1-hide-with-event-delegation.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Спрячьте сообщения с помощью делегирования
3 | *
4 | * Дан список сообщений с кнопками для удаления [x]. Заставьте кнопки работать.
5 | * @type {HTMLElement}
6 | */
7 |
8 | const container = document.getElementById('container')
9 |
10 | container.addEventListener('click', (event) => {
11 | const pane = event.target.closest('.pane')
12 | const isRemoveButtonPressed = Boolean(event.target.closest('button.remove-button'))
13 |
14 | if (isRemoveButtonPressed) {
15 | pane.hidden = true
16 | }
17 | })
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/2.3. Event Delegation/src/2-accordion-tree.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Раскрывающееся дерево (важность: 5)
3 | *
4 | * Создайте дерево, которое по клику на заголовок скрывает-показывает потомков:
5 | *
6 | * Требования:
7 | *
8 | * - Использовать только один обработчик событий (применить делегирование)
9 | * - Клик вне текста заголовка (на пустом месте) ничего делать не должен.
10 | */
11 |
12 | const container = document.getElementById('tree')
13 |
14 | container.addEventListener('click', (event) => {
15 | const isClickedSpan = event.target.tagName === 'SPAN'
16 |
17 | if (!isClickedSpan) {
18 | return
19 | }
20 |
21 | const listItem = event.target.closest('li')
22 | const ul = listItem.querySelector('ul')
23 |
24 | if (!ul) {
25 | return
26 | }
27 |
28 | ul.hidden = !ul.hidden
29 | })
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/2.4. Default Browser Action/src/1-why-return-false-not-work.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Почему не работает return false? (важность: 3)
3 | *
4 | * Почему в коде ниже return false не работает?
5 | */
6 |
7 | /**
8 | *
14 | *
15 | *
браузер откроет w3.org
16 | */
17 |
18 | // Решение: надо возвращать значение из handler()
19 | //
браузер откроет w3.org
20 |
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/3.3. Mouse drag and drop/README.md:
--------------------------------------------------------------------------------
1 | # Drag'n'Drop с событиями мыши
2 |
3 | Базовый алгоритм Drag’n’Drop выглядит так:
4 |
5 | - При `mousedown` – готовим элемент к перемещению, если необходимо (например, создаём его копию).
6 | - Затем при `mousemove` передвигаем элемент на новые координаты путём смены `left`/`top` и `position:absolute`.
7 | - При `mouseup` – остановить перенос элемента и произвести все действия, связанные с окончанием Drag’n’Drop.
8 |
9 | В начале перетаскивания: запоминаем начальное смещение указателя относительно элемента:
10 | `shiftX`/`shiftY` – и сохраняем его при перетаскивании.
11 |
12 | Существует метод `document.elementFromPoint(clientX, clientY)`.
13 | Он возвращает наиболее глубоко вложенный элемент по заданным координатам окна
14 | (или `null`, если указанные координаты находятся за пределами окна).
15 |
16 |
17 |
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/3.5. Pointer-events/README.md:
--------------------------------------------------------------------------------
1 | # События указателя
2 |
3 | События указателя (Pointer events) – это современный способ обработки ввода с помощью различных указывающих устройств,
4 | таких как мышь, перо/стилус, сенсорный экран и так далее.
5 |
6 | Мы можем заменить `mouse` на `pointer` в названиях событий и код продолжит работать для мыши,
7 | при этом получив лучшую поддержку других типов устройств.
8 |
9 | Дополнительные возможности событий указателя:
10 |
11 | - Поддержка мультитач с помощью `pointerId` и `isPrimary`.
12 | - Особые свойства для определённых устройств, такие как `pressure`, `width`/`height` и другие.
13 | - Захват указателя: мы можем перенаправить все события указателя на определённый элемент до наступления события `pointerup`/`pointercancel`.
14 |
15 |
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/3.6. On scroll/README.md:
--------------------------------------------------------------------------------
1 | # Прокрутка
2 |
3 | Событие прокрутки `scroll` позволяет реагировать на прокрутку страницы или элемента.
4 |
5 | Нельзя предотвратить прокрутку, используя `event.preventDefault()` в обработчике `onscroll`,
6 | потому что он срабатывает после того, как прокрутка уже произошла.
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/4.1. Form elements/src/1-add-option-to-select.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Добавьте пункт к выпадающему списку (важность: 5)
3 | *
4 | * Используя JavaScript:
5 | *
6 | * Выведите значение и текст выбранного пункта.
7 | * Добавьте пункт:
.
8 | * Сделайте его выбранным.
9 | */
10 |
11 | const select = document.getElementById('genres')
12 | const selectedOption = select.options[select.selectedIndex]
13 |
14 | alert(`Сейчас выбрана опция "${selectedOption.innerText}"" со значением ${selectedOption.value}`)
15 |
16 | select.append(new Option('Классика', 'classic', true, true))
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/4.2. Focus and blur/README.md:
--------------------------------------------------------------------------------
1 | # Фокусировка: focus/blur
2 |
3 | Элемент получает `focus`, когда пользователь кликает по нему или использует клавишу `Tab`.
4 | Момент потери фокуса (`blur`) может быть важнее.
5 | Это момент, когда пользователь кликает куда-то ещё или нажимает `Tab`, чтобы переключиться на
6 | следующее поле формы.
7 |
8 | Методы `elem.focus()` и `elem.blur()` устанавливают/снимают фокус.
9 |
10 | ## Включаем фокусировку на любом элементе: tabindex
11 |
12 | Любой элемент поддерживает фокусировку, если имеет `tabindex`.
13 |
14 | При совпадающих `tabindex` элементы перебираются в том порядке, в котором идут в документе.
15 |
16 | - `tabindex="0"` ставит элемент в один ряд с элементами без tabindex.
17 | - `tabindex="-1"` позволяет фокусировать на элементе только программно.
18 |
19 |
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/4.3. Change, input, copy/README.md:
--------------------------------------------------------------------------------
1 | # События: change, input, cut, copy, paste
2 |
3 | ## Событие: change
4 |
5 | - срабатывает по окончании изменения элемента.
6 | - Для текстовых `
` это означает, что событие происходит при потере фокуса.
7 |
8 | ## Событие: input
9 |
10 | Событие `input` срабатывает каждый раз при изменении значения.
11 |
12 | Событие `input` происходит после изменения значения.
13 | Поэтому мы не можем использовать `event.preventDefault()` там – будет уже слишком поздно,
14 | никакого эффекта не будет.
15 |
16 | ## События: cut, copy, paste
17 |
18 | Эти события происходят при вырезании/копировании/вставке данных.
19 | Действие можно предотвратить.
20 | Свойство `event.clipboardData` предоставляет доступ на чтение/запись в буфер обмена…
21 |
22 |
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/4.4. Form submit/README.md:
--------------------------------------------------------------------------------
1 | # Отправка формы: событие и метод submit
2 |
3 | Когда форма отправляется, то срабатывает событие `submit`.
4 |
5 | > Обычно событие `submit` используется для валидации формы
6 |
7 | Есть два основных способа отправить форму:
8 |
9 | 1. Первый – нажать кнопку `
` или `
`.
10 | 2. Второй – нажать `Enter`, находясь на каком-нибудь поле.
11 |
12 | > При отправке формы по нажатию `Enter` в текстовом поле,
13 | > генерируется событие `click` на кнопке `
`.
14 |
15 | Метод `form.submit()` позволяет инициировать отправку формы из JavaScript.
16 | При этом событие `submit` уже не сработает, так как предполагается, что программист
17 | знает что делает... (провалидировал данные заранее и т.д)
18 |
19 |
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/5.3. Onload, onerror/src/1-preload-images.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Загрузите изображения с колбэком (важность: 4)
3 | *
4 | * Создайте функцию preloadImages(sources, callback), которая загружает все изображения из массива sources и,
5 | * когда все они будут загружены, вызывает callback.
6 | */
7 |
8 | function loadImage(src) {
9 | return new Promise((resolve, reject) => {
10 | const image = new Image()
11 | image.addEventListener('load', resolve.bind(this, image))
12 | image.addEventListener('error', reject.bind(this, image))
13 |
14 | image.src = src
15 | })
16 | }
17 |
18 | function preloadImages(sources, callback) {
19 | return Promise.all(sources.map(loadImage)).finally(callback)
20 | }
--------------------------------------------------------------------------------
/2. Browser: document, events, interfaces/6.3. Event loop/src/1-what-will-output.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Что код выведет в консоли? (важность: 5)
3 | *
4 | */
5 |
6 |
7 | setTimeout(function timeout() {
8 | console.log('Таймаут');
9 | }, 0);
10 |
11 | let p = new Promise(function(resolve, reject) {
12 | console.log('Создание промиса');
13 | resolve();
14 | });
15 |
16 | p.then(function(){
17 | console.log('Обработка промиса');
18 | });
19 |
20 | console.log('Конец скрипта');
21 |
22 | // Решение:
23 | // 1. "Создание промиса". Так как callback внутри промиса является обычным синхронным кодом
24 | // 2. "Конец скрипта". Обычный синхронный код, но в конце страницы
25 | // 3. "Обработка промиса". Так как это микрозадача
26 | // 4. "Таймаут". Так как это макрозадача.
27 |
--------------------------------------------------------------------------------
/4. Additional/4.1 Programming paradigms/4.1.2 Procedural/README.md:
--------------------------------------------------------------------------------
1 | # Процедурное программирование
2 |
3 | Программа ожидает на вход какие-либо данные, выполняет ряд процедур и возвращает результат.
4 |
5 | Подобный подход и называется процедурным:
6 | ```javascript
7 | const width = 5
8 | const height = 5
9 |
10 | function calcRectArea(width, height) {
11 | return width * height
12 | }
13 |
14 | calcRectArea(width, height)
15 | ```
16 |
17 | Задача разбивается на **шаги** и выполняется **шаг за шагом**
18 |
19 | > Изначально все программы писались именно с процедурным подходом.
20 | > Позже, когда программы стали становиться больше, данный подход начал отходить на второй план
21 |
22 |
23 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/2 kyu/1. Multi Line Task++: Hello World.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5935558a32fb828aad001213
2 |
3 | f=
4 | ''
5 | [
6 | '\
7 | t\
8 | r\
9 | i\
10 | m'
11 | ][
12 | '\
13 | b\
14 | i\
15 | n\
16 | d'
17 | ]`
18 | H\
19 | e\
20 | l\
21 | l\
22 | o\
23 | ,\
24 | \
25 | w\
26 | o\
27 | r\
28 | l\
29 | d\
30 | !`
--------------------------------------------------------------------------------
/5. Tasks/codewars/4 kyu/10. Next bigger number with the same digits.js:
--------------------------------------------------------------------------------
1 | function nextBigger(n){
2 | const digits = String(n).split('')
3 | const permutations = []
4 | const permutate = (digits, tail) => {
5 | const seenDigits = {}
6 |
7 | digits.forEach((digit, idx) => {
8 | if (seenDigits[digit]) return;
9 |
10 | const digitsLeft = [...digits]
11 | digitsLeft.splice(idx, 1)
12 |
13 | seenDigits[digit] = true
14 |
15 | if (digitsLeft.length >= 1) {
16 | return permutate(digitsLeft, tail + digit)
17 | } else {
18 | permutations.push(Number(tail + digit))
19 | }
20 | })
21 | }
22 |
23 | permutate(digits, '')
24 | permutations.sort((a, b) => a - b)
25 |
26 | const foundIdx = permutations.findIndex((number) => number === n)
27 |
28 | return permutations[foundIdx + 1] || -1
29 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/4 kyu/11. Sort binary tree by levels.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/52bef5e3588c56132c0003bc
2 | function treeByLevels(rootNode) {
3 | const list = []
4 |
5 | function sortByLvl(tree, level = 0) {
6 | if (!tree) {
7 | return;
8 | }
9 |
10 | if (!list[level]) {
11 | list[level] = []
12 | }
13 |
14 | list[level].push(tree.value)
15 |
16 |
17 | if (tree.left) {
18 | sortByLvl(tree.left, level + 1)
19 | }
20 |
21 | if (tree.right) {
22 | sortByLvl(tree.right, level + 1)
23 | }
24 | }
25 |
26 | sortByLvl(rootNode)
27 |
28 | return list.flat()
29 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/4 kyu/3. Nesting Structure Comparison.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/520446778469526ec0000001/javascript
3 | */
4 | Array.prototype.sameStructureAs = function (other) {
5 | if (this.length !== other.length) {
6 | return false;
7 | }
8 |
9 | for (let key in this) {
10 | const isPrimitives = !Array.isArray(this[key]) && !Array.isArray(other[key])
11 | const isArrays = Array.isArray(this[key]) && Array.isArray(other[key])
12 |
13 | if (!isPrimitives && !isArrays) {
14 | return false
15 | }
16 |
17 | if (isPrimitives) {
18 | continue;
19 | }
20 |
21 | const checkNested = this[key].sameStructureAs(other[key])
22 |
23 | if (!checkNested) {
24 | return false
25 | }
26 | }
27 |
28 | return true;
29 | };
--------------------------------------------------------------------------------
/5. Tasks/codewars/4 kyu/5. Strip comments.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/51c8e37cee245da6b40000bd
2 |
3 | function solution(input, markers) {
4 | const hashMap = markers.reduce((acc, cur) => {
5 | acc[cur] = true;
6 | return acc
7 | }, {})
8 |
9 | const rows = input.split('\n')
10 | const filtered = rows.map((row) => {
11 | const commentIdx = [...row].findIndex((char) => hashMap[char])
12 | const commented = commentIdx === -1 ? row : row.slice(0, commentIdx)
13 |
14 | return commented.trim()
15 | })
16 |
17 | return filtered.filter(Boolean).join('\n')
18 | }
19 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/4 kyu/6. Permutations.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5254ca2719453dcc0b00027d
2 |
3 | function permutations(string) {
4 | const letters = string.split('')
5 | const permutations = []
6 |
7 | function recursive(letters, tail = '') {
8 | if (letters.length === 1) return permutations.push(tail + letters[0])
9 |
10 | const tree = {}
11 |
12 | for (let i = 0; i < letters.length; i++) {
13 | const letter = letters[i]
14 |
15 | if (tree[letter]) continue
16 |
17 | const otherLetters = [...letters]
18 | otherLetters.splice(i, 1)
19 |
20 | tree[letter] = recursive(otherLetters, tail + letter)
21 | }
22 |
23 | return tree
24 | }
25 |
26 | recursive(letters)
27 |
28 | return permutations
29 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/4 kyu/7. Sum Strings as Numbers.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5324945e2ece5e1f32000370
2 |
3 | function sumStrings(a,b) {
4 | return String(BigInt(a) + BigInt(b))
5 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/4 kyu/9. Range extraction.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/51ba717bb08c1cd60f00002f
2 |
3 | function solution(list){
4 | const ranges = []
5 |
6 | let rangeIdx = 0;
7 |
8 | for (let i = 0; i < list.length; i++) {
9 | const current = list[i]
10 | const next = list[i + 1]
11 |
12 | if (!ranges[rangeIdx]) ranges[rangeIdx] = []
13 | ranges[rangeIdx].push(current)
14 |
15 | if (next - current > 1) {
16 | rangeIdx++
17 | }
18 | }
19 |
20 | return ranges.map((range) => {
21 | const start = range[0]
22 | const end = range.length > 1 ? range[range.length - 1] : null
23 |
24 | if (range.length === 1) return `${start}`
25 | if (range.length === 2) return `${start},${end}`
26 |
27 | return `${start}-${end}`
28 | }).join(',')
29 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/5 kyu/1. int32 to IPv4.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/52e88b39ffb6ac53a400022e
3 | */
4 |
5 | function int32ToIp(int32){
6 | const bytes = (+int32).toString(2).padStart(32, '0');
7 | const octets = [
8 | bytes.slice(0, 8),
9 | bytes.slice(8, 16),
10 | bytes.slice(16, 24),
11 | bytes.slice(24, 32)
12 | ];
13 |
14 | return octets
15 | .map((binary) => parseInt(binary, 2).toString())
16 | .join('.')
17 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/5 kyu/10. Array.diff hero.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/581fc49b55c3d2d83c0000f8
2 |
3 | function arrayDiffVeryFast(a, b) {
4 | const valuesFromSecondMap = b.reduce((acc, cur) => {
5 | acc[cur] = true
6 | return acc
7 | }, {})
8 | const notExistsInSecond = value => !valuesFromSecondMap[value]
9 |
10 | return a.filter(notExistsInSecond)
11 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/5 kyu/12. Simple events.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/52d3b68215be7c2d5300022f
2 |
3 | function Event() {
4 | this._subscribers = [];
5 |
6 | this.subscribe = function(callback) {
7 | this._subscribers.push(callback);
8 | }
9 |
10 | this.unsubscribe = function(callback) {
11 | this._subscribers = this._subscribers.filter((subscriber) => subscriber !== callback);
12 | }
13 |
14 | this.emit = function(...data) {
15 | this._subscribers.forEach((subscriber) => {
16 | subscriber.call(this, ...data);
17 | })
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/5 kyu/14. Can you get the loop.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/52a89c2ea8ddc5547a000863
2 |
3 | function loop_size(node){
4 | const memoized = new Map()
5 |
6 | let current = node
7 | let size = 1;
8 |
9 | while (true) {
10 | if (memoized.get(current)) {
11 | break;
12 | }
13 |
14 | if (!current.getNext() || current.getNext() === current) {
15 | return size;
16 | }
17 |
18 | memoized.set(current, true)
19 | current = current.getNext()
20 | }
21 |
22 | let loopStart = current;
23 |
24 | while (loopStart !== current.getNext()) {
25 | size++
26 | current = current.getNext()
27 | }
28 |
29 | return size
30 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/5 kyu/16. Function Cache.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/525481903700c1a1ff0000e1
2 |
3 | function cache(func) {
4 | const memory = {}
5 |
6 | return (...args) => {
7 | const key = JSON.stringify(args)
8 |
9 | if (key in memory) {
10 | return memory[key]
11 | }
12 |
13 | const result = func.call(this, ...args)
14 | memory[key] = result
15 |
16 | return result
17 | }
18 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/5 kyu/3. Product of consecutive Fib numbers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/5541f58a944b85ce6d00006a/javascript
3 | */
4 | function productFib(prod){
5 | const fibo = [0, 1]
6 | let next = 1;
7 | let idx = 0;
8 |
9 | while (next < Number.MAX_SAFE_INTEGER) {
10 | next = fibo[idx] + fibo[idx + 1]
11 | fibo.push(next)
12 | idx++
13 | }
14 |
15 | for (let i = 0; i < fibo.length; i++) {
16 | const left = fibo[i]
17 | const right = fibo[i + 1]
18 |
19 | const mult = left * right
20 |
21 | if (mult === prod) {
22 | return [left, right, true]
23 | }
24 |
25 | if (mult > prod) {
26 | return [left, right, false]
27 | }
28 | }
29 |
30 | return null;
31 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/5 kyu/5. The Hashtag generator.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/52449b062fb80683ec000024/
2 |
3 | function capitalize(str) {
4 | return str.slice(0, 1).toUpperCase() + str.slice(1)
5 | }
6 |
7 | function generateHashtag (str) {
8 | str = str.trim().replace(/\s{2,}/g, ' ')
9 |
10 | if (str === "") return false
11 |
12 | const hashtag = str
13 | .split(' ')
14 | .map(capitalize)
15 | .join(``)
16 |
17 | if (hashtag.length >= 140) return false
18 |
19 | return `#${hashtag}`
20 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/5 kyu/7. 1's, 0's and wildcards.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/588f3e0dfa74475a2600002a
2 |
3 | function possibilities(str) {
4 | const permutations = []
5 | const position = str.indexOf('?')
6 |
7 | if (position === -1) {
8 | return [str]
9 | }
10 |
11 | const first = str.slice(0, position) + '0' + str.slice(position + 1)
12 | const second = str.slice(0, position) + '1' + str.slice(position + 1)
13 |
14 | permutations.push(
15 | ...possibilities(first),
16 | ...possibilities(second),
17 | )
18 |
19 | return permutations;
20 | }
21 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/5 kyu/9. Number of trailing zeros of N!.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/52f787eb172a8b4ae1000a34
2 |
3 | // A trailing zero is always produced by prime factors 2 and 5.
4 | // If we can count the number of 5s and 2s, our task is done.
5 |
6 | function zeros (n) {
7 | if (n < 0) return -1
8 |
9 | let count = 0
10 |
11 | for (let i = 5; Math.floor(n / i) >= 1; i *= 5) {
12 | count += Math.floor(n / i)
13 | }
14 |
15 | return count
16 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/1. Your order, please!.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/55c45be3b2079eccff00010f/javascript
3 | */
4 |
5 | function order(words){
6 | if (words === "") return ""
7 |
8 | const onlyNum = (str) => +str.replace(/[^0-9]/g, '')
9 |
10 | return words
11 | .split(' ')
12 | .sort((a, b) => {
13 | return onlyNum(a) - onlyNum(b)
14 | })
15 | .join(' ')
16 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/11. Get Length of missing array.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/57b6f5aadb5b3d0ae3000611
2 |
3 | function getLengthOfMissingArray(arr) {
4 | if (!arr?.length) return 0
5 |
6 | const lengths = {}
7 |
8 | for (let inner of arr) {
9 | if (!inner?.length) return 0
10 |
11 | lengths[inner.length] = inner.length
12 | }
13 |
14 | const keys = Object.keys(lengths)
15 | let lastKey = Number(keys[0])
16 |
17 | for (let i = 1; i < keys.length; i++) {
18 | const currentKey = Number(keys[i])
19 | const shouldBeKey = lastKey + 1
20 |
21 | if (currentKey !== shouldBeKey) return shouldBeKey
22 |
23 | lastKey = shouldBeKey
24 | }
25 |
26 | return 0
27 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/12. Duplicate Encoder.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/54b42f9314d9229fd6000d9c
2 |
3 | function duplicateEncode(word){
4 | const charsCountMap = word.split('').reduce((acc, char) => {
5 | char = char.toLowerCase()
6 | acc[char] = (acc[char] || 0) + 1
7 |
8 | return acc
9 | }, {})
10 |
11 | return word
12 | .split('')
13 | .map((char) => charsCountMap[char.toLowerCase()] === 1 ? '(' : ')')
14 | .join('')
15 | }
16 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/13. Take a number and sum its digits raised. Eureca.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5626b561280a42ecc50000d1
2 |
3 | function sumDigPow(from, to) {
4 | const eurica = []
5 |
6 | for (let num = from; num <= to; num++) {
7 | const digits = String(num).split('')
8 | const powed = digits.map((num, i) => num ** (i + 1))
9 | const sum = powed.reduce((acc, cur) => acc + cur)
10 |
11 | if (sum === num) {
12 | eurica.push(num)
13 | }
14 | }
15 |
16 | return eurica
17 | }
18 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/14. Tortoise racing.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/55e2adece53b4cdcb900006c
2 |
3 | function race(v1, v2, g) {
4 | const s1 = v1 / 60 / 60
5 | const s2 = v2 / 60 / 60
6 |
7 | const speedDiff = (v2 - v1) / 60 / 60
8 |
9 | const distanceToLead = Math.floor(g / speedDiff)
10 |
11 | const hours = Math.floor(distanceToLead / 3600)
12 | const minutes = Math.floor((distanceToLead - (hours * 3600)) / 60)
13 | const seconds = Math.floor(distanceToLead - (hours * 3600) - (minutes * 60))
14 |
15 | const result = [hours, minutes, seconds]
16 |
17 | if (result.some((value) => value < 0)) return null
18 |
19 | return [hours, minutes, seconds]
20 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/15. Build tower.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/576757b1df89ecf5bd00073b
2 |
3 | const towerBuilder = floors => Array.from({ length: floors }, (_, i) => {
4 | const spaces = floors - 1 - i;
5 | const stars = 1 + (i * 2);
6 |
7 | return ' '.repeat(spaces) + '*'.repeat(stars) + ' '.repeat(spaces)
8 | })
9 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/16. Triple Double.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/55d5434f269c0c3f1b000058
2 |
3 | function tripledouble(num1, num2) {
4 | const FOUND_RESPONSE = 1
5 | const NOT_FOUND_RESPONSE = 0
6 |
7 | const possibles = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
8 | const [first, second] = [num1, num2].map(String)
9 |
10 | for (const possible of possibles) {
11 | const triple = String(possible).repeat(3)
12 | const double = String(possible).repeat(2)
13 |
14 | const foundTripleInFirst = first.indexOf(triple) !== -1
15 | const foundDoubleInSecond = second.indexOf(double) !== -1
16 |
17 | if (foundTripleInFirst && foundDoubleInSecond) {
18 | return FOUND_RESPONSE
19 | }
20 | }
21 |
22 | return NOT_FOUND_RESPONSE
23 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/17. Function composition.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5655c60db4c2ce0c2e000026
2 |
3 | const compose = (...functions) => arg => functions.reduceRight((res, fn) => fn.call(this, res), arg);
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/18. Data Reverse.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/569d488d61b812a0f7000015
2 |
3 | function dataReverse(data) {
4 | const SEGMENT_SIZE = 8
5 |
6 | const result = []
7 |
8 | for (let i = data.length; i >= 0; i -= SEGMENT_SIZE) {
9 | result.push(...data.slice(i - SEGMENT_SIZE, i))
10 | }
11 |
12 | return result
13 | }
14 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/19. Find the missing letter.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5839edaa6754d6fec10000a2
2 |
3 | function findMissingLetter(letters) {
4 | let lastCharCode
5 |
6 | for (const letter of letters) {
7 | const charCode = letter.charCodeAt()
8 | const diff = charCode - lastCharCode
9 |
10 | if (diff > 1) {
11 | return String.fromCharCode(lastCharCode + 1)
12 | }
13 |
14 | lastCharCode = charCode
15 | }
16 |
17 | return null
18 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/21. Find the last Fibonacci digit.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/56b7771481290cc283000f28
2 |
3 | function lastFibDigit(n){
4 | const pattern = [0, 1, 1, 2, 3, 5, 8, 3, 1, 4, 5, 9, 4, 3, 7, 0, 7, 7, 4, 1, 5, 6, 1, 7, 8, 5, 3, 8, 1, 9, 0, 9, 9, 8, 7, 5, 2, 7, 9, 6, 5, 1, 6, 7, 3, 0, 3, 3, 6, 9, 5, 4, 9, 3, 2, 5, 7, 2, 9, 1]
5 | const idx = n % 60
6 |
7 | return pattern[idx]
8 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/22. The Office V - Find a Chair.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/57f6051c3ff02f3b7300008b
2 |
3 | function meeting(rooms, needChairs){
4 | if (!needChairs) return 'Game On'
5 |
6 | const result = []
7 |
8 | for (const [occupants, chairsInRoom] of rooms) {
9 | if (needChairs === 0) return result
10 |
11 | const availableChairs = Math.max(chairsInRoom - occupants.length, 0)
12 | const willGetChairs = needChairs - availableChairs >= 0
13 | ? availableChairs
14 | : needChairs
15 |
16 | needChairs -= willGetChairs;
17 | result.push(willGetChairs);
18 | }
19 |
20 | if (needChairs >= 1) return 'Not enough!'
21 |
22 | return result
23 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/23. Guess the number!.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5452113c699b538c18000b01
2 |
3 | Guesser.prototype.getNumber = function() {
4 | const phrase = {
5 | greater: 'Too low!',
6 | lower: 'Too high!',
7 | equal: 'Correct!',
8 | }
9 |
10 | let number = 500
11 | let diff = 250
12 | let lastAnswer = null
13 |
14 | while (lastAnswer !== phrase.equal) {
15 | lastAnswer = this.guess(number)
16 |
17 | if (lastAnswer === phrase.greater) {
18 | number += diff
19 | }
20 |
21 | if (lastAnswer === phrase.lower) {
22 | number -= diff
23 | }
24 |
25 | if (lastAnswer === phrase.equal) {
26 | return number
27 | }
28 |
29 | diff = Math.round(diff / 2)
30 | }
31 |
32 | return number
33 | };
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/24. Frog jumping.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/536950ffc8a5ca9982001371
2 |
3 | function solution(arr) {
4 | const MAX_JUMPS = 10_000;
5 |
6 | let idx = 0
7 | let jumps = 0
8 |
9 | while (idx >= 0 && idx < arr.length) {
10 | if (jumps >= MAX_JUMPS) {
11 | return -1;
12 | }
13 |
14 | idx += arr[idx];
15 | jumps++;
16 | }
17 |
18 | return jumps
19 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/25. Number Zoo Patrol.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5276c18121e20900c0000235
2 |
3 | function findNumber(array) {
4 | const set = new Set(array)
5 |
6 | for (let i = 1; i < 999_999; i++) {
7 | if (!set.has(i)) {
8 | return i;
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/26. CamelCase method.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/587731fda577b3d1b0001196
2 |
3 | String.prototype.camelCase=function(){
4 | return this
5 | .split(' ')
6 | .filter(Boolean)
7 | .map((str) => str[0].toUpperCase() + str.slice(1))
8 | .join('')
9 | }
10 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/27. Parse a linked list from a string.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/582c5382f000e535100001a7
2 |
3 | function parse(string) {
4 | const nodes = string.split(' -> ')
5 |
6 | let result = null;
7 |
8 | while (nodes.length) {
9 | const node = nodes.pop()
10 |
11 | if (node === 'null') continue
12 | result = new Node(+node, result)
13 | }
14 |
15 | return result
16 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/28. PhoneWords.js:
--------------------------------------------------------------------------------
1 | function phoneWords(stringOfNums) {
2 | const buttons = {
3 | '2': 'abc',
4 | '3': 'def',
5 | '4': 'ghi',
6 | '5': 'jkl',
7 | '6': 'mno',
8 | '7': 'pqrs',
9 | '8': 'tuv',
10 | '9': 'wxyz',
11 | '0': ' '
12 | }
13 |
14 | return stringOfNums.replace(
15 | /([0]+)|([1]+)|([2]+)|([3]+)|([4]+)|([5]+)|([6]+)|([7]+)|([8]+)|([9]+)/g,
16 | (group) => {
17 | const button = group[0]
18 | const buttonKeys = buttons[button]
19 |
20 | if (!buttonKeys) return ''
21 |
22 | const chunks = []
23 | const chunkSize = buttonKeys.length
24 |
25 | for (let i = 0; i < group.length; i += chunkSize) {
26 | const chunk = group.slice(i, i + chunkSize);
27 | chunks.push(chunk);
28 | }
29 |
30 | return chunks.map(chunk => buttonKeys[chunk.length - 1]).join('')
31 | }
32 | )
33 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/29. Longest consecutive.js:
--------------------------------------------------------------------------------
1 | https://www.codewars.com/kata/56a5d994ac971f1ac500003e
2 |
3 | const longestConsec = (strarr, k) => {
4 | if(k > strarr.length || k < 0) return ""
5 |
6 | let maxLengthString = '';
7 |
8 | for (let i = 0; i < strarr.length + 1 - k; i++) {
9 | const combined = strarr.slice(i, i + k).join('')
10 |
11 | if (combined.length > maxLengthString.length) {
12 | maxLengthString = combined
13 | }
14 | }
15 |
16 | return maxLengthString
17 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/30. Maximum and minimum.js:
--------------------------------------------------------------------------------
1 | function max(...args) {
2 | const flatten = args.map((arg) => {
3 | return Array.isArray(arg)
4 | ? max(...arg.flat())
5 | : +arg
6 | })
7 |
8 | let maxValue = flatten[0] || 0
9 |
10 | for (const number of flatten) {
11 | if (Number.isNaN(number)) {
12 | return NaN
13 | }
14 |
15 | maxValue = maxValue > number ? maxValue : number
16 | }
17 |
18 | return maxValue
19 | }
20 |
21 | function min(...args) {
22 | const flatten = args.map((arg) => {
23 | return Array.isArray(arg)
24 | ? min(...arg.flat())
25 | : +arg
26 | })
27 |
28 | let minValue = flatten[0] || 0
29 |
30 | for (const number of flatten) {
31 | if (Number.isNaN(number)) {
32 | return NaN
33 | }
34 |
35 | minValue = minValue < number ? minValue : number
36 | }
37 |
38 | return minValue
39 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/31. Plenty of Fish in the Pond.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5904be220881cb68be00007d
2 |
3 | function fish(shoal){
4 | const AMOUNT_STEP = 4
5 |
6 | const fishes = shoal.split('').sort((a, b) => a - b)
7 |
8 | function getNewSize(score) {
9 | let size = 1;
10 | let amountExtra = AMOUNT_STEP;
11 |
12 | while (score - amountExtra >= 0) {
13 | score -= amountExtra;
14 | size++;
15 | amountExtra += AMOUNT_STEP;
16 | }
17 |
18 | return size;
19 | }
20 |
21 | let size = 1;
22 | let score = 0;
23 |
24 | for (let i = 0; i < fishes.length; i++) {
25 | const fishToEatSize = Number(fishes[i])
26 |
27 | if (size < fishToEatSize) {
28 | return size;
29 | }
30 |
31 | score += fishToEatSize;
32 | size = getNewSize(score);
33 | }
34 |
35 | return size;
36 | }
37 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/32. Word mesh.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5c1ae703ba76f438530000a2
2 |
3 | function wordMesh(arr){
4 | const FAILED_TO_MESH_ERROR = 'failed to mesh'
5 |
6 | let result = ''
7 |
8 | for (let i = 1; i < arr.length; i++) {
9 | const current = arr[i]
10 | const prev = arr[i - 1]
11 | const minLength = Math.min(prev.length, current.length)
12 |
13 | let same = ''
14 |
15 | for (let j = minLength; j >= 1; j--) {
16 | const left = prev.slice(-j)
17 | const right = current.slice(0, j)
18 |
19 | if (left === right) {
20 | same = left
21 | break
22 | }
23 | }
24 |
25 | if (!same) {
26 | return FAILED_TO_MESH_ERROR
27 | }
28 |
29 | result += same
30 | }
31 |
32 | return result || FAILED_TO_MESH_ERROR
33 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/33. Zero-plentiful Array.js:
--------------------------------------------------------------------------------
1 | function zeroPlentiful(arr){
2 | let groupsCount = 0
3 | let currentStreak = 0
4 |
5 | for (let i = 0; i < arr.length; i++) {
6 | const number = arr[i]
7 | const isZero = number === 0
8 | const isLast = i === arr.length - 1;
9 |
10 | if (isZero) {
11 | currentStreak++;
12 | }
13 |
14 | if (!isZero || isLast) {
15 | if (currentStreak >= 1 && currentStreak < 4) {
16 | return 0;
17 | }
18 |
19 | if (currentStreak >= 4) {
20 | groupsCount++;
21 | currentStreak = 0;
22 | }
23 | }
24 | }
25 |
26 | return groupsCount
27 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/34. Remove the parentheses.js:
--------------------------------------------------------------------------------
1 | function removeParentheses(sentence) {
2 | let depth = 0
3 | let result = ''
4 |
5 | for (const char of sentence) {
6 | if (char === '(') depth++;
7 | if (char === ')') depth--;
8 | if (depth === 0 && char !== ')' && char !== '(') result += char;
9 | }
10 |
11 | return result
12 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/35. Car number plate calculator.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5f25f475420f1b002412bb1f
2 |
3 | function findTheNumberPlate(customerId){
4 | const leftCount = Math.floor(customerId / 999)
5 | const rightCount = customerId % 999
6 |
7 | const leftPart = (() => {
8 | const alphabet = 'abcdefghijklmnopqrstuvwxyz'
9 | const counters = [
10 | leftCount % alphabet.length,
11 | Math.floor(leftCount / alphabet.length) % alphabet.length,
12 | Math.floor(leftCount / alphabet.length ** 2) % alphabet.length,
13 | ]
14 |
15 | return counters.map(idx => alphabet[idx]).join('')
16 | })()
17 |
18 | const rightPart = String(rightCount + 1).padStart(3, '0')
19 |
20 |
21 | return leftPart + rightPart
22 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/38. Lottery Ticket.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/57f625992f4d53c24200070e
2 |
3 | function bingo(ticket, win){
4 | let miniwins = 0
5 |
6 | for (const [characters, characterCodeToWin] of ticket) {
7 | if (characters.split('').some(char => char.charCodeAt() === characterCodeToWin)) {
8 | miniwins++
9 | }
10 | }
11 |
12 | return miniwins >= win
13 | ? 'Winner!'
14 | : 'Loser!'
15 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/39. Simple Fun #52: Pair of Shoes.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/58885a7bf06a3d466e0000e3
2 |
3 | function pairOfShoes(shoes) {
4 | const LEFT_SHOE = 0
5 | const RIGHT_SHOE = 1
6 |
7 | const sizes = {}
8 |
9 | for (const [type, size] of shoes) {
10 | if (!sizes[size]) {
11 | sizes[size] = {}
12 | }
13 |
14 | sizes[size][type] = (sizes[size][type] || 0) + 1
15 | }
16 |
17 | for (const [size, types] of Object.entries(sizes)) {
18 | const leftShoesCount = types[LEFT_SHOE]
19 | const rightShoesCount = types[RIGHT_SHOE]
20 |
21 | if (leftShoesCount !== rightShoesCount) {
22 | return false
23 | }
24 | }
25 |
26 | return true
27 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/4. Sorting on Planet Twisted 3-7.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/58068479c27998b11900056e/javascript
3 | * @param array
4 | * @returns {*[]}
5 | */
6 |
7 | function sortTwisted37(array) {
8 | const twist = (digit) => {
9 | if (digit === '3') return '7'
10 | if (digit === '7') return '3'
11 |
12 | return digit
13 | }
14 |
15 | return [...array].sort((a, b) => {
16 | a = +`${a}`.split('').map(twist).join('')
17 | b = +`${b}`.split('').map(twist).join('')
18 |
19 | return a - b
20 | })
21 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/6. Split strings.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/515de9ae9dcfc28eb6000001
3 | */
4 |
5 | function solution(str){
6 | const CHUNK_LENGTH = 2
7 | const result = []
8 |
9 | for (let i = 0; i < str.length; i += CHUNK_LENGTH) {
10 | const chunk = str
11 | .split('')
12 | .slice(i, i + CHUNK_LENGTH)
13 | .join('')
14 | .padEnd(CHUNK_LENGTH, '_')
15 |
16 | result.push(chunk)
17 | }
18 |
19 | return result
20 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/7. Rectangle into squares.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/55466989aeecab5aac00003e/
3 | */
4 | function sqInRect(length, width){
5 | if (length === width) return null;
6 |
7 | const result = []
8 |
9 | const rectangle = {
10 | length,
11 | width,
12 | get area() {
13 | return this.length * this.width;
14 | }
15 | }
16 |
17 | while (rectangle.area > 0) {
18 | const square = {
19 | side: Math.min(rectangle.length, rectangle.width),
20 | }
21 |
22 | if (rectangle.length > rectangle.width) {
23 | rectangle.length -= square.side
24 | } else if (rectangle.length < rectangle.width) {
25 | rectangle.width -= square.side
26 | } else {
27 | rectangle.length -= square.side
28 | rectangle.width -= square.side
29 | }
30 |
31 | result.push(square.side)
32 | }
33 |
34 | return result
35 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/8. Handshake problem.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/5574835e3e404a0bed00001b
3 | */
4 | function getParticipants(handshakes){
5 | if (handshakes === 0) return 0
6 | if (handshakes === 1) return 2
7 |
8 | let participants = 1;
9 |
10 | while (handshakes > 0) {
11 | participants++
12 | handshakes -= (participants - 1)
13 | }
14 |
15 | return participants
16 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/6 kyu/9. Lets Recycle.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5b6db1acb118141f6b000060
2 |
3 | function recycle(bin) {
4 | const groupedByMaterial = {
5 | paper: [],
6 | glass: [],
7 | organic: [],
8 | plastic: []
9 | }
10 |
11 | bin.forEach((trash) => {
12 | groupedByMaterial[trash.material].push(trash.type)
13 |
14 | if (trash.secondMaterial) {
15 | groupedByMaterial[trash.secondMaterial].push(trash.type)
16 | }
17 | })
18 |
19 | return Object.values(groupedByMaterial)
20 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/1. Don't give me five!.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/5813d19765d81c592200001a
3 | */
4 |
5 | const dontGiveMeFive = (start, end) => Array
6 | .from({ length: end - start + 1 }, (_, i) => i + start)
7 | .filter((num) => !String(num).includes('5'))
8 | .length
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/10. The Coupon Code.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/539de388a540db7fec000642
3 | */
4 |
5 | function checkCoupon(enteredCode, correctCode, currentDate, expirationDate){
6 | const isExpired = new Date(expirationDate) - new Date(currentDate) < 0;
7 | const isInvalid = enteredCode !== correctCode;
8 |
9 | return !isExpired && !isInvalid
10 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/11. Remove anchor from URL.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/51f2b4448cadf20ed0000386
2 |
3 | function removeUrlAnchor(url){
4 | const anchorIdx = url.indexOf('#')
5 |
6 | return anchorIdx === -1 ? url : url.slice(0, anchorIdx)
7 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/12. Number of People in the Bus.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5648b12ce68d9daa6b000099
2 |
3 | var number = function(busStops){
4 | let people = 0;
5 |
6 | for (const [gotOn = 0, gotOff = 0] of busStops) {
7 | people += gotOn - gotOff;
8 | }
9 |
10 | return people
11 | }
12 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/13. Sorted? yes? no? how?.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/580a4734d6df748060000045
2 |
3 | function isSortedAndHow(array) {
4 | const isSortedAscending = array.every((current, i) => {
5 | const previous = array[i - 1] ?? -Infinity
6 |
7 | return current >= previous;
8 | })
9 |
10 | const isSortedDescending = array.every((current, i) => {
11 | const previous = array[i - 1] ?? Infinity
12 |
13 | return current <= previous
14 | })
15 |
16 | if (isSortedAscending) return 'yes, ascending'
17 | if (isSortedDescending) return 'yes, descending'
18 |
19 | return 'no'
20 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/14. Multiply word in string.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5ace2d9f307eb29430000092
2 |
3 | function modifyMultiply (str,loc,num) {
4 | const word = str.split(' ')[loc]
5 | return Array.from({ length: num }, () => word).join('-')
6 | }
7 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/15. Vowel one.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/580751a40b5a777a200000a1
2 |
3 | function vowelOne(s){
4 | const checkVowel = char => {
5 | return Boolean({ a: true, e: true, i: true, o: true, u: true }[char.toLowerCase()])
6 | }
7 |
8 | return s.split('').map(char => checkVowel(char) ? '1' : '0').join('')
9 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/16. Alternate capitalization.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/59cfc000aeb2844d16000075
2 |
3 | function capitalize(s){
4 | return [
5 | s.split('').map((char, i) => i % 2 === 0 ? char.toUpperCase() : char.toLowerCase()).join(''),
6 | s.split('').map((char, i) => i % 2 !== 0 ? char.toUpperCase() : char.toLowerCase()).join(''),
7 | ]
8 | };
9 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/17. Last Survivor.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/609eee71109f860006c377d1
2 |
3 | function lastSurvivor(letters, coords) {
4 | while (coords.length) {
5 | const idx = coords.shift()
6 | letters = letters.slice(0, idx) + letters.slice(idx + 1)
7 | }
8 |
9 | return letters
10 | }
11 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/18. Largest Elements.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/53d32bea2f2a21f666000256
2 |
3 | function largest(n,xs){
4 | if (n <= 0) return []
5 | return xs.sort((a, b) => a - b).slice(-n)
6 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/19. Factorial.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/54ff0d1f355cfd20e60001fc
2 |
3 | function factorial(n) {
4 | if (n < 0 || n > 12) throw new RangeError()
5 |
6 | let sum = 1
7 |
8 | while (n > 0) {
9 | sum *= n
10 | n--
11 | }
12 |
13 | return sum
14 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/2. Disemvowel Trolls.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/52fba66badcd10859f00097e/javascript
3 | */
4 | function disemvowel(str) {
5 | const vowels = { a: 'a', e: 'e', i: 'i', o: 'o', u: 'u', A: 'A', E: 'E', I: 'I', O: 'O', U: 'U' }
6 |
7 | return str
8 | .split('')
9 | .reduce((result, char) => result += vowels[char] ? '' : char, '')
10 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/20. Two oldest ages.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/511f11d355fe575d2c000001
2 |
3 | function twoOldestAges(ages){
4 | return ages.sort((a, b) => a - b).slice(-2)
5 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/21. Power of two.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/534d0a229345375d520006a0
2 |
3 | function isPowerOfTwo(n){
4 | if (n === 1) return true
5 | if (!Number.isInteger(n) || n < 1) return false
6 |
7 | return isPowerOfTwo(n / 2)
8 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/22. Flatten and sort an array.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/57ee99a16c8df7b02d00045f
2 |
3 | const flattenAndSort = arr => [...arr].flat().sort((a, b) => a - b)
4 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/24. Form the minimum.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5ac6932b2f317b96980000ca
2 |
3 | function minValue(values){
4 | const uniques = [...new Set(values)]
5 |
6 | return +uniques.sort((a, b) => a - b).join('')
7 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/25. The 12 Days of Christmas.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/57dd3a06eb0537b899000a64
2 |
3 | var comparator = function(a,b) {
4 | const correctOrders = ['On', '12', '11', '10', '9', '8', '7', '6', '5', '4', '3', '2', 'a']
5 | const idx1 = correctOrders.findIndex((substr) => a.startsWith(substr))
6 | const idx2 = correctOrders.findIndex((substr) => b.startsWith(substr))
7 |
8 | return idx1 - idx2;
9 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/26. Alan Partridge I - Partridge Watch.js:
--------------------------------------------------------------------------------
1 | function part(phrases){
2 | const related = new Set([
3 | 'Partridge',
4 | 'PearTree',
5 | 'Chat',
6 | 'Dan',
7 | 'Toblerone',
8 | 'Lynn',
9 | 'AlphaPapa',
10 | 'Nomad',
11 | ])
12 |
13 | const termsFoundCount = phrases.reduce((found, phrase) => {
14 | if (related.has(phrase)) {
15 | return found + 1;
16 | }
17 |
18 | return found
19 | }, 0)
20 |
21 | return termsFoundCount
22 | ? `Mine's a Pint` + '!'.repeat(termsFoundCount)
23 | : `Lynn, I've pierced my foot on a spike!!`
24 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/27. Alan Partridge III - London.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/580a41b6d6df740d6100030c
2 |
3 | function alan(stations){
4 | stations = new Set(stations)
5 |
6 | const stops = new Set([
7 | 'Rejection',
8 | 'Disappointment',
9 | 'Backstabbing Central',
10 | 'Shattered Dreams Parkway',
11 | ])
12 |
13 | for (const stop of stops) {
14 | if (!stations.has(stop)) {
15 | return 'No, seriously, run. You will miss it.'
16 | }
17 | }
18 |
19 | return 'Smell my cheese you mother!'
20 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/28. How many are smaller than me.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/56a1c074f87bc2201200002e
2 |
3 | function smaller(nums) {
4 | return nums.map((num, i) => {
5 | let count = 0;
6 |
7 | for (let j = i + 1; j < nums.length; j++) {
8 | if (num > nums[j]) count++
9 | }
10 |
11 | return count;
12 | })
13 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/29. Previous multiple of three.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/61123a6f2446320021db987d
2 |
3 | const prevMultOfThree = n => {
4 | do {
5 | const result = n / 3
6 |
7 | if (Number.isInteger(result)) {
8 | return n
9 | }
10 |
11 | n = Math.floor(n / 10)
12 | } while (n >= 3)
13 |
14 | return null
15 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/3. Sum of a sequence.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/586f6741c66d18c22800010a/javascript
3 | */
4 | const sequenceSum = (begin, end, step) => {
5 | let result = 0;
6 |
7 | for (let i = begin; i <= end; i+= step) {
8 | result += i;
9 | }
10 |
11 | return result
12 | };
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/4. Friend or Foe.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/55b42574ff091733d900002f
2 |
3 | function friend(friends) {
4 | const NEED_NAME_LENGTH = 4
5 |
6 | return friends.filter((friendName) => friendName.length === NEED_NAME_LENGTH)
7 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/5. Check the exam.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5a3dd29055519e23ec000074
2 |
3 | function checkExam(correctAnswers, studentAnswers) {
4 | const RATING_SYSTEM = {
5 | correct: 4,
6 | incorrect: -1,
7 | blank: 0
8 | }
9 |
10 | let score = 0;
11 |
12 | for (let i = 0; i < studentAnswers.length; i++) {
13 | const studentAnswer = studentAnswers[i]
14 | const correctAnswer = correctAnswers[i]
15 |
16 | const isBlank = studentAnswer.length === 0
17 | const isCorrect = studentAnswer === correctAnswer
18 |
19 | if (isBlank) {
20 | score += RATING_SYSTEM.blank
21 | continue
22 | }
23 |
24 | if (isCorrect) {
25 | score += RATING_SYSTEM.correct
26 | continue
27 | }
28 |
29 | score += RATING_SYSTEM.incorrect
30 | }
31 |
32 | return score >= 0 ? score : 0
33 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/6. Ultimate Array Reverser.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5c3433a4d828182e420f4197
2 |
3 | const ultimateReverse = sentence => {
4 | const lengths = sentence.map((word) => word.length)
5 | const reversed = sentence.join('').split('').reverse().join('')
6 |
7 | let reversedSentence = reversed
8 |
9 | return lengths.map(length => {
10 | const part = reversedSentence.slice(0, length)
11 | reversedSentence = reversedSentence.slice(length)
12 |
13 | return part
14 | })
15 | };
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/7. Simple fun #176. Reverse letter.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/58b8c94b7df3f116eb00005b
2 |
3 | function reverseLetter(str) {
4 | return str.replace(/[^a-z]/g, '').split('').reverse().join('')
5 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/8. Anagram detection.js:
--------------------------------------------------------------------------------
1 | const countChars = (word) => {
2 | const chars = word.split('')
3 | const map = {}
4 |
5 | chars.forEach((char) => {
6 | char = char.toLowerCase()
7 | map[char] = (map[char] || 0) + 1;
8 | })
9 |
10 | return map
11 | }
12 |
13 | const areCharsCountEqual = (charsMap1, charsMap2) => {
14 | return Object.keys({ ...charsMap1, ...charsMap2 })
15 | .every((key) => {
16 | return charsMap1[key] === charsMap2[key]
17 | })
18 | }
19 |
20 | const isAnagram = (test, original) => {
21 | if (test.length !== original.length) return false
22 |
23 | const chars = {
24 | in: {
25 | test: countChars(test),
26 | original: countChars(original),
27 | }
28 | }
29 |
30 | return areCharsCountEqual(chars.in.test, chars.in.original)
31 | };
--------------------------------------------------------------------------------
/5. Tasks/codewars/7 kyu/9. Sum of odd numbers.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/55fd2d567d94ac3bc9000064
2 |
3 | const rowSumOddNumbers = n => n ** 3
4 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/1. Fake Binary.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Fake Binary
3 | *
4 | * Given a string of digits, you should replace any digit below 5 with '0' and any digit 5
5 | * and above with '1'. Return the resulting string.
6 | *
7 | * Note: input will never be an empty string
8 | */
9 |
10 | const fakeBin = (x) => {
11 | return x.split('').map(char => +char < 5 ? '0' : '1').join('')
12 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/10. Jehny's secret message.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/55225023e1be1ec8bc000390
2 |
3 | function greet(name){
4 | const greetName = name === 'Johnny' ? 'my love' : name;
5 |
6 | return `Hello, ${greetName}!`
7 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/11. Grasshopper - Check for factor.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/55cbc3586671f6aa070000fb
2 |
3 | function checkForFactor (base, factor) {
4 | return Number.isInteger(base / factor)
5 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/12. Do I get a bonus.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/56f6ad906b88de513f000d96/
2 |
3 | function bonusTime(salary, hasBonus) {
4 | const total = hasBonus ? salary * 10 : salary
5 | return `£${total}`
6 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/13. Find multiplies of a number.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/58ca658cc0d6401f2700045f
2 |
3 | function findMultiples(integer, limit) {
4 | const multiplies = []
5 | let multiply = integer
6 |
7 | while (multiply <= limit) {
8 | multiplies.push(multiply)
9 | multiply += integer;
10 | }
11 |
12 | return multiplies
13 | }
14 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/14. Is it a palindrome.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/57a1fd2ce298a731b20006a4
2 |
3 | function isPalindrome(x) {
4 | for (let i = 0; i < x.length / 2; i++) {
5 | if (x[i].toLowerCase() !== x[x.length - 1 - i].toLowerCase()) return false
6 | }
7 |
8 | return true
9 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/15. Get nth even number.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5933a1f8552bc2750a0000ed
2 |
3 | function nthEven(n){
4 | return (n - 1) * 2
5 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/16. Opposites attract.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/555086d53eac039a2a000083
2 |
3 | function lovefunc(flower1, flower2){
4 | return (flower1 % 2 == 0 && flower2 % 2 !== 0) || (flower1 % 2 !== 0 && flower2 % 2 === 0)
5 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/17. Stringy string.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/563b74ddd19a3ad462000054
2 |
3 | function stringy(size) {
4 | const result = '10'.repeat(Math.ceil(size / 2))
5 |
6 | return size % 2 === 0
7 | ? result
8 | : result.slice(0, -1)
9 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/18. Welcome!.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/577ff15ad648a14b780000e7
2 |
3 | function greet(language) {
4 | const i18n = {
5 | english: 'Welcome',
6 | czech: 'Vitejte',
7 | danish: 'Velkomst',
8 | dutch: 'Welkom',
9 | estonian: 'Tere tulemast',
10 | finnish: 'Tervetuloa',
11 | flemish: 'Welgekomen',
12 | french: 'Bienvenue',
13 | german: 'Willkommen',
14 | irish: 'Failte',
15 | italian: 'Benvenuto',
16 | latvian: 'Gaidits',
17 | lithuanian: 'Laukiamas',
18 | polish: 'Witamy',
19 | spanish: 'Bienvenido',
20 | swedish: 'Valkommen',
21 | welsh: 'Croeso'
22 | }
23 |
24 | return i18n[language] || i18n.english
25 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/19. N-th Power.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/57d814e4950d8489720008db
2 |
3 | function index(array, n){
4 | const element = array[n]
5 |
6 | if (element === undefined) {
7 | return -1;
8 | }
9 |
10 | return element ** n;
11 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/2. DNA to RNA conversion.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/5556282156230d0e5e000089/javascript
3 | */
4 |
5 | function DNAtoRNA(dna) {
6 | const mapping = {
7 | 'T': 'U',
8 | 'U': 'T',
9 | }
10 |
11 | return dna.replace(/T|U/g, (char) => mapping[char] || char)
12 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/20. FIXME: Replace all dots.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/596c6eb85b0f515834000049
2 |
3 | const replaceDots = function(str) {
4 | return str.replace(/\./g, '-');
5 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/21. The Feast of many Beasts.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5aa736a455f906981800360d
2 |
3 | function feast(beast, dish) {
4 | return beast[0] + beast[beast.length - 1] === dish[0] + dish[dish.length - 1]
5 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/22. No zeros for heros.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/570a6a46455d08ff8d001002
2 |
3 | function noBoringZeros(n) {
4 | if (n === 0) return n
5 |
6 | return +String(n).replace(/[0]+$/g, '')
7 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/23. Double char.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/56b1f01c247c01db92000076
2 |
3 | function doubleChar(str) {
4 | return str.split('').map(char => char.repeat(2)).join('')
5 | }
6 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/24. Find the position!.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5808e2006b65bff35500008f
2 |
3 | function position(letter) {
4 | const UTF_16_OFFSET = 96
5 | const letterPosition = letter.toLowerCase().charCodeAt() - UTF_16_OFFSET
6 |
7 | return `Position of alphabet: ${letterPosition}`
8 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/25. Twice as old.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5b853229cfde412a470000d0
2 |
3 | function twiceAsOld(dadYearsOld, sonYearsOld) {
4 | const diff = dadYearsOld - sonYearsOld
5 | return Math.abs(sonYearsOld - diff)
6 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/26. Make negative.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/55685cd7ad70877c23000102
2 |
3 | function makeNegative(num) {
4 | return -Math.abs(num)
5 | }
6 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/27. Capitalization and Mutability.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/595970246c9b8fa0a8000086
2 |
3 | function capitalizeWord(word) {
4 | word = word[0].toUpperCase() + word.slice(1);
5 | return word;
6 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/28. Reverse list order.js:
--------------------------------------------------------------------------------
1 | function reverseList(list) {
2 | return [...list].reverse()
3 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/29. Alternating case.js:
--------------------------------------------------------------------------------
1 | String.prototype.toAlternatingCase = function () {
2 | return this.replace(/\w/g, (char) => char.toUpperCase() === char ? char.toLowerCase() : char.toUpperCase())
3 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/3. Leonardo Dicaprio and Oscars.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/56d49587df52101de70011e4
3 | */
4 |
5 | function leo(oscar){
6 | if (oscar === 88) return 'Leo finally won the oscar! Leo is happy'
7 | if (oscar === 86) return 'Not even for Wolf of wallstreet?!'
8 | if (oscar < 88) return 'When will you give Leo an Oscar?'
9 |
10 | return 'Leo got one already!'
11 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/30. Remove duplicates from list.js:
--------------------------------------------------------------------------------
1 | function distinct(a) {
2 | return [...new Set(a)];
3 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/31. Alan Partridge II - Apple Turnover.js:
--------------------------------------------------------------------------------
1 | function apple(x){
2 | return x ** 2 > 1000
3 | ? `It's hotter than the sun!!`
4 | : 'Help yourself to a honeycomb Yorkie for the glovebox.'
5 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/32. Regular Ball Super Ball.js:
--------------------------------------------------------------------------------
1 | var Ball = function(ballType = 'regular') {
2 | this.ballType = ballType
3 | };
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/33. Grasshopper - Array Mean.js:
--------------------------------------------------------------------------------
1 | var findAverage = function (nums) {
2 | return nums.reduce((acc, cur) => acc + cur, 0) / nums.length
3 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/4. What is between.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/55ecd718f46fba02e5000029/javascript
3 | * Complete the function that takes two integers (a, b, where a < b) and return an array
4 | * of all integers between the input parameters, including them.
5 | */
6 |
7 | function between(from, to) {
8 | const length = to - from + 1
9 |
10 | return Array.from({ length }, (_, i) => i + from)
11 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/5. Training on Squash the bugs.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/56f173a35b91399a05000cb7
3 | */
4 |
5 | function findLongest(str) {
6 |
7 | var spl = str.split(" ");
8 | var longest = 0
9 |
10 | for (var i = 0; i < spl.length; i++) {
11 | if (spl[i].length > longest) {
12 | longest = spl[i].length
13 | }
14 | }
15 |
16 | return longest
17 | }
18 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/6. Exclamation marks series #2: Remove all exclamation marks from the end of sentence.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://www.codewars.com/kata/57faece99610ced690000165/javascript
3 | */
4 | function remove (string) {
5 | return string.replace(/[\!]+$/gi, '')
6 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/7. Basic Variable Assignment.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/50ee6b0bdeab583673000025
2 |
3 | const a = 'code'
4 | const b = 'wa.rs'
5 | const name = a + b
6 |
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/8. Potenciation.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/59fc72fe235f93838b002235
2 |
3 | function power(x,y){
4 | return x ** y
5 | }
--------------------------------------------------------------------------------
/5. Tasks/codewars/8 kyu/9. Student's final grade.js:
--------------------------------------------------------------------------------
1 | // https://www.codewars.com/kata/5ad0d8356165e63c140014d4
2 |
3 | function finalGrade (exam, projects) {
4 | if (exam > 90 || projects > 10) return 100
5 | if (exam > 75 && projects >= 5) return 90
6 | if (exam > 50 && projects >= 2) return 75
7 |
8 | return 0
9 | }
--------------------------------------------------------------------------------
/5. Tasks/leetcode/easy/0383. Ransom Note.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://leetcode.com/problems/ransom-note/
3 | * @param {string} ransomNote
4 | * @param {string} magazine
5 | * @return {boolean}
6 | */
7 | const canConstruct = (ransomNote, magazine) => {
8 | const countByChar = (acc, cur) => {
9 | acc[cur] = (acc[cur] || 0) + 1
10 | return acc
11 | }
12 |
13 | const countCharIn = {
14 | ransomNote: ransomNote.split('').reduce(countByChar, {}),
15 | magazine: magazine.split('').reduce(countByChar, {})
16 | }
17 |
18 | for (const key in countCharIn.ransomNote) {
19 | const count = {
20 | ransom: countCharIn.ransomNote[key],
21 | magazine: countCharIn.magazine[key]
22 | }
23 |
24 | if ((count.magazine || 0) - count.ransom < 0) {
25 | return false
26 | }
27 | }
28 |
29 | return true
30 | };
--------------------------------------------------------------------------------
/5. Tasks/leetcode/easy/0412. Fizz Buzz.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://leetcode.com/problems/fizz-buzz/
3 | * @param {number} n
4 | * @return {string[]}
5 | */
6 | const fizzBuzz = function(n) {
7 | return Array.from({ length: n }, (_, i) => {
8 | const num = i + 1;
9 |
10 | if (num % 3 === 0 && num % 5 === 0) return "FizzBuzz"
11 | if (num % 3 === 0) return "Fizz"
12 | if (num % 5 === 0) return "Buzz"
13 |
14 | return String(num)
15 | })
16 | };
--------------------------------------------------------------------------------
/5. Tasks/leetcode/easy/0724. Find Pivot Index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://leetcode.com/problems/find-pivot-index
3 | * @param {number[]} nums
4 | * @return {number}
5 | */
6 | const pivotIndex = (nums) => {
7 | let leftSum = 0
8 | let rightSum = nums.reduce((acc, cur) => acc + cur, 0)
9 |
10 | for (let i = 0; i < nums.length; i++) {
11 | const prev = nums[i - 1] || 0
12 | const current = nums[i]
13 |
14 | leftSum += prev;
15 | rightSum -= current;
16 |
17 | if (leftSum === rightSum) {
18 | return i
19 | }
20 | }
21 |
22 | return -1
23 | };
--------------------------------------------------------------------------------
/5. Tasks/leetcode/easy/1342. Number of steps to reduce a number to zero.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://leetcode.com/problems/number-of-steps-to-reduce-a-number-to-zero/
3 | * @param {number} num
4 | * @return {number}
5 | */
6 | const numberOfSteps = function(num) {
7 | let steps = 0;
8 |
9 | while (num > 0) {
10 | if (num % 2 === 1) {
11 | num -= 1;
12 | steps++;
13 | }
14 |
15 | if (num) {
16 | num /= 2;
17 | steps++;
18 | }
19 | }
20 |
21 | return steps;
22 | };
--------------------------------------------------------------------------------
/5. Tasks/leetcode/easy/1480. Running sum of 1d array.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://leetcode.com/problems/running-sum-of-1d-array
3 | * @param {number[]} nums
4 | * @return {number[]}
5 | */
6 | const runningSum = function(nums) {
7 | let lastSum = 0
8 |
9 | return nums.map(num => {
10 | lastSum += num
11 | return lastSum
12 | })
13 | };
--------------------------------------------------------------------------------
/5. Tasks/leetcode/easy/1672. Richest Customer Wealth.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://leetcode.com/problems/richest-customer-wealth/
3 | * @param {number[][]} accounts
4 | * @return {number|null}
5 | */
6 | const maximumWealth = function(accounts) {
7 | let maxWealth = null
8 |
9 | for (const account of accounts) {
10 | const sum = account.reduce((sum, bankWealth) => sum + bankWealth, 0)
11 | maxWealth = Math.max(maxWealth, sum)
12 | }
13 |
14 | return maxWealth
15 | };
--------------------------------------------------------------------------------
/5. Tasks/leetcode/easy/2235. Add two integers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * https://leetcode.com/problems/add-two-integers
3 | * @param {number} num1
4 | * @param {number} num2
5 | * @return {number}
6 | */
7 | function sum(num1, num2) {
8 | return num1 + num2;
9 | }
--------------------------------------------------------------------------------
/5. Tasks/other/2. Sum curry/2-sum-curry.js:
--------------------------------------------------------------------------------
1 | const sum = (initialNum) => {
2 | let result = 0
3 |
4 | const wrapper = function(num) {
5 | if (typeof num === 'undefined') return result
6 |
7 | result += num
8 |
9 | return wrapper
10 | }
11 |
12 | return wrapper(initialNum)
13 | }
14 |
15 | module.exports = sum
16 |
--------------------------------------------------------------------------------
/5. Tasks/other/2. Sum curry/2-sum-curry.spec.js:
--------------------------------------------------------------------------------
1 | const sum = require('./2-sum-curry')
2 |
3 | describe('sum-curry', () => {
4 | it('sum(1)() should be 1', () => {
5 | expect(sum(1)()).toBe(1)
6 | })
7 |
8 | it('sum(1)(2)() should be 3', () => {
9 | expect(sum(1)(2)()).toBe(3)
10 | })
11 |
12 | it('sum(1)(2)(-1)() should be 2', () => {
13 | expect(sum(1)(2)(-1)()).toBe(2)
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/5. Tasks/other/3. Parallel/3-parallel.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Есть недописаная функция "parallel(funcArray, doneAll)":
3 | *
4 | * Нужно её дописать.
5 | * Что-то вроде аналога promise.all. И не забудьте, что результирующий массив должен сохранять тот порядок, в котором передавались функции.
6 | */
7 |
8 | function parallel(funcArray, doneAll) {
9 | const unresolved = Symbol('unresolved')
10 | const funcResults = Array.from({ length: funcArray.length }, () => unresolved)
11 |
12 | function done(idx, result) {
13 | funcResults[idx] = result
14 |
15 | if (funcResults.every(res => res !== unresolved)) {
16 | doneAll(funcResults)
17 | }
18 | }
19 |
20 | funcArray.forEach((fn, idx) => {
21 | fn.call(null, done.bind(null, idx))
22 | })
23 | }
24 |
25 | module.exports = parallel
26 |
--------------------------------------------------------------------------------
/5. Tasks/other/4. Fold/4-fold.js:
--------------------------------------------------------------------------------
1 | const fold = (str) => str.replaceAll(/(.)\1{1,}/g, (r) => r[0] + r.length)
2 |
3 | module.exports = fold
--------------------------------------------------------------------------------
/5. Tasks/other/4. Fold/4-fold.spec.js:
--------------------------------------------------------------------------------
1 | const fold = require('./4-fold')
2 |
3 | describe('fold', () => {
4 | describe('should fold string with numbers for repeated chars', () => {
5 | const cases = [
6 | ['aabbcd', 'a2b2cd'],
7 | ['maxxxpro', 'max3pro']
8 | ];
9 |
10 | cases.forEach(([input, output]) => {
11 | it(`Case "${input}" should be ${output}`, () => {
12 | const result = fold(input);
13 |
14 | expect(result).toBe(output);
15 | })
16 | })
17 | })
18 | })
19 |
--------------------------------------------------------------------------------
/5. Tasks/other/5. Rectangle to squares/5-rectangle-to-squares.js:
--------------------------------------------------------------------------------
1 | function rectangleToSquares(width, height) {
2 | while (true) {
3 | if (width < height) height -= width
4 | if (width > height) width -= height
5 | if (width === height) break
6 | }
7 |
8 | return width;
9 | }
10 |
11 | const AREA_WIDTH = 1680
12 | const AREA_HEIGHT = 640
13 |
14 | const size = rectangleToSquares(AREA_WIDTH, AREA_HEIGHT)
15 | const count = (AREA_WIDTH * AREA_HEIGHT) / size ** 2
--------------------------------------------------------------------------------
/6. Algorithms/1. Binary Search.js:
--------------------------------------------------------------------------------
1 | function binary_search(arr, item) {
2 | let from = 0;
3 | let to = arr.length - 1;
4 |
5 | while (from <= to) {
6 | const idx = Math.floor((from + to) / 2)
7 | const candidate = arr[idx]
8 |
9 | if (candidate === item) {
10 | return idx
11 | }
12 |
13 | if (candidate > item) {
14 | to = idx - 1
15 | } else {
16 | from = idx + 1
17 | }
18 | }
19 |
20 | return null
21 | }
--------------------------------------------------------------------------------
/6. Algorithms/sort/1-quick-sort.js:
--------------------------------------------------------------------------------
1 | function quickSort(arr) {
2 | if (arr.length <= 1) return arr;
3 | if (arr.length === 2) return arr[0] <= arr[1]
4 | ? [arr[0], arr[1]]
5 | : [arr[1], arr[0]]
6 |
7 | const reference = arr[0]
8 |
9 | const left = []
10 | const right = []
11 |
12 | for (let i = 1; i < arr.length; i++) {
13 | if (arr[i] <= reference) left.push(arr[i])
14 | else right.push(arr[i])
15 | }
16 |
17 | return [...quickSort(left), reference, ...quickSort(right)]
18 | }
--------------------------------------------------------------------------------
/7. Books/Clean code (Robert Martin)/README.md:
--------------------------------------------------------------------------------
1 | # Чистый код (Роберт Мартин)
2 |
3 | Это краткий конспект книги "Чистый код" написанной Робертом Мартином.
4 |
5 | ## Навигация
6 |
7 | - [Глава 1. Чистый код](./1.%20Clean%20code.md)
8 | - [Глава 2. Содержательные имена](./2.%20Meaningful%20names.md)
--------------------------------------------------------------------------------
/9. Courses/1. JS Introduction to OOP/Arrow functions context/collection.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | // BEGIN (write your solution here)
4 | export default function each(arr, callback) {
5 | return arr.forEach((element, i, array) => callback.apply(element, [element, i, array]));
6 | }
7 | // END
8 |
--------------------------------------------------------------------------------
/9. Courses/1. JS Introduction to OOP/Bind/bind.js:
--------------------------------------------------------------------------------
1 | export default function bind(obj, fn) {
2 | return function(...args) {
3 | const key = Symbol('Key');
4 | obj[key] = fn;
5 |
6 | const result = obj[key](...args);
7 | delete obj[key];
8 |
9 | return result;
10 | }
11 | }
--------------------------------------------------------------------------------
/9. Courses/1. JS Introduction to OOP/Boxing/magic.js:
--------------------------------------------------------------------------------
1 | // BEGIN
2 | const f = (...numbers) => {
3 | const sum = numbers.reduce((acc, x) => (x + acc), 0);
4 | const inner = (...rest) => f(sum, ...rest);
5 | // функции - это объекты, что позволяет для "магического" метода установить свою функцию
6 | inner.valueOf = () => sum; // метод вызывается при сравнении, поэтому он возвращает только результат
7 | // подробнее о valueOf: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf
8 | return inner;
9 | };
10 |
11 | export default f;
12 | // END
--------------------------------------------------------------------------------
/9. Courses/1. JS Introduction to OOP/Constructor/Point.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | // BEGIN (write your solution here)
4 | export default class Point {
5 | #x = null;
6 |
7 | #y = null;
8 |
9 | constructor(x, y) {
10 | this.#x = x;
11 | this.#y = y;
12 | }
13 |
14 | getX() {
15 | return this.#x;
16 | }
17 |
18 | getY() {
19 | return this.#y;
20 | }
21 | }
22 | // END
23 |
--------------------------------------------------------------------------------
/9. Courses/1. JS Introduction to OOP/Constructor/Segment.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | // BEGIN (write your solution here)
4 | export default class Segment {
5 | #beginPoint = null;
6 |
7 | #endPoint = null;
8 |
9 | constructor(beginPoint, endPoint) {
10 | this.#beginPoint = beginPoint;
11 | this.#endPoint = endPoint;
12 | }
13 |
14 | getBeginPoint() {
15 | return this.#beginPoint;
16 | }
17 |
18 | getEndPoint() {
19 | return this.#endPoint;
20 | }
21 | }
22 | // END
23 |
--------------------------------------------------------------------------------
/9. Courses/1. JS Introduction to OOP/Constructor/solution.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | import Point from './Point.js';
4 | import Segment from './Segment.js';
5 |
6 | // BEGIN (write your solution here)
7 | export default function reverse(segment) {
8 | const beginPoint = segment.getBeginPoint();
9 | const endPoint = segment.getEndPoint();
10 |
11 | return new Segment(
12 | new Point(endPoint.getX(), endPoint.getY()),
13 | new Point(beginPoint.getX(), beginPoint.getY()),
14 | );
15 | }
16 | // END
17 |
--------------------------------------------------------------------------------
/9. Courses/1. JS Introduction to OOP/Encapsulation/getMutualFriends.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | /* eslint-disable import/prefer-default-export */
3 |
4 | // BEGIN (write your solution here)
5 | export function getMutualFriends(user1, user2) {
6 | const friendsFrom = {
7 | user1: {
8 | flat: user1.getFriends(),
9 | groupedBy: {
10 | id: null,
11 | },
12 | },
13 | user2: {
14 | flat: user2.getFriends(),
15 | groupedBy: {
16 | id: null,
17 | },
18 | },
19 | };
20 |
21 | friendsFrom.user1.groupedBy.id = friendsFrom.user1.flat.reduce((group, user) => ({
22 | ...group,
23 | [user.id]: user,
24 | }), {});
25 |
26 | return friendsFrom.user2.flat.filter((friend) => {
27 | return Boolean(friendsFrom.user1.groupedBy.id[friend.id]);
28 | });
29 | }
30 | // END
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Конспекты learn.javascript.ru
2 |
3 | - В данном репозитории я стараюсь объяснить пройденную тему самостоятельно.
4 | - Необходим для самостоятельного обучения.
5 | - Материалы взяты с сайтов:
6 | - https://learn.javascript.ru/.
7 | - https://developer.mozilla.org/ru/docs/Web/JavaScript
8 | - https://ru.wikipedia.org/
9 | - https://habr.com/
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "learn-javascript-ru",
3 | "version": "1",
4 | "description": "- В данном репозитории я стараюсь объяснить пройденную тему самостоятельно. - Необходим для самостоятельного обучения. - Материалы взяты с сайтов: - https://learn.javascript.ru/. - https://developer.mozilla.org/ru/docs/Web/JavaScript - https://ru.wikipedia.org/ - https://habr.com/",
5 | "repository": {
6 | "type": "git",
7 | "url": "git+https://github.com/meowto16/learn-javascript-ru.git"
8 | },
9 | "homepage": "https://github.com/meowto16/learn-javascript-ru#readme",
10 | "devDependencies": {
11 | "jest": "^27.4.5"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------