Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Я хочу получать рассылки с лучшими постами за неделю
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
Создавая аккаунт, я соглашаюсь с правилами Пикабу и даю согласие на обработку персональных данных.
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр
Пройдите все испытания в игре кальмара второго сезона

Игра в кальмара 2: новые испытания

Аркады, Казуальные, Для мальчиков

Играть

Топ прошлой недели

  • AlexKud AlexKud 38 постов
  • SergeyKorsun SergeyKorsun 12 постов
  • SupportHuaport SupportHuaport 5 постов
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

Нажимая кнопку «Подписаться на рассылку», я соглашаюсь с Правилами Пикабу и даю согласие на обработку персональных данных.

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня

IT + Web-программирование

С этим тегом используют

Программирование IT юмор Программист Юмор Работа Картинка с текстом Разработка Web Javascript Веб-разработка HTML Все
236 постов сначала свежее
Web.Study
Web.Study
2 года назад

Promise API в Javascript⁠⁠

Объект Promise (промис) используется для отложенных и асинхронных вычислений.


Синтаксис


new Promise(executor);

new Promise(function(resolve, reject) { ... });


Параметры


executor

Объект функции с двумя аргументами resolve и reject. Функция executor получает оба аргумента и выполняется сразу, еще до того как конструктор вернет созданный объект. Первый аргумент (resolve) вызывает успешное исполнение промиса, второй (reject) отклоняет его. Обычно функция executor описывает выполнение какой-то асинхронной работы, по завершении которой необходимо вызвать функцию resolve или reject. Обратите внимание, что возвращаемое значение функции executor игнорируется.



Наш канал

[моё] Программирование IT Javascript Web-программирование Web Веб-разработка Текст
3
2
SaintPbroo
2 года назад

Помогите найти наставника по web разработке⁠⁠

Если есть тут человек который может помогать, может и не бесплатно (не дорого) отвечать на мои вопросы? (Вопросов не много)
В данный момент я не могу найти ответ на вопросы: что мне нужно знать что бы делать без проблем 1-3 страничные сайты, но с возвозможностью их редактирования обычным пользователем?(Это общий вопрос)
По сути я хочу научиться самостоятельно создавать админ панель для сайта с возможностью редактирования контента!
По пути моего изучения я сталкиваюсь с вопросами на поиск ответов которых трачу очень много времени! Да и приходят время от времени мысли, что я не в том поле копаю и цель от меня уходит ещё дальше) мой ТГ @MixaSpb93 вдруг кто откликнется!)

[моё] IT Web-программирование Программирование Помощь PHP HTML Текст
13
20
Web.Study
Web.Study
2 года назад
Web-технологии

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами⁠⁠

Так как тема прошлого поста про рекурсию был сложноватой для новичков, я решил залупить цикл публикаций о самой алгоритмизации. При этом попытаюсь разжевать все понятнейшим языком, чтобы джун смог с нуля всё понять.

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

И кстати, мы здесь рассказываем не только про алгоритмы и банально, там нас будет удобнее читать



Зачем мне алгоритмы? Я фронтендер!


Вы наверняка задумались: «А зачем мне нужно тратить своё время на изучение этих сложных алгоритмов, если я работаю с фронтендом? Как знание графов и бинарных деревьев поможет мне лучше отцентровать одну div-ку внутри другой div-ки?»


Многие веб-разработчики на таких форумах, как Reddit и Stack Overflow, отмечали, что, освоив даже на базовом уровне эти фундаментальные основы программирования, чувствовали себя увереннее, профессиональнее и писали более чистый и структурированный код.


Также это помогло им прокачать главный скилл разработчика – умение логически думать и решать сложные технические задачи.


Кстати, именно по этой причине многие крупные IT-компании требуют от своих потенциальных сотрудников знания фундаментальных основ computer science, к которым как раз относятся алгоримты и структуры данных, и с пристрастием спрашивают их на собеседованиях (даже на позицию фронтенд-разработчика!).



Что такое алгоритмы и структуры данных


Алгоритм — это совокупность последовательных операций, направленных на решение определенной задачи.


Структуры данных — это особый способ организации и хранения данных в компьютере, который обеспечивает эффективный доступ к этим данным и их изменение. Для оценки сложности и скорости работы алгоритма используют так называемую «О-нотацию» или «О-большое».


Эта запись имеет вид O(n), где n – это количество операций, которое предстоит выполнить алгоритму. Важное замечание: O(n) всегда описывает худший возможный случай выполнения алгоритма. Это дает нам гарантию, что наш алгоритм никогда не будет работать медленнее O(n).


Скорость работы алгоритмов измеряется не в секундах, а в темпе роста количества операций. Т.е. нас интересует, насколько быстро возрастает время выполнения алгоритма с увеличением размера входных данных.


Вот так выглядит время работы некоторых алгоритмов:


O(1) – константное время. Например, чтение данных из ячейки в массиве.


O(log n) – логарифмическое время. Например, бинарный поиск.


O(n) – линейное время. Например, поиск наименьшего или наибольшего элемента в неотсортированном массиве.


O(n * log n) – линейно-логарифмическое время. Например, быстрая сортировка.


O(n2) – квадратичное время. Например, сортировка пузырьком.


O(n!) – факториальное время. Например, решение задачи коммивояжера полным перебором.



Алгоритм линейного поиска


Давайте для начала рассмотрим такой простейший алгоритм, как линейный поиск элемента в массиве, и реализуем его на JavaScript.

Итак, есть массив чисел, и нам нужно найти в нем конкретное число.

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

Создадим функцию линейного поиска и назовем ее linearSearch. Эта функция будет принимать в себя два параметра: array (т.е. сам массив элементов, в котором ведется поиск) и item (элемент, который мы ищем в этом массиве).

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

