• Как создать массив с равноудаленными элементами?

    @Mercury13
    Программист на «си с крестами» и не только
    Неплохие результаты получились с одной из первых версий с простейшим патчем на повторы.
    #include <iostream>
    
    struct Sector
    {
        char name;
        int total, counter, remainder;
        bool allowNearby;
    };
    
    enum { N = 3 };
    Sector secs[] { { 'A', 3 }, { 'B', 6 }, { 'C', 30 } };
    
    int main()
    {
        int nTotal = 0;
        for (int i = 0; i < N; ++i) {
            Sector& sec = secs[i];
            nTotal += sec.total;
        }
        for (int i = 0; i < N; ++i) {
            Sector& sec = secs[i];
            sec.counter = sec.total;
            sec.remainder = sec.total;
            sec.allowNearby = (sec.total * 2 > nTotal);
        }
    
        Sector* repeatS = nullptr;
        for (int iSec = 0; iSec < nTotal; ++iSec) {
            Sector* bestS = nullptr;
            for (int i = 0; i < N; ++i) {
                Sector& sec = secs[i];
                if (sec.remainder != 0 && &sec != repeatS) {
                    if (!bestS) {   // первый подходящий?
                        bestS = &sec;
                    } else {    // лучше bestS?
                        if (sec.counter < bestS->counter
                                || (sec.counter == bestS->counter && sec.total > bestS->total))
                            bestS = &sec;
                    }
                }
            }
            if (!bestS)     // так и не нашли, что брать — берём repeatS
                bestS = repeatS;
    
            // пересчитаем счётчик и остаток
            bestS->counter += nTotal * 2;
            --bestS->remainder;
    
            for (int i = 0; i < N; ++i) {
                Sector& sec = secs[i];
                sec.counter -= sec.total * 2;
            }
            repeatS = bestS->allowNearby ? nullptr : bestS;
            std::cout << bestS->name;
        }
        std::cout << std::endl;
    }

    Пишу на «си с крестами». Раз уж вы работаете на PHP, вместо указателей придётся держать «лучший индекс» и «последний индекс».

    Принцип программы прост. Счётчики считают вниз с разной скоростью; чем чаще встречается сектор, тем быстрее. Приоритет взятия такой: не исчерпан → без повторов → у кого счётчик меньше → какой встречается чаще. Однако если какого-то сектора больше 50%, для него повторы вполне себе разрешены.
    Ответ написан
  • Как раздать интернет с модема на два wi-fi роутера?

    @Mercury13
    Программист на «си с крестами» и не только
    Что собой представляет кабельный модем в плане модели OSI?
    1. Маршрутизатор. Тогда подключайте к нему что угодно, хоть хабы, хоть маршрутизаторы. Главное — поставить NAT на самом модеме и отключить на маршрутизаторах (или даже поставить маршрутизаторы в режим точек доступа).
    2. Мост. Тогда подключаем маршрутизатор и налаживаем на нём NAT. К нему подключаем второй маршрутизатор, либо переведя его либо в режим точки доступа, либо просто отключив NAT.
    Ответ написан
    1 комментарий
  • Как комментировать код в Delphi так, чтобы при запуске приложения на windows код от андроид не исполнялся?

    @Mercury13
    Программист на «си с крестами» и не только
    {$IFDEF MSWINDOWS}
    // тут код, специфичный для Windows
    {$ENDIF}


    И, аналогично, {$IFDEF ANDROID}

    Часто используют {$IF defined(MSWINDOWS)} — можно написать {$ELSEIF defined(ANDROID)}.
    Ответ написан
    1 комментарий
  • Какой способ организации чтения и записи файлов в разных форматах оптимальнее?

    @Mercury13
    Программист на «си с крестами» и не только
    Портяночный способ хорош, когда на выходе — файл простой структуры. Например, стандартные файлы межпрограммного обмена наподобие HTML, PNG…
    Рекурсивный удобнее для внутреннего формата хранения, когда надо в подходящем виде сериализовать всё, что в программе есть, да ещё и наладить поддержку старых версий этой сериализации.
    Ответ написан
    Комментировать
  • Как создать компонент в потоке и оставить его в delphi?

    @Mercury13
    Программист на «си с крестами» и не только
    Можно, только синхронно. Используй TThread.Synchronize. Код пишется с листа, не уверен, что действующий.
    procedure TMyThread.SyncCreateMemo;
    begin
     Memo:=TMemo.Create(Form6);
      Memo.Parent:=Form6;
      Memo.Left:=50;
      Memo.Top:=50;
      Memo.Width:=250;
      Memo.Height:=100;
      Memo.Text:='Мама я родился!';
    end;
    
    procedure TMyThread.Execute;
    begin
      Synchronize(SyncCreateMemo);
    end;


    Второй способ, более сложный и опасный — PostMessage. Здесь никаких задержек поток испытывать не будет. Но будьте осторожны — форма создаст компонент когда угодно и нельзя его заполнять сразу же.
    procedure TForm6.WmCreateMemo; // message WM_CREATEMEMO = WM_USER + 1
    begin
     Memo:=TMemo.Create(Form6);
      Memo.Parent:=Self;
      Memo.Left:=50;
      Memo.Top:=50;
      Memo.Width:=250;
      Memo.Height:=100;
      Memo.Text:='Мама я родился!';
    end;
    
    procedure TMyThread.Execute;
    begin
      PostMessage(Form6.Handle, WM_CREATEMEMO, 0, 0);
    end;


    Заполнять наш редактор тоже можно путём PostMessage, но тут тоже будьте осторожны: сообщения-то выполнятся по порядку, но никто не знает, до окончания потока или нет. Бывает и такое, что два сообщения ушли в очередь, но ещё не обработались. В общем, будьте предельно осторожны с временем жизни объекта.
    Ответ написан
    Комментировать
  • Паскаль. Переменные и массивы внутри классов?

    @Mercury13
    Программист на «си с крестами» и не только
    Что творится? Не компилируется?
    А не компилируется из-за непонимания концепции эквивалентности типов. В отличие от Си, внешне одинаковые типы не эквивалентны! Для эквивалентности надо, чтобы их цепочки type A = B; вели к одному «предку». Для этого существует оператор type.
    const
      FieldSize = 10;
      MaxShips = 10;
    type
      TField = record
        cells : array [1..FieldSize, 1..FieldSize] of integer;
        nLive : array [1..MaxShips] of integer;
      end;
      TGame = class
        Field : TField;
        constructor Create(const Field : TField);  
      end;

    Возможно, эквивалентность ослабили в Delphi, не проверял. А в BP именно так.

    Возможно, вы также сделали известную ошибку начинающего дельфиста:
    var
      x : Test;
    ....
    x.Create(a, b);     // неверно!
    x := Test.Create(a, b); // верно!


    Есть одно исключение из этой эквивалентности типов.
    type
      DaInt = array of integer;
    
    procedure DoSomething1(var x : array of integer);
    procedure DoSomething2(var x : DaInt);

    Эти команды обе действуют, но не эквивалентны!

    Первое — нововведение TP7, параметр типа «открытый массив», массив любой размерности. Статический, динамический, строчка 2D-массива — всё подойдёт. Действуют Low, High и (для D4+) Length.

    Второе — нововведение D4, динамический массив, которому можно изменять длину через SetLength.
    Ответ написан
    1 комментарий
  • Как использовать кириллицу в параметрах запроса IdHTTP?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Разобраться, в какой кодировке работает сервер (обычно UTF-8).
    2. Для путей — провести преобразование (Utf8Encode вроде). Не забудь, что Delphi 7 «из коробки» неюникодная.
    3. Для доменных имён — закодировать в PunyCode. Это уже сам как-то — думаю, есть библиотеки, но точно не в коробке.
    Ответ написан
    3 комментария
  • Есть ли алгоритм определения оптимального размера посылки?

    @Mercury13
    Программист на «си с крестами» и не только
    Упаковка параллелепипедов. NP-полная задача, точное решение — перебор. Сам решал упаковку прямоугольников (т.е. в 2D) генетическим алгоритмом с переменным успехом.
    Скорее всего, у вашей службы доставки есть ящики стандартного размера — потому стоило бы приспосабливаться к этим ящикам.
    Ответ написан
    1 комментарий
  • Как запустить на выполнение exсel файл из java?

    @Mercury13
    Программист на «си с крестами» и не только
    docs.oracle.com/javase/6/docs/api/java/awt/Desktop.html

    Как работает, не проверял.
    Ответ написан
    Комментировать
  • Android и аппаратная клавиатура - покой навеки? Почему?

    @Mercury13
    Программист на «си с крестами» и не только
    Расскажу как программист о подоплёке этого. Тут есть два вопроса.
    1. Какие телодвижения должен сделать разработчик этого? Насколько это легко?
    2. И какая выгода будет от этого?

    Когда-то деловое ПО разрабатывали под конкретное разрешение экрана. Когда IBM стала делать всё новые и новые машины, сохраняя преемственность, программисты стали делать, чтобы ПО «тянулось»: проверяется за пять секунд и приносит изрядные неудобства, когда плохо реализовано.

    А вот с HiDPI вышло не так радужно. У кинескопа все разрешения были «нештатные», в отличие от одного штатного на ЖК. А ещё был неуменьшаемый предел DPI, порядка 0,2 мм, ограничивавшийся сведением лучей. Первая ОС Microsoft с поддержкой HiDPI — Windows 95 (!). Но чтобы проверить, компьютер требовалось перезагрузить. И перезагрузить ещё раз, чтобы вернуть как было. Естественно, на это подзабили и вернулись, когда уже петух клюнул — появился Яббл со своей Retina.

    Точно так же и тут. Перепробовал пару программ на KitKat. В «лисичке» Tab работает. В Яндекс-картах работает, но не видно, что выделено. Это значит: какая-то поддержка со стороны ОС есть, да и методичка Google говорит: всё должно работать на устройствах с «железной» крестовиной. Реально на это подзабили.

    Окей. Бросим пока программизм. Инвалиды. Все эти пандусы, съезды и прочее. Телодвижений от конструктора требуется куча. Выгода — разве что тем самым инвалидам. Вот и имеем то, что имеем.
    Ответ написан
  • Какими приёмами вы пользуетесь чтобы различать указатели, которые нужно освобождать, от указателей, которыми нужно только пользоваться?

    @Mercury13
    Программист на «си с крестами» и не только
    Но есть ещё один указатель, который реализует именно что единую ответственность — std::unique_ptr. Также я использую одну самоделку — но, возможно, «не умею готовить» unique_ptr.
    Ответ написан
    1 комментарий
  • Что значит Buffered?

    @Mercury13
    Программист на «си с крестами» и не только
    ДЛЯ ВВОДА-ВЫВОДА: Он читает информацию большими кусками и хранит эти куски в памяти.
    Служит для ускорения доступа, если на самом-самом высоком уровне файл надо читать по одному байту или символу, а на самом-самом низком (например, жёсткий диск) эффективнее это делать блоками по 4K.

    У читателей flush (если таковой есть; у BufferedReader, например, его нет) служит для потоков реального времени: клавиатуры, коммуникационных портов и прочего. Всё, что накопилось в буфере, сбрасывается, и считается, что на момент T поток пуст.

    Писатели, естественно, пишут данные не сразу, а когда буфер заполнится, и авария программы или перебой электричества эти данные похѣритъ. Для них команда flush физически записывает накопленные данные.

    ДЛЯ КАРТИНОК: Картинка хранится не в «аппаратно-эффективном» виде, а в таком, чтобы пользователь мог её относительно просто менять.
    Ответ написан
    Комментировать
  • Как найти минимальное время которое удовлетворяет условие?

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

    Сортируем миссии по соотношению «очки/время». Главное — правильно отсечь перебор: например, каждый раз линейно экстраполируем по соотношению «очки/время» лучшей доступной миссии: удастся вписаться или нет? Смотрим на сумму «хвоста»: можно ли вообще, просуммировав «хвост», получить K?
    int N, K;
    Mission missions[100];
    int bestTime = std::numeric_limits<int>::max();
    
    bool recurse(int firstMission, int currPoints, int currTime)
    {
        if (currTime >= bestTime)
            return false;
        if (currPoints >= K) {
            bestTime = currTime;
            return false;
        }
        if (firstMission >= N)
            return true;
    
        int remPoints = K - currPoints;
    
        for (int i = firstMission; i <= N; ++i) {
            bool isFirst = (i == firstMission);
            const Mission& im = missions[i];
            if (currPoints + im.tailPoints < K)           // tailPoints = сумма очков по хвосту от missions[i] до конца
                return isFirst;
            float wantedTime = currTime + remPoints * im.ratio;    // ratio = (float)m.time / m.points;
            if (wantedTime >= bestTime)
                return isFirst;
            if (recurse(i + 1, currPoints + im.points, currTime + im.time))
                return isFirst;
        }
        return false;
    }

    Миссии, как и раньше, отсортированы по ratio по возрастанию.

    И последняя моя идея, в разы ускорившая перебор, такова. Рекурсивная функция возвращает true, если весь разрешённый «хвост» безнадёжен и в нём искать больше нечего. Это происходит при таких условиях.
    1. Хвост пуст.
    2. Хвоста недостаточно, чтобы получить K очков.
    3. Простейшая экстраполяция по 1-й миссии провалилась.
    4. Уже первый рекурсивный вызов говорит: хвост безнадёжен.

    UPD2. Ну и вторая идея, которая там есть. Если хвост безнадёжен, то меньшие хвосты безнадёжны и подавно.
    Ответ написан
  • Какие обьекты удалять в деструкторе?

    @Mercury13
    Программист на «си с крестами» и не только
    После того, как отработает тело деструктора, для всех полей объекта автоматически вызываются деструкторы, в обратном порядке.
    У int и double деструкторы нулевые — но другие-то и не нужны.

    В каких случаях надо писать деструктор самим…
    1. Мы владеем каким-то ресурсом, но штатный деструктор его не уничтожает.
    • Простой (не умный) указатель и выделенная память — это хорошо описал sitev_ru .
    • Объект-блокировщик, например, мьютекса (мьютекс — примитив межпоточной синхронизации, не дающий зайти в определённые участки кода одновременно двум потокам).
    class Mutex {
    public:
      void enter();
      void leave();
    }
    
    class Lock {
    public:
      Lock(Mutex& aMutex) : mutex(aMutex) { mutex.enter(); }
      ~Lock() { mutex.leave(); }
    private:
      Mutex& mutex;
    }
    
    …
    Mutex mutex;
    { Lock lock(mutex);
      // всё, что здесь, выполняется внутри мьютекса.
      // Даже если выпадет авария, из мьютекса корректно выйдем.
    }

    2. Сложный порядок уничтожения. Односвязный список из std::unique_ptr будет работать и так, со штатным деструктором, но это чревато переполнением стека.
    3. Сложная структура владения, и при уничтожении надо автоматически отобрать объект у владельцев. По-чёрному используется в оконных фреймворках на манер VCL и Qt. Удаляем компонент — он автоматически отбирается у владельца.

    По опыту: если структуры данных выносить в отдельный объект (ну и использовать STL, где можно), 80% объектов Си++ будут с автоматическим деструктором.

    ЗЫ. По результатам прикидочных подсчётов в живом проекте, ≈150 файлов (реально файлов 219, но не все наши собственные; библиотечные деструкторы не учитывал).
    • Классов с настоящим деструктором — около 30. Большей частью системные (W32Cs — быстрый мьютекс Win32) или структуры памяти (Array1d, например). Из них в собственно проекте (не в личной библиотеке программиста) — три (!): один связан с автовладением чужой библиотекой XLSX, два — с фоновыми потоками.
    • Интерфейсов с пустым виртуальным деструктором — порядка 40.
    • И ещё деструкторы, автоматически добавленные Qt — по числу форм, ровно 20.
    • И единицы пустых деструкторов, добавленных по желанию левой пятки линкера.
    Ответ написан
    Комментировать
  • Будет работать монитор?

    @Mercury13
    Программист на «си с крестами» и не только
    Максимальное разрешение определяется пропускной способностью DVI/HDMI/DP. Судя по Вике, это действительно максимальное разрешение монитора на DVI Dual Link 60 Гц.
    Поскольку вы подключили два монитора, параллельно действуют два чипа, и никаких проблем.
    Существуют видеоплаты/мониторы, которые дают нужную вам пропускную способность по ДВУМ кабелям, подключённым в параллель к одной видяхе и одному монитору, но это, видимо, не ваш вариант.
    Ответ написан
    Комментировать
  • Как подсчитать комбинацию шагов коня на матрице 4 на 3?

    @Mercury13
    Программист на «си с крестами» и не только
    Твоё дело — перебор с кэшированием.
    Для каждой кнопки вручную закидываем в массив конских «соседей» — ни одного для 5-ки, три для 4 и 6, два для остальных.
    Затем заведи массив 10×7 (стартовая кнопка×длина) и устрой рекурсию с одним небольшим добавлением: если оно закэшировано, брать из кэша. Правила — f(b, 1) = 1, для остальных — sum{c=сосед(b)} f(c, i−1).
    Можно и динамическим программированием, без рекурсии — всё равно расход вычислительной мощи незначительный. Сначала f(b, 2), затем f(b, 3), и т.д. до 7.
    Ответ написан
  • Соединение точка-точка через интернет?

    @Mercury13
    Программист на «си с крестами» и не только
    Первое, что нужно проверить,— провести сессию в пределах одного компьютера с соединением по localhost или 127.0.0.1. Там никакая настройка роутера не помешает.

    Потом — в пределах одной локальной сети по внутрисетевому адресу. Это первый выход в настоящую сеть!

    Затем можно попробовать и через Интернет.

    Если соединялись из той же сети по внешнему IP-адресу роутера: такой маршрутизации (т.н. NAT hairpin) по умолчанию нет, но в некоторых роутерах бывает: пакет, пришедший из внутренней сети на внешний адрес, считается пришедшим извне.

    Если вы соединялись из другой сети (разумеется, по внешнему IP-адресу): проверьте настройку маршрутизатора. Убедитесь, что внешний адрес на маршрутизаторе — реальный интернетовский. Попробуйте наладить другой сервер (например, Апач или игровой). Как правило, после всех этих мытарств проблем не бывает.

    Если «извне» — это работа, то, вероятно, куча портов перекрыта. Тоже стоило бы проверить.
    Ответ написан
  • Освобождается ли память по завершению выполнения функции, если массив инициализировать внутри функции?

    @Mercury13
    Программист на «си с крестами» и не только
    char * a = "hello!";
    Для указателя a — разумеется, на стеке.
    Строка, на которую он смотрит, "hello",— строковый литерал. Для него память изначально, при пуске программы выделена в сегменте данных. Освобождать не надо. На многих платформах — хоть на это рассчитывать не надо — этот сегмент защищается от записи и при попытке туда записать AV.
    Ответ написан
    8 комментариев
  • Разработка под Windows - MSVC или TDM GCC (MinGW)?

    @Mercury13
    Программист на «си с крестами» и не только
    3) Использование инициализации списком для структур (POD) с уже прединициализированными полями:

    Это C++11. Хорошее дело. MinGW поддерживал, пока стандарт ещё вырабатывался. MSVC начал было, да бросил и довёл до конца аж в 2015!!

    1) Разное содержимое одних и тех же хедеров

    Не выбивается из стандарта.

    2) MSVC спокойно компилирует нечто вроде

    MSVC ошибается, таким образом неконстантную ссылку передавать запрещено.

    но при этом не компилирует код, если не-void функция не возвращает значение

    Хорошая диагностика, но это лишь warning, а не error. Компилятору трудно знать, возможен ли тот или иной путь исполнения кода.
    Ответ написан
    Комментировать
  • Не понимаю, что такое модульная сетка?

    @Mercury13
    Программист на «си с крестами» и не только
    Первое определение говорит о вёрстке вообще. И даже второе слишком общее. Более-менее правильное такое.

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

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

    На ватмане эти направляющие рисовали, потом стирали. На компьютере — они находятся где-то на непечатаемом слое и блоки к ним прилипают.

    Всегда следовать модульной сетке? Нет, конечно. Дизайнов разных куча. Где он академичнее, там модули; где закос под что-то неформальное — стараются модули делать там, где пишущий краской на стене действительно сделал бы две вещи одинакового размера. А иногда выровнять одно с другим — это натянуто.

    Я бы дал такие правила.
    1. Не впихивай невпихуемое. Если не получается выровнять по художественным или техническим причинам — зачем это прокрустово ложе?
    2. Не мельчи модуль. Если не видно, что размеры кратны — пропадает смысл.
    3. Модуль не обязательно один. Высота картинки и высота строки могут быть некратны, например, если нет обтекания картинок текстом.
    Ответ написан
    3 комментария