Как стать автором
Обновить
237.08

Алгоритмы *

Все об алгоритмах

Сначала показывать
Порог рейтинга
Уровень сложности

Как задачи на LeetCode прокачали меня как разработчика, или по-честному про алгоритмы

Уровень сложностиПростой
Время на прочтение7 мин
Количество просмотров56K

Однажды я зашла на LeetCode, одну из популярных платформ для решения алгоритмических задач. Сразу уточню: мне не нужно было готовиться к собеседованию, и моя работа не требовала продвинутого знания алгоритмов. Тем не менее я заметила, что у меня стали заполняться пробелы в знаниях, и я продолжила решать задачи — каждый день понемногу.

С тех пор у меня накопилось более 400 решённых задач на LeetCode. Теперь я уверена, что такие платформы как LeetCode, HackerRank или CodeWars, при правильном подходе, способны поднять профессиональные навыки любого разработчика на новый уровень.

Читать далее
Всего голосов 80: ↑72 и ↓8+64
Комментарии92

Как работает хэширование

Уровень сложностиСредний
Время на прочтение12 мин
Количество просмотров59K

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

Хэш-функции фундаментальны и используются повсюду.

Но что же такое хэш-функции и как они работают?

В этом посте я собираюсь развенчать мифы вокруг этих функций. Мы начнём с простой хэш-функции, узнаем, как проверить, хороша ли хэш-функция, а затем рассмотрим реальный пример применения хэш-функции: хэш-таблицу.
Читать дальше →
Всего голосов 76: ↑73 и ↓3+70
Комментарии49

Кодеки новой эпохи: HEVC, AV1, VVC и нейросети

Уровень сложностиСредний
Время на прочтение6 мин
Количество просмотров19K
Сжатие с учётом контекста, источник: WaveOne (сайт удалён)

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

В новом поколении кодеков алгоритмы машинного обучения используются для анализа и понимания визуального содержания видео, выявления избыточных данных и более эффективного сжатия. Вместо написанных вручную алгоритмов, тут применяют методы Software 2.0, основанные на обучении. Данная область развивается на протяжении десятилетий, но в последние годы получила сильный толчок. Все знают, что в 2017 году произошёл прорыв в разработке ИИ благодаря изобретению трансформеров. В свою очередь, они основаны на концепции внимания, которую придумали в 90-е. Эта техника впервые позволила соотносить друг с другом отдельные части текста или видеокадра.
Читать дальше →
Всего голосов 61: ↑58 и ↓3+55
Комментарии32

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

Уровень сложностиСредний
Время на прочтение13 мин
Количество просмотров10K

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

Ресурсы


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

  • Build Your Own Text Editor — наверно, самый фундаментальный пост о создании текстового редактора с нуля, который я видел. Это превосходный туториал на случай, если вы хотите начать писать собственный текстовый редактор. Стоит заметить, что в редакторе из этого туториала в качестве внутренней структуры для текста используется, по сути, вектор строк.
  • Text Editor: Data Structures — отличный обзор множества структур данных, которые можно использовать при реализации текстового редактора. (Спойлер: как минимум одна из них будет рассмотрена в моём посте)
  • Плейлист Ded (Text Editor) на YouTube — это потрясающая серия, в которой @tscoding фиксирует процесс создания с нуля текстового редактора. Эти видео стали для меня источником вдохновения.

Зачем?


Если в сети есть так много хороших ресурсов о создании собственного текстового редактора (не говоря уже о том, что уже существует множество феноменальных текстовых редакторов), то зачем я это пишу? На то есть несколько причин:

  1. Я хотел заняться проектом, непохожим ни на один свой прошлый.
  2. Я хотел создать инструмент, которым смогу пользоваться.
  3. Мне всегда хотелось глубже разобраться с созданием собственных структур данных.
Читать дальше →
Всего голосов 60: ↑59 и ↓1+58
Комментарии18

Истории

Реализуем с нуля функцию косинуса на языке C

Уровень сложностиСложный
Время на прочтение10 мин
Количество просмотров14K

Я изучил, как реализовать функцию косинуса при помощи нескольких разных подходов. Одна из реализаций почти в три раза быстрее, чем math.h, но придётся смириться с точностью до четырёх знаков после запятой.

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