Линейный поиск происходит достаточно предсказуемо: мы используем цикл for, в котором пробегаемся по элементам массива и сравниваем каждый элемент с искомым.

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

Далее инициализируем счётчик и установим его исходное значение, которое будет равно нулю, так как мы собираемся проверять массив с самого первого элемента.

let i = 0;
Наш цикл будет выполняться до тех пор, пока не пройдет по всем элементам массива. В качестве конечной точки мы используем значение array.length, которое возвращает количество элементов в массиве. Так как массив array начинается с нулевого индекса, то мы используем при сравнении знак «<».

i < array.length;

После каждой итерации цикла увеличиваем значение переменной i на единицу.

i++

Далее с помощью условной конструкции if будем проверять на истинность одно условие. Данная проверка будет выполняться при каждой итерации цикла, но код внутри нее сработает только один раз, после чего функция завершится.


Здесь мы сравниваем каждый элемент массива (array[i]) c искомым элементом (item) и, если эти элементы совпадают, то возвращаем i (индекс массива, по которому находится этот искомый элемент item).

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

Если же искомый элемент не был найден, то по завершении работы цикла мы возвращаем -1.

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

Дальше нам остается только вызвать функцию linearSearch, первым параметром передать в нее массив элементов, а вторым параметром — искомое число.


Затем, с помощью функции console.log, выводим результат в консоль.

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

Как видите, алгоритм линейного поиска довольно прост в реализации. Сложность данного алгоритма: линейное время или O(n).


Давайте теперь рассмотрим более сложный и интересный алгоритм, который еще называют алгоритмом бинарного поиска.



Алгоритм бинарного поиска


Бинарный (или двоичный) поиск — это алгоритм, при котором массив данных будет последовательно делиться пополам до тех пор, пока не будет обнаружен искомый элемент.


Важное замечание: данный алгоритм будет работать только для отсортированного массива.


Бинарный поиск может быть реализован следующим образом:


0. Берём исходный массив отсортированных данных (например, по возрастанию).

1. Делим его на две части и находим середину.

2. Сравниваем элемент в середине с искомым элементом.

3. Если искомое число меньше этого центрального элемента — продолжаем искать элемент в левой части массива. Для этого мы делим левую часть массива на 2 части. Если искомый элемент больше центрального элемента, то мы отбрасываем левую часть массива и продолжаем поиск в правой.


И повторяем данную процедуру до тех пор, пока не найдем искомый элемент. Как только мы его нашли, то возвращаем индекс в массиве, по которому он находится. Если же данный элемент не будет найден, то возвращаем -1.


Давайте сначала взглянем на реализацию данного алгоритма, а потом разберем ее детально.

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

Итак, у нас есть массив чисел arr, отсортированный по возрастанию. Как вы помните, если заранее не отсортировать массив, то бинарный поиск не будет работать.

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

Создаем функцию binarySearch и передаем в нее два параметра: отсортированный массив arr и искомый элемент value.

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

Затем определяем следующие переменные:

let start = 0;

Так как мы должны найти центральный элемент, то сначала необходимо определить начальный и конечный элементы.


Задаем таким образом начальный элемент и устанавливаем его значение равным нулю, так как наш массив начинается с нулевого индекса.

let end = arr.length - 1;

Затем определяем конечный элемент. Его позиция будет вычисляться по длине массива arr.length - 1.


Далее мы создадим цикл while, который будет работать до тех пор, пока начальная и конечная позиция массива не сравняются (start <= end).

let middle;

Внутри цикла мы будем высчитывать позицию центрального элемента в массиве и сохранять ее в переменную middle. Для этого мы складываем начальную позицию с конечной и делим результат на две части.


Результат обернем в функцию Math.floor(), так как в результате деления у нас может получиться дробное число. С помощью данной функции мы округляем полученное число до нижней границы.

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

Далее с помощью условной конструкции if создаем проверку: если центральный элемент в массиве по индексу middle равен искомому элементу, то мы возвращаем индекс найденного элемента, сохраненный в переменной middle. И на этом наша функция завершает свою работу.

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

Если на данной итерации цикла мы не нашли искомый элемент, то необходимо выполнить еще одну проверку с помощью условной конструкции if. Если искомый элемент меньше, чем элемент, находящийся в середине, то это значит, что нам нужно продолжить поиск в левой части массива, а правую можно отбросить.


Для этого нам нужно изменить значение переменной end. В итоге мы получим end = middle + 1. А в блоке else мы прописываем такое же условие, только для случая, если искомый элемент будет больше, чем элемент, находящийся в середине. Тогда мы отбрасываем левую часть массива и продолжаем поиск в правой.

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

После завершения цикла while возвращаем -1 на случай, если искомое число не будет найдено в массиве. Далее вызываем функцию binarySearch и передаем в нее два параметра: массив элементов и искомое число.


И выводим результат в консоль.

Это сложно, да и зачем мне алгоритмы? Я же фронтендер! Объясняем алгоритмизацию простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Мат, Длиннопост

Что касается оценки сложности приведенных алгоритмов: бинарный поиск эффективнее линейного, поскольку массив данных на каждом шаге разделяется надвое и одна половина сразу отбрасывается.


Последовательная сложность бинарного поиска в худшем и среднем случаях равна O(log n), в лучшем — O(1) (если обнаруживаем искомый элемент на первой итерации). Для сравнения: вычислительная сложность линейного поиска, как вы помните, равна O(n).



На этом мы закончили вторую статью из нашего цикла статей по алгоритмам. Спасибо за внимание.

Показать полностью 13
[моё] Программирование IT Полезное Алгоритм Рекурсия Javascript Web-программирование Web Веб-разработка Мат Длиннопост
6
19
Web.Study
Web.Study
2 года назад
Web-технологии

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами⁠⁠

