• Что такое пул в программировании?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    pool - переводится не только как "бассейн", но и как "общий фонд". Пул в пограммировании - это набор однотипных ресурсов, которые переиспользуются по мере надобности. А при осовбождении - возвращаются в общую кучу. Так экономятся расходы на создание и уничтожение этих ресурсов. Бывают пулы почти чего угодно: потоков, буферов, каких-то объектов.

    Например, вместо того, чтобы запускать поток под каждое новое подключение в сервере, у вас есть 20 потоков, которые просто ничего не делают, а когда появляетсся подключение, какой-то из свободных потоков его обрабатывает. Если свободных потоков нет, возвращается ошибка, или соединение ждет в очереди. Когда оно обработано, поток возвращается в пул, вместо уничтожения. Это работает хорошо, потому что создание потоков - сложная и дорогая операция. Гораздо дешевле поток усыпить и засунуть какой-то дискриптор в какую-то структуру данных.
    Ответ написан
    Комментировать
  • Как избавить от заданных размеров количества строк и столбцов при считывании из файла?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Читайте построчно до конца файла. У вас уже эта проверка есть там, где вы fscanf делаете - вы же проверяете, что оно вернуло? А столбцов у вас всегда 3.

    Если проблема с тем, что у вас массив, куда вы читаете, ограниченного размера, то можно, например, завести его достаточно большой длины, с запасом. Как у вас там 101 символ выделен под кажую строку. А еще лучше, если у вас C++, использовать std::vector - ему можно длину динамически менять. Если же это C - то пишите свою собственную логику увеличения массива, через malloc и realloc по мере заполнения.
    Ответ написан
    Комментировать
  • Что подразумевается под поиском двух линий при создании контейнера?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    У вас есть куча вертикальных столбиков с заданными высотами. Вам надо взять 2 столбика так, чтобы между ними было больше всего воды. Они образуют загогулину вроде |____| - это и есть контейнер, в котором может быть вода (если мир двумерный). Например если в примере взять самый левый (1) и самый правый (7) столбики, то высота воды будет 1 (иначе она слева выльется), а ширина будет 8 - итого получается 1*8=8 единиц воды.

    Формально, вам надо найти такие i<j, что min(h[i],h[j])*(j-i) максимально.
    Ответ написан
    2 комментария
  • Как исправить ошибку undefined reference to при коспиляции кода с++ в VS?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Как собираете проект? Ошибка в том, что линкер не может найти определение метода, потому что оно в другом cpp файле, а он не включен в сборку.
    Ответ написан
  • Преобразование шрифта?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Этот текст - это символы Unicode.

    Например, "б" в слове "большое" - это символ 0x0431

    Проблема в том, что там символы не из одного алфавита, а полная солянка. На этом сайте можно получить коды всех символов: https://www.rapidtables.com/convert/number/ascii-t...
    Получите:
    1D04 1D00 28D 43E 1D07 20 431 43E 1D27 44C 26F 43E 1D07 20 28D 43E 1D29 1D07


    Как видите, они все разбросаны довольно сильно. 1D** - Phonetic Extensions . 04** - Cyrillic, 02** - IPA Extensions

    Символы из разных алфавитов подобраны по внешней похожести на нужные буквы (как Ш - это перевернутая m вообще). Наверно, какой-то онлайнг конвертер вроде этого где-то имеет набор из 33 кодов и подставляет их вместо русских букв. Не знаю, есть ли такой обратный.

    Можно написать обратный конвертер на том же питоне, только надо руками сопоставить каждому символу из текста нужный символ из обычного ascii. Например, заведите солварь (вам надо руками все встречающиеся символы в исходной строке туда добавить):
    convert = {'ᴀ': 'а', ... 'ʍ':'м', ...}

    Потом примените его ко всем символам в вашей строке каким-нибудь map().
    Ответ написан
    Комментировать
  • Адрес сайта с нормальными гайдами по алгоритмам?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Есть русский сайт e-maxx.ru/algo
    Есть сборник кучи алгоритмов, но там мало объяснений: https://rosettacode.org/wiki/Rosetta_Code
    Ответ написан
    2 комментария
  • Как переделать код согласно современным стандартам?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вам точно надо, чтобы значение класса нельзя было перемещать? Если вы только разрешите конструктор и оператор перемещения, то можно будет засунуть ваши элементы в обычный std::vector.
    Ответ написан
  • Как соединить рандомные точки на координатной плоскости в многоугольник?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Выпуклая оболочка, предложенная Vindicar, может соеденить не все точки. Какие-то будут просто внутри. Как в примере с картинки в вопросе, оболочка будет теругольником, а точка по центру будет не соединена ни с чем.

    Надо точки как-то отсортировать. Например, берете самую нижнюю, из всех таких самую левую. Сортируете все оставшиеся точки по углу, относительно этой (по значению atan2(yi-y0, xi-x0)), при равенсве угла по расстоянию (не важно по возрастанию или убыванию). Потом в таком порядке их соединяйте, пересечений не будет.

    В примере из вопроса оно как раз отсортирует их как на картинке.

    Edit, а еще, можно вместо atan сравнивать углы через векторное произведение. Если входные данные - целые точки, то вообще все вычисления будут в целых переменных.
    Ответ написан
    3 комментария
  • С++ Как правильно вернуть ссылку?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ссылка - это как указатель, только она не может быть нулевой.
    Поэтому никак нельзя вернуть *nullptr_t вместо ссылки на переменную, в отдельных случаях.

    Вообще, у вас там разыменование нулевого указатяля, что есть UB и делать это категорически нельзя.

    Второй пример ошибок не содержит, но очень странен. Возвращать ссылку на какую-то переменную, только для того, чтобы не переписывать нужное значение? Все с ног на голову перевернуто.

    Вам лучше подойдут указатели.
    Ответ написан
    2 комментария
  • Как доказать, что группы неизоморфны?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Надо найти какое-то противоречие в структурах групп.
    Например, в C есть элементы {1, i, -1, -i}. Это 4 различных элемента которые при умножении сами на себя дают 1. Если группы изоморфны, то должны быть 4 соответствующих им элемента в R, все - квадратные корни из 1. Но в R таких только 2: {1, -1}.

    Во втором примере можно привязаться к 0. в Q есть 0, умножив на который всегда получится 0. Но нет элемента, прибавив которой всегда получится одно и то же число.

    Опять же, 0 в {Q, *} не имеет аналога в {R, +}
    Ответ написан
    Комментировать
  • Поможете сделать код лучше, чем у меня сейчас, a³+b³=c³?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    2. Этот код не для Windows;


    Там нет ничего платформо-зависимого. Если установите какой-нибудь mingw на windows, то оно makefile съест.

    В крайнем случае, установите любой C компилятор и введите команду вручную (последняя строчка тут)

    3. Если я в формуле a³+b³+c³=3 поменяю 3, на 0 будет ли программа правильно считать?

    Там в описании написано "cubefree k = +/- 3 mod 9 at most 1000", т.е. для k=0 не сработает.

    Поможете сделать код лучше?


    Выкиньте цикл по c. Вам не надо его перебирать, а вам надо решить уравнение c³=3-a³+b³.
    Для чего просто вычислите значение справа, потом возьмите кубический корень: int((3-a**3-b**3)**(1/3.0)). Не забудьте только проверить, что это значение c подходит, ибо тут корень округляется до целого. И не факт, что уравнение выполняется.
    Ответ написан
  • Насколько хорошая практика использовать обертки над операторами?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В библиотечных функциях - можно так сделать. В смысле, ваши функции используют непубличную функцию, передавая ей оператор.

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

    И вообще, довольно редко есть смысл так заморачиваться. Код становиться хуже поддерживаемый. Экономите вы совсем чуть чуть повторяемого кода. А потом придется всякие заморочки делать, вроде, в делении надо проверять на 0, а в умножении проверять на переполнение и т.д. Этот общий код становиться уже чуть ли не длиннее если все по отдельности делать. И уж точно хуже читаемый.
    Ответ написан
    Комментировать
  • Алгоритм поиска маршрута?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    В питоне есть библиотека для работы с графами NetworkX. И там есть уже реализованные алгоритмы кратчайших путей.

    Это будет быстрее, чем самостаятельно реализовывать какой-нибудь алгоритм Дейкстры или обход в ширину, ибо питон - безбожно тормознутый язык. А в библиотеке вычисления обычно реализованы на более быстрых языках.
    Ответ написан
    1 комментарий
  • Как решить эту задачу?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    У вас 7 неизвестных и 3 уравнения. Так что однозначно вы найти значения переменных никак не сможете. Но и найти вам надо какую-то сумму. Есть шанс, что как-то комбинируя, складывая, вычитая и домножая левые части этих уравнений можно получить искомую сумму. Иными словами, вам надо вектор (16, 25..100) представить в виде линейной комбинации векторов (1, 2..49), (4, 9..64) и (9, 16..81). Обратите внимание, что там везде получаются суммы трех квадратов равны следующему.

    Вам надо подобрать такие 3 коэффициента, что x*n^2 + y(n+1)^2+z(n+2)^2 = (n+3)^2. Для n=1..7. У вас тут квадратные многочлены от n получаются, равны они в 7 точках, так что они должны быть равны вообще при любых n. Значит, вам надо раскрыть скобки, сгрупировать степени n и приравнять к 0 все коэффициенты.

    Так вы получите 3 уравнения на 3 переменные x, y, z.
    x+y+z=1
    2y+4z=6
    y+4z=9

    Отсюда получается x=1 y=-3 z=3

    В итоге получаете 1*1-3*12+3*123 - это ваш ответ.
    Ответ написан
    2 комментария
  • Какой самый быстрый способ найти позицию последовательности 0-bit заданной длины в int[]?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Зависит от длины n. Если n маленькое то можно прикладывать маску. Байт x содержит 3 ноля в последних битах, если ~x &0x7 == 0x7. Аналогично, сдвигая маску из трех единиц (0x7) можно приложить ко всем позициям.

    Если n большое, то надо чтобы было много нулевых байт в массиве подряд. Тут можно использовать SSE инструкции для массового сравнения байт с нулями.

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

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Ну ведь тут массив же отсортирован. Хоть и с приколом: он сдвинут. Можно тем же бинарным поиском найти, где там "разрыв" происходит, а после у вас 2 отсортированных куска. Или сразу модифицировать бинпоиск.
    Представьте, что у вас массив, где сначала идут 1, а потом 0. Можете найти в нем, где 1 переходит в 0?

    Или смотрите так: ищите вы x. Взяли значение a[m]. Можете, посмотрев на a[l], a[m], a[r] и x понять, в какой половине лежит x?

    Edit: ах, тут числа могут быть одинаковыми. Тогда бинпоиск тут не работает. Ибо может быть тест {1,1,1,2,1,1} - и тут можно 2 в любую позицию поставить. И, если вам надо эту 2 найти, то вам придется просмотреть все числа, иначе вы ее не найдете. Бинпоиск возможен, если первое и последнее числа разные.
    Ответ написан
    3 комментария
  • Как на udp сервере подсчитать one-way latency и верменной offset клиента?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Надо клиенту в пакете отправлять время получения и отправления в пакете.

    В итоге сервер получит 4 таймстампа: сервер отправил, клиент получил, клиент отправил, сервер получил. При этом два серверных и два клиентских - могут быть в разных часах. Поэтому надо взять t4-t1+t2-t3 - и вы получите rtt. Поделите на 2, получите оценку нужной задержки. И это надо сглаживать по многим пакетам.

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

    Однако, если вы часы синзронизируете, то вам надо постоянно пересчитывать отставание по последнему пакету и оценке rtt. И этот сдвиг часов будет изменятся со временем а соответствии с разной скоростью часов.
    Ответ написан
    Комментировать
  • Какой структурой можно повесить lock на диапазон?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Если у вас диапазоны такие маленькие, то можно прямо в классе буфера завести еще и массив mutex-ов. И каждый поток будет их лочить слева на-право по всему диапазону (важно, что каждый поток делает это в одном и том же порядке, а то дедлоки получите).

    Тут "выделение" куска будет не такой тривиальной операцией, как один лок, но зато, никах спинлоков. Система может потоки усипить и будить только когда очередной мютекс освободится.

    Если же у вас ожидаются интервалы побольше 100, то тут возможно лучше будет вот такое решение:
    У вас будет одна глобальная структура-индекс, где вы будете хранить статус буфера (о ней позже). Потоки будут к ней обращатся и просить у нее выделить потоку кусок.
    Внутри этой структуры, похоже, придется сделать один глобальный мьютекс.
    В качестве самой структуры хорошо подойдет дерево отрезков с отложенным добавлением. Пусть оно будет считать сумму на отрезке. При запросе на выделение вы смотрите, равна ли сумма на запрошенном отрезке 0. Если да, то прибавляете на отрезке 1. Если нет, то возвращаете неудачу и поток должен будет опять обратиться к структуре. При освобождении интервала прибавляйте -1.

    Тут операция выделения сама по себе будет сильно быстрее. Но это фактически спинлок - каждый поток будет в цикле пытаться выделить себе интервал, пока не сможет. Если ожидается, что потокам придется долго ждать, то надо какие-то стратегии back-off добавлять (спать между вызовами). И вообще спинлоки - это плохо.

    Как сделать это без спинлоков с деревом отрезков - я не придумал.
    Ответ написан
    Комментировать
  • Как показать зависимость скорости от O(nlogn)?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Можно, только надо числа брать побольше. Скажем, 100000 и 1000000. Для полносты картины можно взять несколько точек. Еще возьмите, например, 5000000 и 10000000.

    Но вообще сложность алгоритма обычно доказывают логически. Типа, у вас там n операций с кучей, каждая операция ограничена O(log n) - потому что она проходит по бинарному дереву с менее чем n листьями, а значит, высотой менее log n.
    Ответ написан
  • Ошибка double free or corruption (out) Aborted, как исправить?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы никакого free и даже delete или new в программе не делаете. Значит ошибка в том, что структуры менеджера памяти как-то портятся. Это значит, что вы пишите куда-то за границы массива.

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

    Подозреваю, что ошибка тут:
    int mli=index(len,ml),mpi=index(len,mp);
    Обратите внимание на второй вызов index. Вы ищите в массиве len значение mp, которое вы нашли в массиве price. Возможно оно возвращает -1 и дальше уже вы пытаетесь что-то делать в векторе по этому индексу, что вряд ли закончится хорошо.
    Ответ написан
    Комментировать