Створення Ghent Theft Auto за допомогою кодування монахів.

Ви коли-небудь стикалися з проблемою, коли треба моделювати поведінку 270,000 автономних агентів у цифровому двійнику, використовуючи календарні машини станів? Звучить складно, але насправді багато наших звичок і поведінок визначаються завдяки «Годиннику». Як і в реальному світі, багато людських патернів поведінки зводяться до планування, яке залежить від часу.

Наприклад, коли світло включається, коли відкриваються магазини, або коли транспорт збільшується перед дзвінком на урок. Багато з цих патернів залежать від календаря і подій на кшталт свят або робочих днів. Іноді важко точно порахувати, коли наступає певна подія, і, звісно, Пасха є однією з найбільш складних дат для обчислення.

Пасха завжди змушує мене … Читати далі

Проектування API на C++

pic

Виступ Джейсона Тёрнера на CppCon 2022 під назвою "Back to Basics: C++ API Design" містить кілька ключових рекомендацій для створення кращих API, на які варто звернути увагу при розробці програмного забезпечення.

Основною ідеєю є те, щоб API було складно використовувати неправильно. Тёрнер наголошує, що це має бути основною метою під час проектування API.

Одним з перших важливих аспектів є вибір правильних назв. Назви повинні бути чіткими і описовими, оскільки це значно полегшує роботу з API. Використання зрозумілих і точних імен дозволяє уникнути багатьох помилок і непорозумінь.

Наступний важливий момент — це використання атрибута [[nodiscard]]. Цей атрибут повідомляє компілятору, що … Читати далі

Leetcode — Масиви та Хешування (Рівень — Легкий)

Задача на LeetCode під номером 1929 передбачає об'єднання масиву з самим собою, формуючи новий масив, довжина якого вдвічі більша за початковий. Для цього можна створити новий масив, який буде містити елементи з першого масиву двічі.

У завданні на пошук дублюючих елементів у масиві (LeetCode Problem 217) необхідно визначити, чи є у масиві дублікати. Для цього використовується unordered_map (в C++) або словник (в Python), щоб підрахувати кількість входжень кожного елементу. Якщо елемент зустрічається більше ніж один раз, повертається true.

Задача, що перевіряє, чи є два рядки анаграмами (LeetCode Problem 242), полягає у визначенні, чи складаються два рядки з тих самих … Читати далі

Вибір правильної мови програмування: як моделі виконання впливають на ваше рішення

pic

Інтерпретатори і компілятори мають важливе значення в програмуванні, оскільки вони визначають, як код виконується на комп'ютері. Коли я почав вивчати Java, я часто чув терміни такі як компілятор (compiler), інтерпретатор (interpreter), JVM (Java Virtual Machine) та байт-код (bytecode). Спочатку я не розумів, як саме код виконується за лаштунками, і це спонукало мене дослідити процес виконання програм, що виявився природною еволюцією: від інтерпретаторів до компіляторів, і зрештою до гібридних моделей, як у Java.

Якщо вам цікаво, що відбувається з вашим кодом після натискання кнопки "Запустити", ось чому важливо розуміти різницю між інтерпретаторами та компіляторами.

Інтерпретатори: Перший крок до спрощення

На початку … Читати далі

Leetcode 98 — Перевірка правильності бінарного дерева пошуку | BST | DFS | C++ | Середній рівень LC | Проблема для інтерв’ю на C++

pic

Дано корінь бінарного дерева, і завдання полягає в тому, щоб визначити, чи є це дерево правильним бінарним деревом пошуку (BST).

Правильне BST має такі характеристики:

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

Обидва піддерева також повинні бути правильними бінарними деревами пошуку.

Приклад 1:

pic

Кредит: Leetcode

Вхід: root = [2,1,3]

Вихід: true

Приклад 2:

pic

Кредит: Leetcode

Вхід: root = [5,1,4,null,null,3,6]

Вихід: false

Пояснення: Значення кореня — 5, але правий нащадок має значення 4, що суперечить правилу.

Підхід

Для вирішення цієї задачі необхідно … Читати далі