Для многих разработчиков рекурсия кажется чем-то очень сложным и непонятным, но это только на первый взгляд. В этой статье мы разложим все по полочкам, чтобы вы в следующий раз не боялись этого страшного слова "рекурсия".


Мы узнаем, как устроена рекурсия, а также разберем алгоритм сортировки массива под названием Quick Sort или, как еще его называют, быстрая сортировка Хоара. Как вы уже догадались, этот алгоритм рекурсивный.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Читайте нас в телеграме, там мы каждый день выкладываем полезные материалы из вселенной Front-end



Перейдем к статье


Рекурсия


Рекурсия, если максимально упростить, это вызов функцией самой себя. Этот приём программирования можно использовать, когда есть возможность разбить задачу на несколько более простых подзадач. И, написав решение этой подзадачи в функции и вызывая такую функцию рекурсивно, мы можем все эти подзадачи итеративно решить.


Давайте взглянем на простой пример.


У нас есть простая функция обратного отсчёта:

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Данная функция принимает аргументом число n и выводит на экран числовую последовательность от n до 1 включительно, а в конце, после завершения работы цикла, выводит на экран слово «Финиш».


Давайте вызовем эту функцию, передав в нее число 3. В консоли мы получим следующий результат: «3 2 1 Финиш».

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Теперь перепишем эту функцию на рекурсивный манер:

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Разберемся, как эта функция работает. Первым делом, чтобы не получить бесконечный цикл вызовов функции и как результат ошибку «stack overflow», которая говорит нам о превышении лимита вызовов для функции в стеке, нужно определить так называемый базовый случай.


Базовый случай — это условие, при котором наша функция должна перестать вызывать саму себя рекурсивно.


Так как наш цикл работал до тех пор, пока i > 0, то здесь условие для прерывания цикла должно быть следующим:

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

То есть, как только n будет меньше или равно нулю, мы перестаем рекурсивно вызывать функцию и выходим из нее. Перед выполнением оператора return необходимо будет вызвать наш console.log('Финиш'), потому что именно это действие и будет последним в работе функции.


По сути, базовый случай работает как оператор break в циклах, то есть прерывает вызов функцией самой себя, чтобы мы могли вернуть результат ее выполнения.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Дальше мы выводим в консоль текущее значение числа n. И, следующим шагом, снова вызываем нашу функцию countDownRecursive() и передаем в нее n - 1.


Как вы помните, в примере с циклом for, на каждой итерации цикла мы уменьшали число i на единицу (i--), поэтому здесь, по аналогии, передаем n - 1.


Запустим функцию и получим в консоли следующий результат:

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Результат, как вы видите, аналогичен результату работы простой функции countDown.


Давайте теперь чуть подробнее разберём, как работает рекурсивная функция.



Как работает рекурсивная функция

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Итак, сначала мы вызываем функцию countDownRecursive со значением 3.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Базовый случай не отрабатывает, потому что n > 0. Мы выводим число 3 в консоль и дальше снова вызываем функцию, передав в нее n - 1, то есть 3 - 1 или просто число 2.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Повторяем эту процедуру, пока не дойдем до нуля:

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

И вот здесь уже срабатывает базовый случай. Так как 0 === 0, выводим в консоль слово «Финиш» и дальше срабатывает оператор return.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Дальше происходит завершение работы всех предыдущих функций (потому что неявно завершенная функция возвращает undefined, то есть как только выполнение нашей функции доходит до закрывающей фигурной скобки, происходит return undefined).


Здесь вы можете подумать, что это всё очень сложно, и почему бы не использовать такой понятный и простой цикл for?


Важно отметить, что, действительно, не везде нужно применять рекурсию. Но бывают задачи, где рекурсивное решение выглядет очень элегантно и занимает гораздо меньше строчек кода, чем с использованием традиционных циклов.


Давайте разберем один из таких примеров.



Числа Фибоначчи


Как вы знаете, ряд Фибоначчи — это числовая последовательность, первые два числа которой являются единицами, а каждое последующее за ними число является суммой двух предыдущих.


Автором данной числовой последовательности был Леонардо Пизанский (более известный под прозвищем Фибоначчи) из итальянского города Пизы — один из крупнейших математиков средневековой Европы.


Вот так ряд Фибоначчи выглядит на практике:

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Иногда перед первой единицей добавляют еще и ноль, но мы не будем рассматривать данный случай, а рассмотрим классический ряд Фибоначчи, как в средневековых книгах (но только без кроликов).


Наша задача — написать функцию, которой можно передать номер элемента ряда Фибоначчи, и на выходе из функции получить значение этого элемента.


Допустим, мы ищем 10-ый элемент в последовательности. Значением этого элемента будет 55. Для 12-го элемента значением будет 144 и так далее.


Вот так будет выглядеть эта функция, написанная с применением рекурсии:

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

В результате работы функции в консоли мы получим число 8. Можете это проверить: если вы посмотрите на ряд Фибоначчи выше, то увидите, что значением 6-го элемента в ряду будет число 8.


Давайте разберём, как работает данная функция.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Объявляем стрелочную функцию fibonachi, которая принимает аргументом число искомого элемента в ряду — n.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Далее определяем базовый случай, т.е. условие, при котором выходим из рекурсии.


Так как мы будем последовательно уменьшать число n (об этом ниже), то нет смысла делать это бесконечно.


Как только n оказывается меньше 2, то это значит, что мы достигли начала ряда Фибоначчи, а значит дальше нам двигаться не нужно и можно возвращать n обратно вызывающему коду.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Если же базовый случай не отработал, то снова вызываем функцию, передав в ее аргументы n - 1 и n - 2 соответственно, и складываем результат этих функций между собой по следующей формуле: F(n) = F(n - 1) + F(n - 2). Эта формула позволяет нам найти число из ряда Фибоначчи. Так как каждое число равно сумме двух предыдущих чисел в цепочке, то именно эту формулу мы реализовали в нашей функции.


