Задать вопрос
  • Как в графе найти самый "большой" полный подграф?

    @Mercury13
    Программист на «си с крестами» и не только
    Это штатная задача, т.н. «задача о клике», NP-полная. Ничего лучше усовершенствованного перебора не существует.
    https://ru.wikipedia.org/wiki/Алгоритм_Брона_—_Кербоша
    Ответ написан
    Комментировать
  • Как отсортировать "случайно", с возможностью отсортировать так же в будущем?

    @Mercury13
    Программист на «си с крестами» и не только
    У генератора псевдослучайных чисел есть такое понятие, как «случайная затравка» (random seed). Затравку берут из истинно случайных мест вроде счётчика тактов процессора. Достаточно сохранить затравку — и последующие запуски генератора дадут те же результаты.

    Допустим, манипуляции с затравкой есть вот тут.
    php.net/manual/ru/function.mt-srand.php
    Ответ написан
    Комментировать
  • Почему выражение делится на 6?

    @Mercury13
    Программист на «си с крестами» и не только
    Разложим на множители, получается mn(m−n)(m+n)(m²+n²). А теперь думаем.

    Делимость на 2. Или m делится, или n, или m+n.
    Делимость на 3. Хоть у одного остаток 0 — делимость налицо. У обоих 1 или 2 — делится m−n. У одного 1, у другого 2 — делится m+n.

    Значит, делится на НОК(2,3) = 6.
    Ответ написан
    2 комментария
  • Какой хэшкод является идейно верным?

    @Mercury13
    Программист на «си с крестами» и не только
    Существуют так называемые криптографические хэши, задача которых — сделать, чтобы генерация двух документов с одинаковым хэшем была вычислительно невозможна. Если хэш удлиняется на два бита, эта задача усложняется, насколько мне известно, не вчетверо, а вдвое.

    Потому криптографические хэши огромные (устаревший MD5 — 16 байтов, большинство современных — 32 или 64). Как его записать в БД, если и тип такой не всегда есть, а BLOB’ы — пальба из пушки по муравьям? Как-то закодировать в строчку. К тому же в вебе есть места, где двоичные данные не катят и без строчного кодирования никак (например, URL’ы).

    Автор, очевидно, мэн из лагеря Perl/PHP и в дополнение к вычислению хэша взял и закодировал его. Вероятно, методом BASE64 (8 символов BASE64 соответствуют 6-байтовому хэшу). Для чего так кодировать обычные, не криптографические хэши — я вообще не знаю!
    Ответ написан
    Комментировать
  • Как построить треугольник?

    @Mercury13
    Программист на «си с крестами» и не только
    Этот код вычисляет координату верхней вершины треугольника.

    2,3 — полученная обмерами конкретного экрана пропорция пикселя. Расчётная 2,4 = (640·3) / (200·4), и заметно, что на эмуляторе треугольник слегка сплюснутый.
    √3 / 2 — высота треугольника при единичном основании.
    Координаты вершин (100, 160), (400, 160) [основание соответственно 300]. Какие (X, Y) у третьей?
    X3 — среднее между ними, основание 300, ну а Y3 = 160 − 300·(√3 / 2) / aspect.

    Первое, что вам придётся сделать на современном компьютере — избавиться от коэффициента 2,3: пиксели-то сейчас квадратные. Затем как можно больше констант сделать производными. Например:
    TriangleX = 100
    TriangleY = 50
    TringleSide = 300
    Sqr32 = Sqr(3) / 2
    TriangleHeight = TriangleSide * Sqr32
    X1 = TriangleX
    Y1 = TriangleY + TriangleHeight
    X3 = X1 + TriangleSide
    Y3 = Y1
    X2 = X1 + TriangleSide / 2
    Y2 = TriangleY

    UPD. Я поменял местами X2/X3 так, чтобы оно сходилось с экраном. И ты не забудь. То есть, 400 — теперь это будет X3!!!
    Ответ написан
  • Java или C++ в качестве первого языка. Что выбрать?

    @Mercury13
    Программист на «си с крестами» и не только
    Только Java. Почему…
    1. Достаточно удачная стандартная библиотека.
    2. Проверка массивов на индекс — для начинающего бесценно.
    3. Не настолько полагается на указатели, когда человек ещё толком не знает, что это такое.
    4. Очень строгая проверка типов.
    5. Статическая типизация, Си-подобный синтаксис (хотя всё это у обоих).
    6. Сообщения об ошибках не настолько страшны (стандартная библиотека Си++ полагается на шаблоны).
    Вторым языком человек уже съест что угодно, но Си без плюсов — один из худших первых. Си++ не так плох, но Java, по-видимому, лучше.
    Ответ написан
    4 комментария
  • Как вывести уравнение прямой в R3 пространстве через точку и направляющий вектор через определитель?

    @Mercury13
    Программист на «си с крестами» и не только
    Через векторы: M = M0 + td, t — параметр.
    (мы различаем точку M0 и вектор td, но точка + вектор = точка)
    По координатам: x = x0 + pt, и т.д.
    Выпишем, чему равняется t, и получаем наше уравнение.
    Ответ написан
    Комментировать
  • Как решить ошибку LNK2019?

    @Mercury13
    Программист на «си с крестами» и не только
    Судя по всему, эти функции в библиотеках OpenGL. Надо включить в проект opengl32.lib (и, возможно, glu32.lib).
    Ответ написан
  • Задача "Бинарные числа"?

    @Mercury13
    Программист на «си с крестами» и не только
    (n > 0) and (n and (n - 1) = 0)
    Раз у вас паскаль, первый AND логический, второй битовый.
    Второе условие — стандартный программистский приём, срезающий последний единичный бит.

    UPD2. Да, ты меня слегка перехитрил с алгоритмом, но, нем не менее…
    1. Если число <= 0 — без единой итерации пишет YES, что неверно.
    2. Если у вас условие сложное — лучше разделить программу на проверку условия (подпрограмму или переменную типа boolean) и реакцию на это условие.
    3. Стандартная ошибка начинающих: допустим, не сработало условие N mod 2 = 1. Зачем писать N mod 2 = 0, если есть else?
    Ответ написан
  • Как передать вывод?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Чтобы получить ссылку на CMD.EXE, прочитайте переменную окружения COMSPEC.
    2. Не используйте ShellExecute для запуска того, что гарантированно программа, для этого есть CreateProcess.
    3. Да, и не забывайте, что ShellExecute заканчивает работу, когда программа пошла на исполнение. Если нужен результат исполнения — всё тот же CreateProcess + ввод-вывод через каналы + WaitForSingleObject.
    Ответ написан
    Комментировать
  • Принцип работы анимации?

    @Mercury13
    Программист на «си с крестами» и не только
    time — это длительность такта (в игре, очевидно, не просто переменный FPS, но и переменная тактовая частота). Писал такое, правда, не в платформере, а в гоночке.

    rect.left — это точное решение дифура left′ = dx (движение с постоянной скоростью). Очевидно, dx где-то устанавливается по управлению.

    rect.top и dy — это приближённое решение дифура top′′ = 0,005, если снят флаг onGround (полёт под действием силы тяжести). Здесь 0,005 — это ускорение силы тяжести, ось Y направлена вниз. Дифур второго порядка, преобразуется в систему top' = dy, dy′ = 0,005, и то, что в первом случае было точным, здесь приближённое, но приемлемое для игр.

    currentFrame просто прокручивается, чтобы 6-кадровая анимация прошла за 1200 тактов, независимо от частоты. Здесь 1200 = 6 / 0,005.

    Заметьте, dx и dy проходят по разным трактам данных: один — состояние управления, второй — состояние физики персонажа. К тому же что делает dx = 0 и где он ставится не в 0, чтобы не зависеть от частоты автоповтора клавы — непонятно. И много магических констант. Говнокод.

    UPD. Прямые ответы на ваши вопросы.
    1) 6-кадровая анимация, но тут одно из двух. Либо из-за огромного цикла (1200 тактов) явно анимируются не ноги. А может, афтар гонит такты с предельной частотой и потому 1200 тактов действительно пройдут за секунду-две, но тогда это слишком уж явная привязка к скорости компьютера;
    2) в зависимости от номера кадра выбираем тот или иной спрайт на атласе;
    3) dy — скорость, и чтобы откорректировать положение (rect.y), надо прибавить к нему скорость·время.

    UPD2. Кроме того, непонятно, почему в коде анимации нет бега в разные стороны. Хотя из-за крайне простой физики есть подозрение, что жанр — бесконечная бегалка.
    Ответ написан
    3 комментария
  • Как продумать геймплей, чтобы он был завлекающий и сбалансированный?

    @Mercury13
    Программист на «си с крестами» и не только
    К сожалению, геймдизайн — это очень творческая профессия, и Extra Credits предупреждает: дизайн, базирующийся на собранных данных, не делает нового, он только оттачивает имеющееся.
    https://www.youtube.com/watch?v=nqGcXOksFGg

    Может быть, это вам и нужно — заработать побольше денег на клоне Dota (PUBG, Candy Crush, Angry Birds). Но про творчество попытаюсь рассказать.

    1. Ходите на художественные выставки.
    2. Играйте во что угодно, впрочем, необычным образом. Во-первых, играйте не только в любимые жанры, но и в файтинги, RPG, симуляторы и прочее. Во-вторых, часто хватит потратить на игру четыре-пять часов. В-третьих, прикарманивайте их решения. В четвёртых, ищите поломы системные (например, где-то ∞ денег) и поломы отдельной подсистемы (застревающая камера). Намеренные ли эти поломы? Мешают ли играть?
    Ответ написан
    Комментировать
  • Нету вывода из массива с указателями из структуры с++?

    @Mercury13
    Программист на «си с крестами» и не только
    Первое и главное. Удивительно, что у вас программа заработала, ведь text.sentences не инициализировано. У меня вылет.

    Ну и извечная ошибка начинающего «плюсовика»: память выделяется, непонятно, кто чем владеет, и, разумеется, память «течёт». Для чего, извините, в Си++ сделали инкапсуляцию, конструкторы и деструкторы?
    Ответ написан
    Комментировать
  • Почему компилятор не видит конструктор?

    @Mercury13
    Программист на «си с крестами» и не только
    Нет, дело не в этом. Линкер не может найти среди OBJ-файлов конструктор MyDb::MyDb. Очевидно, mydb.cpp не скомпилировался или не подключён.
    1) Убедиться, что mydb.cpp включён в проект. 2) Build → Run Qmake.

    Гуглите понятие «единица трансляции» и что делает линкер.
    Ответ написан
    1 комментарий
  • Зачем прописывать методы в Interface когда можно так же в классе?

    @Mercury13
    Программист на «си с крестами» и не только
    Ответ явоспецифичный. Потому что один класс может реализовать сколько угодно интерфейсов, но наследуется лишь от одного класса.

    Ответ концептуальный. Ромбическое наследование. От А наследуются B и C, от них обоих наследуется D.
    1) Если в A есть поле, в D что, это поле будет в двух экземплярах? А если оно protected и в B мы добавили метод, который его меняет?
    2) Если B и C переопределяют какой-то метод foo(), как быть D? А если нужна и версия B.foo(), и C.foo(), и они обе вызывают A.foo — получатеся D.foo вызовет A.foo дважды? А если в C есть второй метод bar(), который вызывает foo() и начинает вести себя не так, как надо, если мы берём реализацию B.foo()?
    В общем, множественное наследование — хорошая штука, но ромбическое — штука опасная. В языке, где любое множественное наследование неизменно ромбическое, всё, что остаётся — делать такие условия, при которых ни 1, ни 2 не сработает.
    Одно из таких условий — унаследоваться от одного класса и нескольких интерфейсов. 1) У интерфейса нет полей, и 2) эталонная реализация, существующая в некоторых языках программирования, в любом случае менее приоритетна, чем конкретная реализация из класса. Вызывать ту и другую нет смысла: если программист написал свою сверх эталонной — значит, он хочет сделать то же другим путём.
    Ответ написан
    Комментировать
  • Какое время жизни объекта в std::unique_ptr?

    @Mercury13
    Программист на «си с крестами» и не только
    Уничтоженный unique_ptr уничтожит ваш объект.

    «Уничтожит» — это значит, вызовет деструктор и сделает память доступной менеджеру памяти. Теперь другие указатели, которые смотрят на этот объект, будут «висячими», и при их разыменовании программа может сделать ЧТО УГОДНО.

    А теперь посмотрим, что именно ей угодно. Ваша функция foo() невиртуальная и не имеет дела с полями, ей нужен только this (указатель на объект), который даже не разыменовывается. Она в принципе не может вылететь, даже если десять раз занулить этот объект!

    То, что вы хотите сделать — это семантика std::shared_ptr/weak_ptr.
    std::shared_ptr<ttt> sh1 = std::make_shared<ttt>();
    std::weak_ptr<ttt> we = sh1;
    {
      std::shared_ptr<ttt> sh2 = sh1;
      sh1 = nullptr;
    }
    std::cout << we.expired();  // должно быть true


    UPD. Вот для таких, как ты, и ввели в C++14 функцию std::make_unique, по аналогии с std::make_shared. Просто чтобы было меньше таких ошибок.
    Ответ написан
    Комментировать
  • Как заполнить двумерный массив?

    @Mercury13
    Программист на «си с крестами» и не только
    var // ну или const
    masMask: array[1..3, 1..3] of string = (
      ( '11', '12', '13' ), ( '21', '22', '23' ), ( '31', '32', '33' )
    );

    ВНИМАНИЕ! Я не проверял, как оно работает, когда это локальная переменная (var).

    UPD. Проверил, нельзя. Var работает только если массив глобальный. Const, разумеется, работает всегда, ибо создаёт глобальный массив и запрещает туда писать. Если же нужно инициализировать локальный var, надо объявить тип
    type TSomeTable = array[1..3, 1..3] of string;
    создать какую-то константу
    const masStart: TSomeTable = …;
    var masMask : TSomeTable;

    а затем в начале masMask := masStart;

    UPD2. Для чего объявить тип? Читайте правила эквивалентности типов в Паскале, они жёстче, чем в Си. И тот учебник, по которому я учил Паскаль (Зуев), особо упоминает, что два одинаковых array не эквивалентны.

    UPD3.
    months = (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec);
     — это не массив! Это перечисляемый тип. Кстати, из-за правил пересечения идентификаторов очень не советую писать типы и перечисляемые константы без венгерской записи, к тому же название months сбивает с толку. Лучше будет TMonth = (monJan, monFeb, …);.
    Ответ написан
    Комментировать
  • Как применяется закон Бенфорда для второй цифры?

    @Mercury13
    Программист на «си с крестами» и не только
    Распределение второй цифры неравномерное, но малозаметное на практике. Например, для нуля будет.
    p0 = (lg 11 − lg 10) + (lg 21 − lg 20) + … + (lg 91 − lg 90)
    Ответ написан
    Комментировать
  • Где найти новые детерминированные игры с полной информацией?

    @Mercury13
    Программист на «си с крестами» и не только
    Есть разумеется.
    18 век: https://en.wikipedia.org/wiki/Agon_(game)
    19 век: https://ru.wikipedia.org/wiki/Реверси
    20 век: https://ru.wikipedia.org/wiki/Перебрось_мостик
    20 век: https://ru.wikipedia.org/wiki/Гекс
    20 век: https://en.wikipedia.org/wiki/Quoridor
    21 век: https://ru.wikipedia.org/wiki/Улей_(игра)
    21 век: https://ru.wikipedia.org/wiki/Khet

    Почему таких игр крайне мало?
    1. Мы автоматически отбрасываем часть позиций как неперспективные — потому, чтобы обеспечить ту же просчитываемость, ДИсПИ должна быть намного богаче тайной или случайной. Некоторые механики придётся отбросить, поскольку, например, заимствованием стратегии доказывается, что первый выигрывает.
    2. Из двух игроков разной силы один выигрывает с вероятностью, стремящейся к 100%, игра быстро теряет интерес. А ведь как важен такой интерес для новой игры, которая пока продвигается…
    3. Продвигается исключительно гиками: сложно сыграть, например, папе с дочкой.
    UPD. 4. Крайне сложно сделать, чтобы компьютер косплеил человека. Другими словами, совершал ошибки, свойственные человеку, и при попытках подловить тупой алгоритм ходил как угодно, лишь бы по-другому.

    А насчёт шахмат — от первых упоминаний до современных правил прошло тысячелетие! Догадываетесь, какие плейтесты они прошли, чтобы из банального варгейма стать тем, чем они являются сейчас (хотя тоже, по всей видимости, были популярны в первую очередь у верхушки общества).
    Ответ написан
    5 комментариев
  • Разделение строки из символом в массив?

    @Mercury13
    Программист на «си с крестами» и не только
    // считать строчку
    std::string s;
    std::getline(std::cin, s);
    // …и разбираем её потихоньку через поток-строку
    std::istringstream is(s);
    int i;
    std::vector<int> v;
    while (is >> i)
      v.push_back(i);
    Ответ написан
    Комментировать