Моё исследование началось с того, что мой друг и коллега Стивен Марц работал над ядром операционной системы и я предложил, чтобы он отрисовал на экране функцию косинуса. Я часто использую косинус в качестве «hello, world» для графических приложений. Возникла проблема: его ядро не задействовало стандартную библиотеку C (а значит, прощай math.h!), а целевой платформой являлась архитектура RISC-V (а значит, никаких подобий команды fcos Intel!).

Так началось моё долгое приключение.
Читать дальше →
Всего голосов 60: ↑57 и ↓3+54
Комментарии29

Как устроено распределение памяти

Уровень сложностиСредний
Время на прочтение11 мин
Количество просмотров23K

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

В этом посте я познакомлю вас с основами распределения памяти (memory allocation). Распределители памяти существуют, потому что иметь доступную память недостаточно, необходимо ещё и эффективно её использовать. Мы наглядно изучим, как работают простые распределители. Мы рассмотрим некоторые из задач, которые им необходимо решать, а также некоторые из методик, которыми они их решают. Прочитав этот пост, вы узнаете всё, что необходимо для написания собственного распределителя.
Читать дальше →
Всего голосов 77: ↑75 и ↓2+73
Комментарии6

Что делает ChatGPT… и почему это работает?

Уровень сложностиСредний
Время на прочтение75 мин
Количество просмотров146K

То, что ChatGPT может автоматически генерировать что-то, что хотя бы на первый взгляд похоже на написанный человеком текст, удивительно и неожиданно. Но как он это делает? И почему это работает? Цель этой статьи - дать приблизительное описание того, что происходит внутри ChatGPT, а затем исследовать, почему он может так хорошо справляться с созданием более-менее осмысленного текста. С самого начала я должен сказать, что собираюсь сосредоточиться на общей картине происходящего, и хотя я упомяну некоторые инженерные детали, но не буду глубоко в них вникать. (Примеры в статье применимы как к другим современным "большим языковым моделям" (LLM), так и к ChatGPT).

Читать далее
Всего голосов 248: ↑248 и ↓0+248
Комментарии121

Как журналист помогает выявлять серийных убийц с помощью алгоритма

Время на прочтение14 мин
Количество просмотров18K

17 октября 2014 года в мотеле маленького городка Хаммонд, Индиана, был обнаружен труп 19 летней Африки Харди. Вызванные на место полицейские почти сразу пришли к выводу, что это было убийство. На поиски убийцы ушло меньше суток — его обнаружили по записям камер наблюдения, установленных возле мотеля, а также по анализу телефонных разговоров жертвы (в номере был найден её телефон).

43-летний Даррен Ванн был арестован уже 18 октября и, как ни странно, совсем не был удивлён появлению полиции. Когда наручники защёлкнулись на его запястьях, Даррен повернулся и сказал полицейскому: «Наконец-то вы меня поймали». Так попался серийный убийца, жертвами которого стали ещё минимум шесть женщин. Но как полагали детективы, на самом деле счёт приближался к 20. 

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

Поймать маньяка
Всего голосов 67: ↑65 и ↓2+63
Комментарии29

Реализация двустороннего A* на двух потоках

Уровень сложностиСложный
Время на прочтение10 мин
Количество просмотров5K

На Хабре можно найти немало статей, посвящённых оптимизациям поиска кратчайшего пути на графе. Я расскажу ещё про еще один подход. Речь пойдёт о распараллеливании алгоритма A* и исполнении его на двух потоках, а также о сложностях, с которыми я столкнулся при реализации, и их преодолении.

Читать далее
Всего голосов 56: ↑56 и ↓0+56
Комментарии35

RSync на стероидах с поддержкой Windows

Уровень сложностиСредний
Время на прочтение5 мин
Количество просмотров28K


На Хабре периодически рассказывают о новых инструментах для синхронизации данных. Это интересная тема. Такие программы используются:

  • для синхронизации файлов на разных устройствах,
  • дедупликации,
  • резервного копирования,
  • сжатия.

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

Кроме того, инструменты синхронизации интересны с алгоритмической точки зрения. Любопытно, как люди умудряются оптимизировать базовые алгоритмы типа rsync, которые вроде бы работают идеально. Но нет, всегда можно придумать что-то получше.
Читать дальше →
Всего голосов 62: ↑62 и ↓0+62
Комментарии27