Если вам до конца не понятно объяснение данного алгоритма, то, во-первых, это абсолютно нормально, а во-вторых, можете посмотреть подробное видео, объясняющее работу данной функции здесь.



Быстрая сортировка Хоара


А теперь рассмотрим более сложный алгоритм. Он называется быстрая сортировка (Quick Sort) или сортировка Хоара.


Данный алгоритм был разработан английским информатиком Тони Хоаром во время работы в МГУ в 1960 году.


И вот здесь как раз будет применяться рекурсия.


Как вы помните, в предыдущей статье мы с вами разбирали широко известный в узких кругах алгоритм — пузырьковую сортировку. Ее единственный недостаток — это крайне низкая эффективность. Быстрая же сортировка является улучшенной версией подобных алгоритмов сортировки с помощью прямого обмена.


Итак, в чем суть. Имеется неотсортированный массив чисел arr.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Наша задача написать функцию, которая будет принимать в себя аргументом этот массив и возвращать его полностью отсортированным по возрастанию.


Быстрая сортировка относится к алгоритмам из серии «разделяй и властвуй».


Небольшое отступление. Алгоритмы типа «разделяй и властвуй» (англ. divide and conquer) — это парадигма разработки алгоритмов, заключающаяся в рекурсивном разбиении решаемой задачи на две или более подзадачи того же типа, но меньшего размера, и комбинировании их решений для получения ответа к исходной задаче. Разбиения выполняются до тех пор, пока все подзадачи не окажутся элементарными.


Наш алгоритм будет сводиться к следующим шагам:


1. Выбираем элемент из массива и считаем его опорным (в англоязычной литературе его называют pivot).


2. Сортируем элементы в массиве таким образом, чтобы элементы меньше опорного размещались в подмассиве перед ним, а большие или равные — в подмассиве после.


3. Рекурсивно применяем первые два шага к двум подмассивам слева и справа от опорного элемента. Т.е. дробим наш массив на подмассивы и сортируем их относительно опорного элемента, пока в этих подмассивах не останется по одному элементу или меньше. Рекурсия не применяется к массиву, в котором только один элемент или отсутствуют элементы. Это как раз и будет базовым условием, при котором мы прервем рекурсию.


Вот здесь вы можете увидеть визуализацию работы быстрой сортировки (а также многих других алгоритмов).


А вот так выглядит реализация сортировки Хоара на JavaScript:

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Подробный разбор алгоритма сортировки Хоара


Давайте подробно разберём, как работает данная сортировка.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Создаем функцию quickSort() и передаем аргументом неотсортированный массив.


Дальше, как вы помните, необходимо определить базовый случай выхода из рекурсии.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Так как нам предстоит дробить основной массив на подмассивы и сортировать элементы в этих подмассивах относительно опорного элемента (об этом ниже), то как только такие подмассивы будут содержать по одному элементу или будут пустыми, нам нет смысла дальше продолжать разбивать их на более мелкие части, поэтому здесь мы выйдем из рекурсии.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Теперь определим индекс в массиве так называемого опорного элемента. Для этого создадим переменную pivotIndex, передадим в функцию Math.floor длину массива, поделим результат на 2 и получившееся число присвоим переменной pivotIndex. Функция Math.floor, как вы знаете, округляет результат в меньшую сторону:

Math.floor(5.5); // 5

Затем определим сам опорный элемент. Для этого кладем в переменную pivot значение массива по индексу pivotIndex. В массиве arr значением pivotIndex будет 5 (длина массива — 11. 11 делим на 2 и округляем в меньшую сторону, получаем 5). Значением pivot будет -12.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Дальше нужно объявить два пустых подмассива less и greater. В массив less будем сохранять все элементы, которые меньше опорного, а в greater все элементы, которые больше опорного.


Дальше в цикле for мы пробегаем по всем элементам массива и сравниваем каждый элемент с опорным.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Затем у нас идут три условия. В первом условии мы сравниваем индекс текущей итерации цикла с индексом опорного элемента в массиве.


Если они совпадают, то текущую итерацию цикла мы завершаем с помощью ключевого слова continue, так как нам не нужно добавлять опорный элемент в один из наших подмассивов.


Далее во втором условии мы сравниваем элемент массива с опорным элементом. Если опорный элемент больше, то добавляем наш текущий элемент массива в массив less.


В противном же случае, добавляем текущий элемент массива в массив greater (третье условие).


В итоге, после завершения цикла for, у нас на выходе будет 2 массива: less с числами меньше опорного и greater с числами больше опорного или равными ему.


И дальше мы возвращаем массив, в который разворачиваем результат рекурсивного выполнения функции, принимающей в качестве аргумента массив less. Дальше вставляем наш опорный элемент pivot, а после снова разворачиваем результат выполнения функции для массива greater.

Не так страшен черт, как его малюют. Объясняем рекурсию в Javascript простыми словами Программирование, IT, Полезное, Алгоритм, Рекурсия, Javascript, Web-программирование, Web, Веб-разработка, Длиннопост

Когда функция доходит до базового случая, рекурсивный вызов функции заканчивается и все одиночные массивы соединяются в один большой отсортированный массив.


Выведем в консоль результат работы функции и убедимся в этом.


Быстрая сортировка в среднем и лучшем случае выполняется за Θ(n * log(n)) и Ω(n * log(n)) соответственно.


В худшем случае время выполнения алгоритма занимает О(n^2).


Более подробно про лучшее, среднее и худшее время выполнения алгоритма быстрой сортировки можно прочитать здесь.



Спасибо тем, кто дочитал, пишите ваше мнение, вопросы и предложения в комментариях. Не забудьте поставить плюсик этому посту, если он вам понравился :3

