Задать вопрос
  • В каком случае программа выдает ложный результат?

    @Mercury13
    Программист на «си с крестами» и не только
    T = 4, X = 2, N = 1. Получаются 2 минуты, хотя надо четыре.
    Надо не ceilDiv(nt, x), a t·ceilDiv(n,x).
    Ну и с такими ограничениями ceilDiv(n, x) = (n + x - 1) / x, без дробной арифметики.
    (Собирая всё в одно выражение, не забывайте скобки!)
    Ответ написан
    3 комментария
  • Если какие-либо профессиональные курсы по разработке браузеров?

    @Mercury13
    Программист на «си с крестами» и не только
    Такого не может быть. Рассмотрим браузер с двух сторон.

    1. Браузерный движок. В настоящее время движков раз, два и обчёлся, и ты НЕ СДЕЛАЕШЬ хороший движок. И я не сделаю — если уж M$ и Opera отказались. Удивляюсь, как Рыжая держится — держу её за старый GDI’шный рендеринг текста, иначе давно бы перешёл на Вивальди. Единственное, что иногда бывает нужно,— небольшой неполнофункциональный движок, совместимый в первую очередь с самим собой (например, чтобы отформатировать текст в интерфейсе программы).

    2. Браузер на существующем движке. А это больше вещь из бизнеса, чем из программирования. А именно — откуда брать деньги и что предложить такое, чего нет у других. Допустим, M$ и Гугл перенаправляют на собственные поисковые системы. Ну а распространении «в придачу» и говорить нечего. Из уникальных фишек у Яндекса обход украинских запретов, у Вивальди — неплохая копия старой Оперы на новом движке.

    Кроме того, есть такая штука, как Google Widevine — инфраструктура раздачи шифрованного контента, которой пользуются все клоны Хрома и Рыжая. В принципе, без неё можно, вот только Нетфликс не посмотришь — можно и свою написать, только как убедить Нетфликс ею пользоваться?
    Ответ написан
    4 комментария
  • Как обеспечить безопасность в связке «64-битная программа + 32-битный COM-прокси»?

    @Mercury13 Автор вопроса
    Программист на «си с крестами» и не только
    Опять вынужден сам отвечать.
    Win32: Кто вызвал программу?
    Ответ написан
    Комментировать
  • Как отсортировать вектор по одному из элементов структуры?

    @Mercury13
    Программист на «си с крестами» и не только
    std::sort(thrusters.begin(), thrusters.end(), 
        [](const calcThrusterType& x, const calcThrusterType& y) {
            return (x.angle < y.angle);
        });

    Вы используете typedef и в вашем компиляторе нет Си++11?
    bool angleLess(const cTT& x, const cTT& y) { return x.angle < y.angle; }
    
    std::sort(thrusters.begin(), thrusters.end(), angleLess);
    Ответ написан
    1 комментарий
  • Где у меня может быть ошибка в нахождении площади сложной фигуры?

    @Mercury13
    Программист на «си с крестами» и не только
    Обсуждение было в комментах, и ключевая причина — при comp_a < 0 корни не сортируются.

    Побочные проблемы кода.
    1. Можно было интеграл разности, а не разность интегралов.
    2. Лучше не использовать vector и pair на месте struct { a, b, c } — кроме случаев, когда есть важная автоматизация.
    Ответ написан
    Комментировать
  • Как ускорить решение на c++?

    @Mercury13
    Программист на «си с крестами» и не только
    Вы тут что-то ухитрились написать, но всё равно n². Потому и TL.

    Пусть для каждого поддона длина — большее из измерений, ширина — меньшее. Теперь условие «поддон А можно поставить на поддон Б» упрощается.

    Очевидно, что поддоны, которые нельзя поставить друг на друга, будут возрастать по одному измерению и убывать по другому. (Иначе мы сортанём по длине, по ширине тоже обнаруживаем неубывание — и, сюрприз, эти поддоны становятся!)

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

    Нам приходит новый поддон. Упорядочиваем координаты, затем ищем в списке equal_range по длине.

    Для «БОЛЬШЕЙ» части списка [LOWER_bound, end): наш поддон можно поставить на все эти поддоны по длине, и только на первые из них — по ширине. Если l_b=end, или наш поддон не встаёт на *l_b — добавляем поддон в список. Но не сразу, а после проверки меньшей части.

    Для «МЕНЬШЕЙ» части списка [begin, UPPER_bound): все эти поддоны можно поставить на наш поддон по ДЛИНЕ, и только некоторый хвост [some_pallet, upper_bound) — по ширине. Находим этот кусок и исключаем из дерева.

    А теперь вопрос: как хакнуть наш set, чтобы можно было проводить поиск за log n и по длине, и по ширине?
    А для этого пишем свой объект-сравниватель, который можно переключать между двумя вариантами: length1<length2, либо width1>width2;

    P.S. Не очень понятно условие «один поддон становится на другой» — ни из описания, ни из примера. Мой алгоритм — length1 <= length2, width1 <= width2. Если, например, оба строго меньше (length1 < length2, width1 < width2) — то большая часть будет [u_b, end), меньшая — [begin, l_b), и из-за непересечения этих частей не обязательно добавлять в список отложенно.
    Ответ написан
    7 комментариев
  • Как перенести структуру в бинарный файл что бы он мог его прочитать без повреждения файла?

    @Mercury13
    Программист на «си с крестами» и не только
    Начнём с 2. Структуры, используемые как формат файла, применяй в прикладном коде с большой осторожностью. Если хочешь, чтобы формат расширялся, придумай простенький блочный формат.
    Для 1 — приходится использовать какую-то сигнатуру и находить её в файле.
    Например: после собственно EXE-файла идут данные, потом сигнатура и положение данных в файле. Сигнатуры нет или смещение странное — значит, просто приклеивай всю эту дрянь в конец файла. Сигнатура есть и смещение правдоподобное — идём по указанному смещению, пишем новые данные вместе с новой сигнатурой, а потом усекаем файл (на случай, если старые данные были длиннее).
    На этом принципе, кстати, основаны самоизвлекающиеся архивы RAR и RARJPEG — только сигнатура в начале, а не в конце RAR-данных.
    Ещё нужно проверить, в какой кодировке ifstream принимает данные — UTF-8 или Win-1251. Начиная с Си++17 появилась поддержка юникодных имён файлов, но я с нею не работал.
    Ответ написан
  • Редизайн книги для портфолио нарушение авторских прав?

    @Mercury13
    Программист на «си с крестами» и не только
    Нарушением не будет, пока ты не займёшься распространением собственно альбома.
    Всё, что ты дерёшь,— это тривиальную информацию: название альбома и список песен.
    Ответ написан
    1 комментарий
  • Возможно ли в процедурном программирование, имитировать ООП?

    @Mercury13
    Программист на «си с крестами» и не только
    Можно, и я бы посоветовал посмотреть на две вещи.
    1. MiniZip. Настоящие виртуальные потоки, написанные на чистом Си!
    Кстати, у нас на работе есть библиотека MiniZipPort, представляющая собой тупой перевод MiniZip на виртуальные потоки и шаблонные контейнеры — две строчки Си превращались в одну строчку на «крестах». К тому же для хранения каталога я использовал уже имевшийся самописный AccuStream (что-то вроде std::deque, только в виде потока).
    2. Doom. Самый первый, 1993–94 года. Там тоже ухитрились делать объектно — правда, другими методами.
    Ответ написан
    3 комментария
  • Как сделать срез массива?

    @Mercury13
    Программист на «си с крестами» и не только
    В Си++ нет понятия «произвольный массив», и это мешает.
    Но несложно этот самый произвольный массив (без хранения) написать
    template <class T>
    struct Buf1d {
      size_t size;
      T* d;
      constexpr Buf1d() : size(0), d(nullptr) {}
      constexpr Buf1d(size_t aSize, T* aD) : size(aSize), d(aD) {}
      Buf1d(std::vector<T>& x) : size(x.size()), d(x.data()) {}
    }

    И этому Buf1d можно придумать и другие функции, например:
    template <class T>
    Buf1d<T> Buf1d<T>::sliceLeft(size_t x) const
    {
      if (x >= size) {
        return {};
      } else {
        return { size - x, d + x };
      }
    }


    Если же вам нужно с хранением, то, например, можно воспользоваться старым добрым vector.
    template<class T>
    std::vector<T> sliceLeft(const std::vector<T>& v, size_t x)
    {
      if (x >= v.size()) {
        return {};
      } else {
        std::vector<T> r;
        r.insert(r.end(); v.begin() + x, v.end());
        return r;
      }
    }
    Ответ написан
  • Какую программу можно сделать с использованием двумерного массива?

    @Mercury13
    Программист на «си с крестами» и не только
    Тетрис. Питончик. Морской бой.
    Ответ написан
    Комментировать
  • Как решить задачу на or?

    @Mercury13
    Программист на «си с крестами» и не только
    Это невозможно.
    Пусть у нас есть массив, состоящий НЕ ЦЕЛИКОМ из нулей и содержащий хоть один ноль.
    Возьмём любой ненулевой элемент a и про-XOR’им с ним все элементы массива.
    Ноль переместился в другое место, а результаты нашей операции a[i] xor a[j] не изменились.
    Получается, что первый массив неотличим от второго, и нули в них в разных местах.

    Например: массив 0 1 2 3 неотличим от массива 1 0 3 2.
    0 xor 1 = 1 … 1 xor 0 = 1
    0 xor 2 = 2 … 1 xor 3 = 2
    0 xor 3 = 3 … 1 xor 2 = 3
    1 xor 2 = 3 … 0 xor 3 = 3
    1 xor 3 = 2 … 0 xor 2 = 2
    2 xor 3 = 1 … 3 xor 2 = 1
    Ну а 0 xor 0, 1 xor 1, 2 xor 2 и 3 xor 3 всегда были нулями.

    ------------------

    В версии с OR — берём a[0] or a[i], поддерживая AND этих сумм и подсчитывая, сколько раз этот самый AND среди наших сумм встречается.
    1) Если числа, превышающие AND, встречаются столько раз, сколько [ну, подсчитайте, сколько чисел от 0 до N−1 будут иметь все эти биты] — отбросим наше 0-е число, а также проверенные числа, чья сумма НЕ совпадает с AND, и начнём сначала.
    ПРИМЕР: 2 3 4 0 1
    2 or 3 = 5, AND=5
    2 or 4 = 6, AND=2 — бит 2 тут будут иметь только 2 и 3, отбрасываем 2, 3 и 4.

    Если AND встречается 2k−1 раз (k — кол-во битов в AND), оставим ТОЛЬКО ЭТИ случаи и снова начнём сначала.
    ПРИМЕР: 2 1 0 3
    2 OR 1 = 3, AND=3
    2 OR 0 = 2, AND=2
    2k−1=1, и нам хватает одной встречи числа 2 — оставляем 2 и 0.

    Остались три числа — действуем по стандартному алгоритму.
    Осталось одно число — оно 0.
    Остались два числа — одно 0, другое некий бит. Мы должны найти число, этого бита не имеющее. Снова проходим по результату предыдущего обхода, суммируя сначала с одним, потом с другим. Видим разницу — понятно, где 0, а где бит.
    Ответ написан
  • Как найти координаты точек на дуге зная координаты точек хорды?

    @Mercury13
    Программист на «си с крестами» и не только
    По теореме Пифагора находим расстояние от центра до хорды: d = sqrt(R² − [(x2−x1)² + (y2−y1)²]/4).
    Находим середину отрезка AB (назовём её (x3, y3)). Находим направляющий вектор отрезка AB (x4,y4) = ((x2−x1)/|AB|, (y2−y1)/|AB|), и есть два варианта центра — (x0,y0) = (x3±d·y4, y3∓d·x4).
    А дальше через atan2 получаем углы, упорядочиваем их и через углы получаем сколько угодно точек.
    Ответ написан
  • Порядок выполнения действий в выражении --i + i++?

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

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

    В Си даже это «левая → правая» зачастую остаётся за реализацией: в каком порядке компилятор хочет вычислять, в таком будет вычислять. Да ещё и «i++» — не атомарное выражение, а «i:=i+1», то есть прибавить 1, а потом присвоить — и эти операции «прибавить» и «присвоить» компилятор может разнести далеко друг от друга, если так пожелает.
    Ответ написан
    9 комментариев
  • Нормально ли обращаться к методам и свойствам классов через единый сервис?

    @Mercury13
    Программист на «си с крестами» и не только
    С моей колокольни статических языков такая конструкция — избыточная сложность на пустом месте.
    Но есть места, где такая сложность ещё и чем-то оправдана. Например, Qt — содержимое ячейки таблицы…
    QVariant SomeModel::data(
        const QModelIndex &index, int role = Qt::DisplayRole) const override {}

    Для чего оно такое в Qt…
    • в самом начале функции может вычисляться адрес в памяти, где все эти данные находятся, а за ним — длинный switch/case «в зависимости от роли, возьми то-то»;
    • возможно возвращение пустого QVariant, когда надо сказать: «действуй как обычно»;
    • наконец, возможны сложные операции с данными, вроде преобразования в отображаемую форму и сортировки, которые не зависят от специфики модели данных.

    Так что ответ. Смотрите по месту: что вы хотите этой конструкцией сказать и почему более простые не оправданы.
    Ответ написан
  • Что значит const volatile?

    @Mercury13
    Программист на «си с крестами» и не только
    const — чтобы исключить попытки писать в него.
    volatile — каждый раз при обращении проходить по адресу и брать данные , а не кэшировать.
    Если какая-то ячейка в памяти (в данном случае по адресу 0x30) меняется другим потоком или, например, железом, она volatile.
    Лучше было бы писать
    const volatile char* const port = (const volatile char *) 0x30;

    Ещё лучше (Си++11 и непортабельно)
    constexpr const volatile char *port = (const volatile char *) 0x30;

    А ещё лучше сделал Паскаль
    var
      SomePort : byte absolute $30;
    Ответ написан
  • Ошибка с типами с++?

    @Mercury13
    Программист на «си с крестами» и не только
    1. C:\Users\XXX\Desktop — не обязательно стол будет там.
    2. Гуглите функцию std::string::c_str() — преобразование string в нуль-терминированную строку Си.
    Ответ написан
    Комментировать
  • Что означает данная запись структуры?

    @Mercury13
    Программист на «си с крестами» и не только
    Переменная этого типа.
    Ответ написан
    Комментировать
  • Какие бывают библиотеки для лицензирования, и бывают ли?

    @Mercury13
    Программист на «си с крестами» и не только
    Я бы посоветовал посмотреть открытые части VmProtect (там и на PHP версия есть, и на C++). Они связаны именно с лицензированием.
    А также поискать где-то структуру VmProtect’овского hardware ID.
    Закрытые части, связанные с защитой лицензий от взлома и собственно виртуальной машиной, которая и дала название защите VmProtect, вы вряд ли найдёте. Да и вообще защита от копирования не может быть опенсорсной.
    Ответ написан
    Комментировать
  • Как сделать алгоритм?

    @Mercury13
    Программист на «си с крестами» и не только
    Пусть минимальный простой делитель a.
    Тогда минимальный делитель a (будь мин.делитель составной — нашёлся бы меньший), максимальный — x/a (по сходной причине), x=91·a².
    Кроме того, 91 = 7·13, и потому a <= 7.
    2²·91 и 3²·91 до четырёхзначного явно не дотягивают.
    А вот следующее — a=5 — даёт 2275 = 5²·7·13.
    Также должно подойти a=7, x=7³·13=4459.
    (Раз тут математика, часто запрещён даже калькулятор, потому попытался написать так, как думал бы человек без калькулятора)
    Ответ написан
    Комментировать