Ответы пользователя по тегу JavaScript
  • Как расположить плоскую текстуру сегмента на кольцо?

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

    x_r = (sqrt(x^2+y^2)-r0)/(r1-r0)*Width
    y_r = (atan(y/x)/pi+1/2)*Height


    Тут (x,y) - координаты на кольце. Центр кольца в (0,0), внутренний радиус r0, внешний r1. Width, Height - размеры прямоугольной текстуры.
    Ответ написан
    1 комментарий
  • Как вывести кратчайший путь в графе?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Вам надо в вашем алгоритме еще завести словарь, куда вы для каждой вершины будете складывать предыдущую в пути. Там, где вы соседнюю вершину кладете в очередь - там надо сарзу смотреть, посещенная она или нет и класть только если нет. Вот в этот момент вы знаете, что вы пришли в graph[city][i] из city.

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

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

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Да, нижние индексы - это обозначение системы счисления. Так, 110 в двочиной - это 6 в десятичной, или вот то разложение по степеням двойки.
    Ответ написан
  • Отдельное окно, отдельный скрипт. Как?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Завист от того, как реализованы "действия" в каждом окне-игре.
    Если дело на windows, то есть шанс, что окно воспримет за клик получение сообщение WM_MOUSEDOWN/WM_MOUSEUP. Тогда можно просто посылать сообщения в каждое окно параллельно отдельной программой.
    Но для некоторых игр важно, чтобы окно было активно, а некоторые еще и детектируют кучу всего с мышью и надо именно что эмулировать движение мышью через mouse_event, например. Но, в этом случае мышь одна на оба окна, поэтому надо, чтобы оба "скрипта" посылали клики централизовано, через какой-то компонент с мьютексом, который бы вы полнял ровно одно действие в единицу времени.

    Нажатия на клавиатуру обычно срабатывают просто через посылание сообщений окну, т.ч. тут все легко параллелизуется.

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

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

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

    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 комментария
  • Как правильно рассчитать коэффициент полезного использования пространства?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Обход в ширину, он же алгоритм заливки: закрасьте на невидимом канвазе или в массиве все блоки, пройдитесь по всей границе канваза/массива, если там непокрашенная точка, то красьте ее и добавляйте ее в очередь. Потом берите из очереди точки и добавляйте в нее 4 соседа, если они еще не покрашены. В конце все непокрашенные пиксели - ваши полости.

    Можно ускорить алгоритм сжатием координат: вввпишите все x и y координаты всех углов блоков, отсортируйте и унифицируйте (отдельно по каждой оси). Потом замените все координаты в блоках на порядковый номер в массиве уникальных координат. Примените алгоритм выше, но в конце надо помнить, что каждая ячейка теперь не 1x1, а сколько-то больше по вертикали и горизонтали.
    Ответ написан
  • Почему не отсеиваются нули при сравнении 0 < 0?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    array[index + 1] ? item < array[index + 1] : true Что эта конструкция делает, можете объяснить? Ошибка в ней.
    Ответ написан
    5 комментариев
  • Какая временная сложность у этого алгоритма?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Линейная. O(N+M). Ибо там цикл по i от 0 до startMedianIndex и вся остальная мишура на i вообще никак не влияет. Больше циклов в программе нет. Не понимаю, что тут может быть непонятного.
    Ответ написан
    Комментировать
  • Как лучше развернуть двумерный массив?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Если не обязательно делать поворт на месте, то вся суть алгоритма вот в этой одной строке:
    result[i][j] = arr[n-1-j][i];
    Надо только циклы прогнать по нужным границам, да массив нужного размера создать.

    Если матрица квадратная, то элементы сдвигаются по кругу в четверках - и это можно сделать без дополнительного массива . Можно делать сдвиг по кругу со временной переменной. Что-то вроде этого:
    tmp = arr[i][j];
    arr[i][j] = arr[n-1-j][i];
    arr[n-1-j][i] = arr[n-1-i][n-1-j];
    arr[n-1-i][n-1-j] = arr[j][n-1-i];
    arr[j][n-1-i] = tmp;


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

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

    Но если вам по заданию надо бинпоиск использовать, то у вас там следующие ошибки в реализации:
    - постоянное преобразование к toLowerCase - это ОЧЕНЬ неэффективно. Один раз все приведите к lowerCase и работайте только с этим. Можно эти ключи схоранить в новых полях.
    - когда вы нашли совпадение, можно делать из цикла break.

    Вы не сможете бинпоиском найти все объекты. Он может найти только один. Самый левый, самый правый, или как повезет - зависит от реализации.
    Вам надо запустить два бинпоиска последовательно. Один будет искать минимальный элемент, больше равный искомому (lower_bound), а второй бинпоиск будет искать максимальный элемент строго больший искомому (upper_bound). Пусть ваши бинпоиски возвращают индекс в массиве list. Эти две функции будут отличаться только в одном месте - там будет < и <= соответсственно.
    Ответ к задаче будет в массиве list по индексам от lower_bound (включительно) до upper_bound (не включительно). Может быть и так, что lower_bound == upper_bound, если искомого элемента в массиве нет и ответ будет пустым.
    Ответ написан
    2 комментария
  • Min max алгоритм или как сделать ползунок сложности в игре?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Можно при просчете вершины дерева игры выбирать не максимальное/минимальное значение из всех детей, а второе с конца с некоторой вероятностью. Значение вероятности задаётся уровнем сложности.
    Ответ написан
    Комментировать
  • Как из массива целых чисел найти все возможные комбинации (не только двух чисел, а и более) дающие искомую сумму?

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

    Можно рекурсивно перебрать числа: функция принимает список уже выбранных чисел, их сумму и сколько первых чисел массива обработаны. Если все числа обработаны, функция сравнивает сумму с искомой и, если надо, выводит список. Потом завершается. Если еще не все числа обработанны, то функция два раза рекурсивно вызвается с параметрами: Текущее число добавлено или нет в список, обработано на одно чисел больше.

    Другой вариант, через битовые маски, без рекурсии. Перебирайте число от 0 до 2^n-1. Потом смотрите на него, как на битовую маску. Так вы переберете все подмножества из n элементов. Если i-ый бит установлен, то берите i-ое число в сумму. Если сумма совпала с искомой - вы нашли вариант.

    Ну и самый быстрый вариант: с использованием динамического программирования. Как в задаче о рюкзаке вам надо подсчитать F(i,j) - можно ли числами с i-ого по последнее собрать сумму равную j. Потом рекурсивый перебор оптимизируется с этой информацией. Вы текущее число берете или нет и запускаетесь рекурсивно, если оставшимеся числами можно набрать оставшуюся сумму до ответа.

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

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Ваш алгоритм быстрее. Но в задаче часто бывает сработает не только самый быстрый код. Например, если там чисел всего 10 в массиве, то вы никакими измерениями разницу между сортировкой и вашим решением не намеряете (если только не запустите оба решения миллионы раз. Но это же уже другая задача. Ваша задача - найти минимальные 2 числа в одном массиве и ограничение по времени, если и есть, будет считаться по одному массиву)

    Поэтому иногда имеет смысл написать не самый быстрый алгоритм, но зато гораздо более простой. Если он проходит, то зачем кодить больше?

    В вашем алгоритме еще проблема, что не очевидно, почему он работает. Надо аккуратно рассматреть все 6 случев расположения arr[0], arr[1] и numbers[i] и убедиться, что инваринат "2 минмальных числа лежат в arr" поддерживается. Тут легко накосячить, перепутать 0 и 1, не там проверку поставить и все.

    Обычно, когда такой алгортм реализуют, поддерживают более строгий инвариант "минимальное число в arr[0], следующее минимальное число в arr[1]". Тогда проверки чуть чуть упрощаются и за логикой решения следить проще.
    Ответ написан
    1 комментарий
  • Какой алгоритм использовать для нахождения точки?

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

    При чем не надо решать систему в общем виде. Если вы возьмете ваши 4 точки как (0,0,0) и (0,0,1), (0,1,0) и (1, 0, 0) то вы уже можете найти координаты искомой точки, не решая даже квадратных уравнений или систем.

    Например, для первых двух точек:
    x^2+y^2+z^2 = d1^2
    x^2+y^2+(z-1)^2 = d2^2


    Вычтите одно уравнение из другого, сократите все сокращаемое, поделите на 2 и в одно арифмитическое действие найдете z.

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

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

    Тут вообще-то ответ - числа фиббоначи. Подумайте, почему.
    Ответ написан
    Комментировать
  • Обход Dom дерева как то относится к дискретной математике?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Просто при обходе - нет ничего не даст.
    Ответ написан
    Комментировать
  • Кто знает решение?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Вы умножаете на 2. А надо возводить в квадрат, т.е. в степень 2 ("power").
    Ответ написан
    2 комментария
  • Как в js равномерно распределить комбинации пунктов в массиве, который был создан с помощью рекурсивного размещения?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Если вам не надо чтобы каждый человек одинаково часто работал с каждым другим, то подойдет обощение решения, предложенного в комментариях Alexandroppolus и Сергей Сергей.

    Допустим количество работ (N) и количество людей (M) взаимно просты.

    Тогда сгенерируйте M строчек беря людей подряд:
    1, 2, 3
    4, 5, 1
    2, 3, 4
    5, 1, 2
    3, 4, 5

    Тут каждый человек одинаковое количество раз (по одному разу) будет на каждой работе. И дни, когда он будет работать будут максимально равномерно распределены (минимальное расстояние и максимальное между соседними работами будут различаться максимум на 1 и равны floor(N/M) и ceil(N/M)). Это идеальное с точки зрения равенства расписание. Но у него минус - частоты пар работников будут не одинаковыми. 1 гораздо чаще будет работать с 2 и 5, чем с 3 и 4.

    Теперь, если N и M не взяимно просты. Пусть D = GCD(N,M) - наибольший общий делитель.

    Разбейте всех людей на D групп по N'=N/D человек. N' и M взяимно просты, поэтому можно применить алгоритм выше к каждой группе.

    Дальше эти D расписаний надо перемешать. Для максимальной равномерности - сначала взять все первые строки всех расписаний, потом все вторые, и т.д.

    На i-ом месте будет день i / N' из расписания i % N' (если индексация с 0).

    Так, например, решение для 2 работ и 6 людей:

    N' = 3. 2 группы.
    В первой:
    1 2
    3 1
    2 3

    Во второй:
    4 5
    6 4
    5 6

    В итоге:
    1 2
    4 5
    3 1
    6 4
    2 3
    5 6
    Ответ написан
    Комментировать