Показать полностью 25
[моё] Программирование IT Полезное Алгоритм Рекурсия Javascript Web-программирование Web Веб-разработка Длиннопост
6
12
Web.Study
Web.Study
2 года назад
Web-технологии

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS⁠⁠

В последние пять лет в интерфейсном дизайне появилось понятие тёмной темы: это когда фон делают тёмным, а текст — светлым. Это полезно в телефонах для энергосбережения и чтения с экрана ночью. Ну и просто красиво.


Сегодня мы добавим на страницу переключатель тёмной и светлой темы с помощью CSS.


Не только про CSS, но и про другие штуки из области Front-end мы рассказываем тут

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS Программирование, IT, Программист, CSS, Frontend, Web-программирование, Веб-дизайн, Веб-разработка, Длиннопост

Автопереключение тёмной темы



Современные браузеры умеют определять, что на телефоне или компьютере включена тёмная тема. Для этого разработчики используют такой медиазапрос:


@Media screen and (prefers-color-scheme: dark) {}


Если на устройстве используется тёмная тема, то CSS выполнит всё, что написано в фигурных скобках. В нашем случае нам нужно сделать тёмный фон и светлый текст:

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS Программирование, IT, Программист, CSS, Frontend, Web-программирование, Веб-дизайн, Веб-разработка, Длиннопост

Добавим этот код в стили на странице, и задача решена: мы получили поддержку тёмной темы. Если в настройках устройства переключить тему обратно на светлую, то сайт тоже получит белый фон.


Посмотреть на автопереключение темы на странице проекта.



Ручное переключение темы


Медиазапросы — это хорошо, но иногда нужно поставить принудительный переключатель темы, чтобы не зависеть от настроек устройства. Например, если нужно отладить тёмную тему, когда у вас на компьютере работает светлая тема.


Чтобы не создавать с нуля страницу, поступим так: создадим копию главной страницы нашего учебного сайта и добавим туда переключатель, который заставит тему смениться.



Настраиваем стили


Единственное, что нам нужно добавить в стили — это два класса: для светлой и тёмной темы:

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS Программирование, IT, Программист, CSS, Frontend, Web-программирование, Веб-дизайн, Веб-разработка, Длиннопост

Первый класс устанавливает чёрный фон и белый цвет текста, а второй, наоборот, — белый фон и чёрный текст. Цвета здесь можно указывать любые и для любых элементов, а мы для простоты остановимся на двух.


Внешне страница никак не поменяется — мы ещё не применили эти стили. Чтобы это сделать, надо поработать с остальными элементами, например добавить id к тегу <body> — по нему мы будем обращаться к содержимому всей страницы:

<body id="main">

Добавляем переключатель


Чтобы мы могли менять светлую тему на тёмную и обратно, добавим простой переключатель. Сделаем его в виде абзаца и добавим его сразу после строки поиска:

<p id="select" onclick="darkLight()" style="cursor: help;">Включить тёмную тему</p>

Вот что здесь происходит:


<p id="select» ← указываем id переключателя, чтобы потом получить доступ к нему из скрипта;


onclick="darkLight ()» ← говорим, что должно произойти при нажатии: вызываем функцию darkLight ();


style="cursor: help;»> ← меняем внешний вид курсора при наведении на переключатель;


Включить тёмную тему</p> ← текст надписи.


Переключатель появился на странице, но пока ничего не переключает. Исправим это в скрипте.

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS Программирование, IT, Программист, CSS, Frontend, Web-программирование, Веб-дизайн, Веб-разработка, Длиннопост

Пишем скрипт


Мы указали в свойствах переключателя, что при нажатии нужно выполнить функцию darkLight () — значит, нам нужно добавить её в рабочий скрипт.


Чтобы не зависеть от работы других скриптов и не лезть в их код, сделаем новый js-файл dark.js и положим в него такой код:

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS Программирование, IT, Программист, CSS, Frontend, Web-программирование, Веб-дизайн, Веб-разработка, Длиннопост

Последнее, что осталось сделать, — подключить скрипт в конце HTML-страницы:


<script type="text/javascript" src="dark.js"></script>


Теперь у нас появилась поддержка тёмной темы с моментальным переключением:

Мам, сейчас так модно. Добавляем темную тему на страницу с помощью CSS Программирование, IT, Программист, CSS, Frontend, Web-программирование, Веб-дизайн, Веб-разработка, Длиннопост

Посмотреть на работу переключателя на странице проекта.



Что дальше


Этот способ работает только на одной странице, и после перезагрузки тему нужно переключать заново. В следующий раз сделаем апгрейд — научим сайт запоминать настройки и применять их ко всему сайту. А ещё подружим автопереключение с надписью на переключателе.

Показать полностью 6
[моё] Программирование IT Программист CSS Frontend Web-программирование Веб-дизайн Веб-разработка Длиннопост
9
19
MaxSholts
2 года назад
Информационная безопасность IT

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал)⁠⁠

Это было сложно!.. Вот что можно сказать по итогу квеста от NoobGameDev. Нам удалось его пройти лишь спустя почти 3 недели. Механизм остановлен - кот спасён. А теперь поподробнее.


Это третий пост по данному квесту, поэтому сразу порекомендую ознакомиться с предыдущими: Часть 1, Часть 2. А так же с оригинальной новостью от автора.


В прошлой части мы остановились на том, что нашли в видео сообщение, зашифрованное азбукой Морзе, которое привело нас к странице с Коржиком из Улицы Сезам, который говорил "OMMM NOM NOM NOM".

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Мы так же нашли на странице форму ввода и куку "Monster" со значением: 0DF5B38B2D4B4BBEA13D626CA7C6D4A3366EB07F3C594C9179BE0D34F8832B36

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Спустя какое-то время, благодаря огромной подсказке на маркерной доске, мы поняли, что в куки находится сообщение в HEX формате, зашифрованное при помощи AES алгоритма, а фраза "OMMM NOM NOM NOM" оказалась 128-мибитным ключом.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