Алгоритмы балансировки нагрузок

Уровень сложностиСредний
Время на прочтение8 мин
Количество просмотров31K

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

В этом посте мы рассмотрим способы, которыми один балансировщик нагрузок может распределять HTTP-запросы на множество серверов. Мы начнём снизу и проделаем весь путь вверх до современных алгоритмов балансировки нагрузок.
Читать дальше →
Всего голосов 107: ↑106 и ↓1+105
Комментарии16

Ответом на задачу по упаковке цветов в бесконечной сетке оказалось число 15

Уровень сложностиСредний
Время на прочтение7 мин
Количество просмотров7.6K
Видео

В задаче по «упаковке цветов графа» (в оригинале packing coloring, — прим. пер.) спрашивается, сколько чисел необходимо для заполнения бесконечной сетки так, чтобы идентичные числа никогда не оказывались слишком близко друг к другу. И новый арифметический эксперимент с использованием компьютера даёт на удивление простой ответ.

Сколько чисел потребуется для заполнения бесконечной сетки так, чтобы расстояние между вхождениями одного числа было больше самого этого числа?
Читать дальше →
Всего голосов 54: ↑53 и ↓1+52
Комментарии12

Полезен ли сегодня быстрый обратный квадратный корень из Quake III?

Время на прочтение23 мин
Количество просмотров71K

В 2005 году id Software опубликовала под лицензией GPL-2 исходный код своей игры 1999 года Quake III Arena. В файле code/game/q_math.c есть функция для вычисления обратного квадратного корня числа, которая на первый взгляд выглядит очень любопытным алгоритмом:

float Q_rsqrt( float number )
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y  = number;
    i  = * ( long * ) &y;                       // зловещий хакинг чисел с плавающей запятой на уровне битов
    i  = 0x5f3759df - ( i >> 1 );               // какого чёрта?
    y  = * ( float * ) &i;
    y  = y * ( threehalfs - ( x2 * y * y ) );   // первая итерация
//  y  = y * ( threehalfs - ( x2 * y * y ) );   // вторая итерация, можно удалить

    return y;
}

Об этом алгоритме написано множество статей, и ему посвящена хорошая страница Википедии, где он назван fast inverse square root (быстрым обратным квадратным корнем). На самом деле, этот алгоритм упоминался на различных форумах ещё до публикации исходного кода Q3. Ryszard из Beyond3D провёл в 2004-2005 годах исследование и в конечном итоге выяснил, что первоначальным автором алгоритма был Грег Уолш из Ardent Computer, который создал его десятью годами ранее.
Читать дальше →
Всего голосов 196: ↑194 и ↓2+192
Комментарии52

Ближайшие события

Удивительные клеточные автоматы: направленные и пользовательские окрестности

Уровень сложностиПростой
Время на прочтение7 мин
Количество просмотров3.1K


👾, Хабр!

На прошлых неделях мы познакомились с различными вариациями альтернативных окрестностей – начиная с учёта расположения нотацией Хенселя, через альтернативные шаблоны расположения, и заканчивая взвешенными окрестностями. Сегодня добавим в тему окрестностей стандартного поля небольшой финальный штрих – пользовательские расположения.
Что здесь происходит (для новых читателей серии)
В этой серии мы разбираем клеточные автоматы – дискретную модель, основой которой является сетка из ячеек-клеток, которые изменяют (или не изменяют) своё состояние в зависимости от количества соседей.
Учёт соседей определяется правилами, которые устанавливаются нами. Вариаций правил существует бесчисленное множество, и они были систематизированы в определённые конфигурации.
Самая популярная конфигурация – «B/S», или «life-like», по названию крайне широко известного клеточного автомата «Game of Life», где B/S обозначает, что в нашем правиле мы описываем всего два параметра – количество соседей необходимых для рождения новой клетки в пустой ячейке, и количество соседей для выживания существующей клетки.
В каждой статье серии мы углубляемся в данную конфигурацию, добавляя новые параметры, либо дополняя существующие. Иногда заглядываем и в прочие конфигурации.
Для понимания сегодняшней статьи достаточно знать, что:
  • поиск соседей изначально выполняется в радиусе 1 (8 окружающих клеток – ), но мы можем установить другой, добавив к правилу Rx, где x – нужный нам радиус;
  • мы можем изменять шаблон окрестности поиска соседей. Изначально подразумевается окрестность Мура – R в каждую сторону (и диагональ) от рассматриваемой клетки, – но указывая Nxx мы будем определять иной шаблон, что, конечно, изменит вид правила. Сегодня мы продолжаем расширение этой части правила. Знакомство с предыдущими расширениями не является необходимым, но вы, конечно, можете предварительно ознакомиться с ними и прочими дополнениями, для большей последовательности чтения. Ссылки в конце материала и в профиле.