Практичні програми з багатопоточності на C++

Практика з багатопоточності на C++ є чудовим способом закріпити теоретичні знання та отримати реальний досвід у розробці ефективних багатозадачних програм. Початкові вправи дозволяють познайомитись з основами багатопоточності, такими як створення потоків і передача параметрів у функції потоків. Наприклад, можна почати з простих завдань, таких як виведення повідомлення з потоку або обчислення суми елементів масиву за допомогою кількох потоків. Інші вправи включають синхронізацію доступу до спільних змінних через std::mutex та демонстрацію умов гонки без використання цього механізму. Також важливо освоїти такі інструменти, як std::lock_guard і std::unique_lock, для управління блокуванням mutex.

Середній рівень вправ пропонує більш складні завдання, такі як реалізація … Читати далі

Оволодіти як основами, так і передовими концепціями многопоточності в C++.

C++ є потужною мовою програмування, яка дозволяє ефективно працювати з багатозадачністю та багатопоточними програмами. Однією з основних тем, яку варто вивчити, є основи C++ та концепції, що дозволяють ефективно керувати потоками.

Починаючи з основ, вам потрібно ознайомитися з базовими поняттями функцій, класів та об'єктів, а також із шаблонами та важливою концепцією RAII, яка допомагає керувати ресурсами. Лямбда-вирази також є потужним інструментом для оптимізації коду та покращення його читабельності.

Важливо розуміти, як використовувати стандартну бібліотеку C++, зокрема колекції даних як std::vector, std::queue та std::map. Вміння працювати з бібліотеками для часу, такими як std::chrono, також значно полегшує розробку програм.

Що стосується багатозадачності … Читати далі

Leetcode 242 — Дійсне анаграмування в C++ | HashMap | Unordered Map | LC Легке | Проблема для співбесіди на C++

Програмування — це важкий процес для багатьох, поки вони не освоять його тонкощі. (Звісно, я маю на увазі епоху до ChatGPT). Є момент, коли програмісти вивчають синтаксис і базову логіку, набувають впевненості, але потім стикаються з проблемами складності часу та пам'яті. Хороший програміст оволодіває цими концепціями і починає писати швидкий код. Але чи достатньо цього?

Ми говоримо про швидкий код, але що це насправді означає? Програміст повинен розуміти, що ваш код буде перетворено в інструкції машини в кілька етапів. Код вважається швидким, якщо кількість інструкцій, які повинна виконати машина, мінімізована.

Уявіть, програміст працює над часо-чутливим кодом, що вимагає ініціалізації 2D … Читати далі

Чи повинні програмісти знати, що відбувається всередині комп’ютера?

Програмування часто здається головоломкою для багатьох, поки не розберешся в цьому мистецтві. (Звісно, я маю на увазі епоху до ChatGPT). І ось наступає момент, коли програмісти опановують синтаксис і базову логіку, здобуваючи впевненість, і раптом стикаються з проблемами складності часу та простору. Хороший програміст освоює ці концепції та, зрештою, створює швидко працюючі коди. Але чи цього достатньо?

Коли ми говоримо про швидкодіючий код, що саме маємо на увазі? Програміст має розуміти, що його код буде перекладений у кілька етапів в інструкції для машини. Код вважається швидким, якщо в кінці кількість інструкцій, які потрібно виконати, мінімізована.

Програміст працює над дуже чутливим … Читати далі

Модульна бібліотека для логування в C++23

Сьогодні на порядку денному — очевидний, але часто не використовуваний підхід: Негайно Викликані Лямбда Вирази (IILE).

Чому важливий const?

Незмінність є ключовим принципом для надійного і зрозумілого коду. Використання const, де це можливо, допомагає компілятору виявляти помилки та чітко вказує на намір програміста. Коли інша людина читає ваш код і бачить const, це значно знижує її когнітивне навантаження — "немає потреби відслідковувати зміни цієї змінної — все ясно". Важливість правильного використання const є основою багатьох хороших практик у C++.

Проблема

У простих випадках ініціалізація констант не викликає труднощів:

const int cmaxPlayers = 100;
const double
Читати далі