При дешифровке получалась строка в стандарте Base64: "dmVyeSBnb29kIGNvbXJhZGU=", которая, в свою очередь, при декодировании превратилась в строку "very good comrade". Именно эту фразу необходимо было ввести в поле ввода. После этого Коржик поздравлял нас и просил дать ему пятюню.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

После этого нас перенаправило на очередной сайт, с казалось бы просто чёрным фоном. И поначалу мы даже подумали, что что-то не подгрузилось или произошёл какой-то сбой. Но после того как мы забрались в код страницы, то поняли, что фоновое изображение залито не всплошную, а имеет вырезанные участки.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Если помните из предыдущей части мы восстановили обрезанный участок изображения с барбером и нашли страницу, очень сильно похожую на звёздное небо, поэтому решение этой задачи не заставило долго ждать - мы просто наложили вытащенный фон на карту неба и у нас остались лишь два созвездия: орла и льва. И после недолгих раздумий был подобран верный пароль - Грифон.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

После ввода пароля, на короткий промежуток времени появлялось очередное "именование" и... ничего не происходило. Но подождав какое-то время, проявлялось знаменитое изображение с Морихэем Уэсиба (создателем айкидо, которого ошибочно называют Конфуцием).

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Через пару минут нам удалось распознать и перевести текст, в котором упоминались: подсказки кудрявого и городского героя, а так же алгоритм и ключ, который можно спросить у лиса Клайда.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Кудрявыми подсказчиками были либо Шерлок, либо Цукерберг, городской герой - отрывок из мультфильма "Город героев", а вот с лисом Клайда был ступор. В добавок ко всему у русского языка есть удивительная способность к толкованию вне контекста... Поэтому мы пытались понять, кто именно нам нужен: Клайд у которого есть лис, либо лис по имени Клайд. В итоге каким-то чудом нам удалось узнать, что Клайд - это имя логотипа Дискорда, а перейдя на основной сервер организатора, мы нашли и лиса - Juniper Bot. И, спустя некоторое время перебора префиксов и команды, введя в канал сообщение "?key", мы получили ключ. При этом бот удалял верную команду и на пару секунд показывал нужный нам ключ.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Ключ был очередным набором цифр - 97294172474890016071804703


К этому времени на доске детектива уже становилось понятно, что вордовский документ - это не только штрих-код, и что непонятные наборы цифр в нём мы должны расшифровать используя другой непонятный набор цифр - ключ, который выдал бот.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Для решения этой загадки нам недоставало лишь алгоритма. Но к этому времени, один из участников сложил несколько фактов и у нас родилась новая версия. В показанном отрывке из фильма "Социальная сеть" говорилось о том, что алгоритм записан на окне спальни. И приглядевшись к изображению окна в сцене с котом мы обнаружили нечто похожее на записи.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

После этого возникла мысль покопаться в файлах игровой сцены. Не знаю почему мы не подумали об этом раньше. Необходимый файл с данными игры мы обнаружили в консоли https://noobgamedev.xyz/quest/Build/SaveCatGzip.data, и при помощи программы AssetStudioGUI извлекли ассеты из игры. Мы искали окно из скриншота, чтобы получше его рассмотреть, но при этом нашли и ключ, который, видимо, необходим для сейфа, потому что замочная скважина на нём требует загрузки изображения.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Но мы так же нашли и окно, на котором был нарисован алгоритм и написан сам метод (на C#), при помощи которого было зашифровано сообщение.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Один из участников довольно быстро в этом разобрался и написал метод декодирования. Однако при вставке всего текста или отдельной строки возникала ошибка. Но так как был реализован и метод кодирования, то мы обратили внимание на то, что между символами в определённом порядке расставляются "-": в начале строки после первых 2-х символов, а дальше через каждые 4 символа.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Немного преобразовав строки удалось получить вменяемый результат - каждая отдельная строка в расшифрованном виде представляла из себя один символ. И в итоге получилась ссылка: https://ngdquest.ru/xp7cpbxyqae026sf3ta3seaix4qn54h3k7wupc6xstxpac


При переходе по ней происходил редирект к изображению на Google Диске. И так как с изображениями в предыдущих частях мы уже сталкивались, то сперва проверили картинку в программе Stegsolve и обнаружили скрытую надпись "Silent Eye" - это программа для сокрытия данных в изображениях (с ней в квесте мы уже "работали"- она оставляет на картинке видные под фильтрами точки).

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Текст на картинке, в переводе с японского, означает "С днём рождения, самурай". После перевода этой фразы сомнения по поводу азбуки Морзе отпали автоматически - мы поняли, что это формат ввода даты для доступа к скрытой информации. Источник есть, программа есть, оставалось только выяснить дату, и так как на этот момент мы уже раздобыли намёк на Амидамару (духа самурая из аниме Shaman King), то мы узнали дату его рождения - 06.01.1385 г. Она и оказалась ключом.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

В результате мы получили сообщение "A2GD5DAW", которое напоминало все те "имена", которые мы находили ранее (поэтому мы записали и само "имя" и место, где его нашли).


К этому моменту, опираясь на доску детектива мы прошли уже все ветки - оставались только сейф и механизм.