Читать дальше →
Всего голосов 52: ↑51 и ↓1+50
Комментарии9

Удивительные клеточные автоматы: альтернативные окрестности и HROT

Уровень сложностиПростой
Время на прочтение6 мин
Количество просмотров3.4K


👾, Хабр!

В прошлой статье о циклических КА мы мельком затронули тему альтернативных окрестностей, рассмотрев несколько примеров. Несмотря на то, что ранее мы использовали только окрестности Мура и фон Неймана, существует ещё множество прочих именованных окрестностей, а потенциал для создания новых ограничен лишь нашей фантазией.

Сегодняшний обзор мы совместим с ещё одним расширением: в статье об LtL было упомянуто, что параметры рождения и выживания клетки могут поддерживать множество значений и диапазонов в некоторых прочих конфигурациях. В первую очередь речь шла о HROT (Higher-Range Outer-Totalistic) – обобщении LtL конфигурации, на котором и будут наши сегодняшние примеры.
Читать дальше →
Всего голосов 52: ↑52 и ↓0+52
Комментарии17

Как устроено индексирование баз данных

Уровень сложностиПростой
Время на прочтение12 мин
Количество просмотров74K

Индексирование баз данных — это техника, повышающая скорость и эффективность запросов к базе данных. Она создаёт отдельную структуру данных, сопоставляющую значения в одном или нескольких столбцах таблицы с соответствующими местоположениями на физическом накопителе, что позволяет базе данных быстро находить строки по конкретному запросу без необходимости сканирования всей таблицы. Применяются разные типы индексов, однако они занимают пространство и должны обновляться при изменении данных. Важно тщательно продумывать стратегию индексирования базы данных и регулярно её оптимизировать.
Читать дальше →
Всего голосов 68: ↑66 и ↓2+64
Комментарии9

Пишем игру от первого лица в 2КБ на Rust

Уровень сложностиСредний
Время на прочтение21 мин
Количество просмотров14K

Введение


Поначалу кажется, что создать игру от первого лица без движка или графического API практические невозможно. В этом посте я расскажу, как это сделать при помощи алгоритма под названием ray casting.

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

Для начала разберёмся, как работает алгоритм, а затем построчно напишем его. Затем мы пересмотрим код, добавим несколько возможностей и оптимизируем его размер. Я постарался сделать пост максимально доступным и дружелюбным, но вам поможет приличное знание программирования, Rust и основ геометрии.
Читать дальше →
Всего голосов 78: ↑77 и ↓1+76
Комментарии10

Пятничные клеточные автоматы: 10 удивительных правил с нотацией Хенселя

Уровень сложностиПростой
Время на прочтение7 мин
Количество просмотров6.7K

Продолжим знакомиться с вариациями клеточных автоматов. Ранее мы рассмотрели базовую «life-like» конфигурацию и добавили к ней поколения.

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

👾
Всего голосов 57: ↑57 и ↓0+57
Комментарии11

В этой одежде системы распознавания будут считать вас животным

Время на прочтение4 мин
Количество просмотров45K
У Рэйчел Дидеро интересный набор навыков: несколько степеней в области дизайна одежды (полученные в школах трех разных стран) и докторская степень в области машинного обучения Миланского политехнического университета.

Эти знания позволили ей выпустить коллекцию — довольно уродливой — одежды Manifesto. Она страшная и безвкусная, зато в ней вы становитесь нераспознаваемые для ML-алгоритма детектирования Yolo, активно используемого для работы с уличными камерами.



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

Читать дальше →
Всего голосов 78: ↑76 и ↓2+74
Комментарии254

О вреде GOTO-фобии (с примерами на C)

Время на прочтение17 мин
Количество просмотров30K

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

Читать далее
Всего голосов 129: ↑122 и ↓7+115
Комментарии344

Вклад авторов