В прошлой части я говорил, что мы нашли коды для Энигмы, которыми было зашифровано сообщение в первом дисплее механизма. Код менялся каждый день, и каждый день нам приходилось брутфорсить зашифрованные фразы (благо это были пословицы или поговорки на английском), потому что нам удавалось расшифровывать только первое слово в сообщении. Но мы продолжали изучать Энигму и в Википедии обнаружили пару абзацев, согласно которым, продолжительный период во время Войны, для повышения уровня безопасности, использовался следующий алгоритм: оператор брал установки на день из известного всем шифровальщикам списка, после этого выбирал любой код, который ему хотелось, прописывал его и менял положение роторов в соответствии с тремя первыми буквами введённого им слова, и основное сообщение зашифровывал уже по своему коду. В итоге получалось 2 слоя шифровки. Узнав этот факт, мы попробовали первые три буквы расшифрованных имён в качестве стартовой позиции роторов и таким образом научились расшифровывать и вторую часть сообщений. Но это всего лишь упростило ситуацию с первым дисплеем, но в целом ничего нового не принесло - по прежнему оставалось ещё 3 дисплея.


На листке, прикреплённом к механизму, подсказкой ко второму дисплею было слово "Congratuletions" (Поздравления), и так как мы совсем недавно поздравляли Амидамару с ДР, то догадались, что код, полученный из изображения торта ("A2GD5DAW"), являлся ключом для второго дисплея.


А вот подсказкой к третьему дисплею было "Сейф..." . Поэтому все остатки своих сил мы бросили на открытие сейфа, который без неожиданного упрощения, мы бы скорей всего до сих пор пытались бы открыть. Как я уже говорил в предыдущей части, основной сложностью сейфа являлся ввод сразу трёх ключей. И это при том, что мы не были уверены в каждом из них.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

В итоге автор, видимо, решил, что квест пора заканчивать и на маркерной доске появилось сообщение, согласно которому, преступник понизил уровень безопасности сейфа, для того чтобы перераспределить потребление мощности, в результате чего механизм начал работать быстрее. После этого сообщения мы обнаружили, что теперь с сейфом есть обратная связь - мы стали получать ответ на отправленные ключи в формате "0 no/yes no/yes no/yes". Это очень сильно упрощало нам задачу, вместо подбора сразу трёх верных ключей, мы могли сосредоточиться на каком-то одном и по по очереди подобрать все три. Этим мы и занялись.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Картинка ключа, которую мы достали из файлов игры сражу же дала нам один "yes" из трёх.


Следующим нам покорился лимбовый замок. По телевизору в сцене с котом очень часто проигрывался эпизод из фильма "Ограбление по итальянски", в котором героиня Шарлиз Терон взламывала как раз-таки сейф с подобным замком. Особо отважные участники квеста посмотрели фильм полностью и нашли данный фрагмент. Попытка монтажёра сделать из довольно скучной сцены динамичную вызывала проблемы с пониманием последовательности введённых чисел. Но на маркерной доске появилась ещё одна подсказка. Спустя время мы поняли что DUD - это Down Up Down, т.е. направление вращения колеса мышки. И, собрав в кучу все эти обрывки информации, спустя множество попыток подбора, нам удалось получить второй "yes" от сейфа. 7-17-51, такова верная комбинация для лимбового замка (до 7 по часовой, до 17 против часовой, и до 51 по часовой).

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Последним оставался цифровой кодовый замок. У нас уже была последовательность добытая в честном бою в реплике Flappy Bird, к тому же она отображалась на доске детектива: "3-8-9-6-4-1-2-7-5-6-4-9-0-0-7-5-2-2-4-9-1-7-5-9-0-4-6-1-7-5-2-1-0-4-9-3-8". В видео-подсказке Стетхем говорил о большом длинном числе с тройками, восьмёрками, семёрками и пятёрками, а так же о том, что данное "число" является шифром от сейфа. Поэтому сомнений, что это связано с цифровым замком практически не было. Однако, ввести было необходимо 5 групп цифр по 7 символов в каждой группе (35 цифр). В нашей же последовательности было 37 цифр. Сначала мы откинули "3 и 8" с начала, потом "3 и 8" с конца... В итоге, последовательность становилась верной, если откинуть от неё 3-ку с начала и 8-ку с конца: 8964127 - 5649007 - 5224917 - 5904617 - 5210493.


После ввода трёх верных ключей происходит переход на страницу с открытым сейфом, и если вы открыли сейф впервые, то появится форма ввода никнейма, который будет записан на дверце сейфа. Так же для всех тех, кто открыл сейф не первым, будет показана записка с ником участника, открывшим сейф первым.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Однако, у открывшего сейф первым, записка была немного другая (спасибо @NoobGameDev, за предоставленное изображение)

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Как видно, в сейфе был спрятан бумажный биткоин-кошелёк с, цитирую: "небольшим, но приятным вознаграждением".


Немного погрустив, мы продолжили) На дверце сейфа была запись "for stopped expiremen - stopplaesestopyes". Это, очевидно, и был тот самый ключ для третьего дисплея, но только его пришлось написать заглавными буквами и на русском, т.е. "СТОППОЖАЛУЙСТАСТОПДА". Довольно иронично.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

После этого мы вышли на "финишную прямую" - оставался всего один дисплей механизма. И подсказкой к нему была матрица чисел, а на доске детектива была запись "Вернуться в начало?". Мы догадались, что это намёк на изображение с 15-ю картинками в стартовом видео. У нас были все необходимые имена, но, видимо, из-за усталости мы довольно долго пыхтели над порядком этих частей фразы.

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

В итоге всё оказалось проще, чем мы думали. И порядок частей оказался следующим:


1. Наушники - 2CQ5BP6 - имя файла из страницы в даркнете.

2. Книга - QWDIYDU - описание файла в свойствах архива с книгой Гарри Поттера.

3. Медведи - FY2CY5B - появляющийся код на странице со созвездиями.

4. GPS - PRA2CZND - имя файла в котором координаты указывали на решение.

5. Тег - AOQWXIL - один из тегов .mp3 файла из ВК.

6. Штрих-код - YIGQW7ILA - название вордовского документа.

7. Змея - IGRQLIL4LB - код выдавался в Змейке тому, кто займёт первое место.

8. Амидамару - A2GD5DAW - часть, паролем к которой была дата рождения Амидамару.

9. Ножницы - QXYQNBP6 - имя изображения с барбером.

10. Печенье - QX3IYHU - часть, в комментариях страницы с зашифрованными cookie.

11. Матрёшка - MH2CYN - имя файла изображения с матрёшками.

12. Птица - DAORQLIL - часть, в комментариях веб-страницы с Flappy Bird.

13. Шелдон - FUF62CZN - часть ссылки в ветке начатой с сообщения на клингонском.

14. Лук - BMGQXPIL - заголовок веб-страницы в даркнете.

15. YouTube - QII= - надпись над монитором в видео на YouTube.


Т.е. финальная фраза оказалась следующей: 2CQ5BP6QWDIYDUFY2CY5BPRA2CZNDAOQWXILYIGQW7ILAIGRQLIL4LBA2GD5DAWQXYQNBP6QX3IYHUMH2CYNDAORQLILFUF62CZNBMGQXPILQII=


Это оказалась запись в Base32, а после расшифровки получилось "Спасибо всем, за то, что поучаствовали!".

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Это и был ключ для 4-го дисплея и ко всему механизму. После этого механизм был остановлен, а кот покинул клетку. Но как позже выяснилось сделать это он мог и без нашего вмешательства. А всё это был эксперимент по испытанию новой модели мультиварки. Такие дела)

Сложный ARG квест для IT-шников, в котором ты не участвовал. (Часть 3 — финал) Игры, Загадка, Головоломка, Информационная безопасность, Arg, Ctf, IT, Шифр, Криптография, Стеганография, Web-программирование, Web, Логика, Ребус, Квест, Шифрование, Гифка, Длиннопост

Заключение


Огромная работа, классные воспоминания и эмоции, интересные и сложные загадки... Многие участники отмечали, что узнали что-то новое о методах сокрытия и шифровки информации, кто-то изучил Энигму и посмотрел за время квеста несколько фильмов, которые бы никогда и не подумал смотреть, а кто-то даже вспомнил, что на небе существуют звёзды и ловил какие-то приятные детские эмоции.


Лично от себя могу сказать, что я благодарен NoobGameDev, за то, что целых 3 недели в такое не простое время, мои мысли были только в квесте, и я почти не думал ни о чём другом. А когда всё закончилось, то я даже испытал приятное облегчение и чувство, что все мои мысли испарились, а разум как будто бы на мгновение очистился.


Считаю, что мы должны поддерживать подобные познавательные и затягивающие проекты, поэтому оставлю ссылку на ютуб-канал и на дискорд-сервер автора квеста. А так же огромное спасибо всем вам за прочтение и хорошие оценки данных статей. Удачи)

Показать полностью 24
[моё] Игры Загадка Головоломка Информационная безопасность Arg Ctf IT Шифр Криптография Стеганография Web-программирование Web Логика Ребус Квест Шифрование Гифка Длиннопост
0
Web.Study
Web.Study
2 года назад

7 легких способов склонировать массив в JS⁠⁠

Приветствую коллеги, как я думаю уже понятно из названия тут будет небольшая шпаргалка на тему клонинрования массивов.


const cloneArr = (arr) => arr.slice(0);
const cloneArr = (arr) => arr.concat([]);
const cloneArr = (arr) => Array.from(arr);
const cloneArr = (arr) => arr.map((x) => x);
const cloneArr = (arr) => [...arr];
const cloneArr = (arr) => Array.from(arr);
const cloneArr = (arr) => JSON.parse(JSON.stringify(arr));

Удачи в экспериментах!


Наш канал

[моё] Программирование IT Javascript Web-программирование Frontend Веб-разработка Текст
10
recognize1
2 года назад

Выбор обучения в It сфере, Heeelp⁠⁠

Доброго дня суток пикабушники и пикабушницы, столкнулся с такой несущественной проблемой для себя, как выбор обучения непосредственно в IT сфере, а именно это программирование и компьютерная графика/web дизайн, курс длится 2.5 года, по этому хотелось бы предварительно кто занимался тем или иным, а лучше и тем, и тем - дать какие-то свои комментарии по поводу этого. В целом ситуация следующая, я максимальный гуманитарий, никогда не любил и не понимал математику и все, что с этим связано (специальность моя правовед, а работаю юристом), так вот, в во всяких математических штуках я полный ноль, но как и всем парням, всегда нравилось находится за компом, что-то устанавливать, менять винду, разбирать/собирать и прочее, та и нахожусь по сути у компа все своё время, вот решил пока время есть пойти на курсы, но вот не понимаю пока на какие..

В целом программирование для меня, как для человека максимально от этого далёкого заучит интересно, хотя я знаю поверхностно об этом, но и создание сайтов, графика тоже интересно. Но с моим ебл@наским складом ума, исходя из вашего опыта, на что лучше обратить внимание из вариантов и почему? Может быть вообще есть что-то лишнее, что можно и не изучать, либо чего-то наоборот нет. Вообщем, жду адекватных советов. ЗА ОТВЕТЫ ВСЕХ ОБНЯЛ И ПОЦЕЛОВАЛ!! Спасибо 😉

P.s. выложу так же 2 фото, в котором будет указано что входит в курс программирования (зелёная картинка) и компьютерной графики/web дизайна (красная).

Выбор обучения в It сфере, Heeelp Совет, Личный опыт, Помощь, Саморазвитие, IT, Программист, Web-программирование, Дизайн, Веб-дизайн, Длиннопост
Выбор обучения в It сфере, Heeelp Совет, Личный опыт, Помощь, Саморазвитие, IT, Программист, Web-программирование, Дизайн, Веб-дизайн, Длиннопост
Показать полностью 2
[моё] Совет Личный опыт Помощь Саморазвитие IT Программист Web-программирование Дизайн Веб-дизайн Длиннопост
17
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии