Ответы пользователя по тегу Алгоритмы
  • Алгоритм нахождения синуса любого угла?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Смотря какая точность нужна. Есть формула Бхаскара, работающая на диапазоне от 0° до 180° (0-π):
    sin(x°) = 4·x·(180−x)/(40500−x·(180−x))
    sin(x) = 16·x·(π−x)/(5·π2−4·x·(π−x))
    На большей части диапазона она даёт точность в пределах 0.2%, на краях точность падает до 2%.
    Значения для углов вне этого диапазона можно получить из тождества:
    sin(2·π+x) = sin(x)
    sin(π+x) = -sin(x)
    Ответ написан
    2 комментария
  • Как называется алгоритм подсчета посетителей?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Составляете ассоциативный массив вида {ид: время}.
    По приходу данных проходите по всем обнаруженным сейчас людям, если такого человека в списке нет, то добавляете его в массив с указанием времени.
    Проходите по массиву. Если человека нет в обнаруженных сейчас, то смотрите на время первого обнаружения и причисляете его к посетителям или прохожим, после чего удаляете из массива.
    Ответ написан
    Комментировать
  • Машинные константы и асимптотический анализ алгоритмов?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    machine dependent constants - это количество тактов на один цикл алгоритма и тактовая частота процессора.
    Предположим, что линейный алгоритм O(n) работает на быстром компьютере и каждый цикл выполняется за 1 наносекунду, то есть общее время будет 1×n. Логарифмический алгоритм O(log n) работает на медленном компьютере и каждый его цикл занимает 100 наносекунд, общее время 100×log(n) Посмотрим, как будет меняться время алгоритма при изменении n.
    n    | O(n) | O(log n)
    1    |    1 |   100
    10   |   10 |   200
    100  |  100 |   300
    1000 | 1000 |   400

    То есть, в интервале от 100 до 1000 есть значение n, после которого логарифмический алгоритм работает быстрее даже на более медленном компьютере.
    В общем случае значение n можно получить из равенства a×n = b×log(n)
    Ответ написан
    1 комментарий
  • Как упаковать в 128 бит значения?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Берём номер первого элемента (0..31)
    Умножаем на 31, прибавляем номер второго элемента в последовательности с удалённым первым элементом (0..30).
    Умножаем на 30, прибавляем номер третьего элемента в последовательности с удалёнными первым и вторым элементами (0..29).
    ...
    Умножаем на 2, прибавляем номер тридцать первого элемента в последовательности с удалёнными первым - тридцатым элементами (0..1).
    Максимум получим 8.68331761881189e+36, что меньше 2128 = 3.4028237e+38.
    Ответ написан
    3 комментария
  • Как преобразовать ключи объекта вида "key[index]" к массиву?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    var t = {
      list: {
        "action_buttons[0]": "View",
        "action_buttons[1]": "Share",
        "action_buttons[2]": "Download",
        "columns[0]": "Date of Study",
        "columns[1]": "Patient",
        "columns[2]": "File name",
        "columns[3]": "Reporting <br>Physician",
        "columns[4]": "Institution"
      }
    };
    
    var list = {};
    var re = /^(.*?)\[(\d+)\]$/;
    var match;
    for (var prop in t.list) {
      match = prop.match(re);
      if (typeof list[match[1]] == "undefined") {
        list[match[1]] = [];
      }
      list[match[1]][match[2]] = t.list[prop];
    }
    t.list = list;
    console.log(t);

    {…}
    ​   list: {…}
    ​​      action_buttons: […]
    ​​​         0: "View"
    ​​​         1: "Share"
    ​​​         2: "Download"
    ​​​      columns: […]
    ​​​         0: "Date of Study"
    ​​​         1: "Patient"
    ​​​         2: "File name"
    ​​​         3: "Reporting <br>Physician"
    ​​​         4: "Institution"
    ​
    Ответ написан
    2 комментария
  • Различие в конечных автоматах НКА ДКА?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Детерминированный конечный автомат для каждого состояния содержит не более одного перехода для каждого входного символа и не содержит перехода для пустого символа ε.
    Светофор вообще к конечным автоматам не относится.
    Ответ написан
  • Как узнать сложность (количество переходов) в поиске по хэш таблице?

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

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    В принципе, ваш алгоритм рабочий, только перебирать надо не все отрезки в каждом цикле, а только те, что лежат ниже. То есть
    for (i = 0; i < pairs.length-2; i++) {
      ... 
      for (i = i+1; j < pairs.length-1; j++) {
        ...
        for (k = j+1; k < pairs.length; k++) {
          ...
        }
      }
    }
    Ответ написан
    1 комментарий
  • Как проверить, входит ли работа во временной период?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    <?php
    $begin = new DateTime('09:00');
    $end = new DateTime('21:00');
    $intervals = array(
      array(new DateTime('10:00'), new DateTime('10:15')),
      array(new DateTime('10:15'), new DateTime('11:45')),
      array(new DateTime('12:30'), new DateTime('16:00'))
    );
    $time = 90;
    
    function checkInterval($begin, $end, $time) {
      $intervalDiff = $begin->diff($end);
      $intervalMinutes = $intervalDiff->h * 60 + $intervalDiff->i;
      if ($intervalMinutes >= $time) {
        echo $begin->format('H:i'), ' - ', $end->format('H:i'), "\n";
      }
    }
    
    $intervalStart = $begin;
    foreach ($intervals as $interval) {
      checkInterval($intervalStart, $interval[0], $time);
      $intervalStart = $interval[1];
    }
    checkInterval($intervalStart, $end, $time);
    Ответ написан
    1 комментарий
  • Определить, что точка внутри фигуры или нет?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Проведите из точки луч в любую сторону. Если он пересекает контур нечётное число раз, то точка в контуре, если чётное (или ноль), то вне контура.
    Если луч попадает в вершину, то надо определить, как расположены примыкающие к этой вершине отрезки контура относительно луча. Если отрезки находятся с разных сторон от луча, то засчитывается одно пересечение, если с одной - то ни одного.
    Если один из отрезков контура совпадает с лучом, то надо смотреть как располагаются относительно луча соседние отрезки.

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

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Найти все подграфы, выбрать из них самый большой.
    Ответ написан
  • Сложение и умножение вероятностей часть 2. Как выбрать?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Вероятности так не складываются. Как влияет одно событие на другое - в данном случае определяется правилами игры. Представьте, что игра идёт до миллиона очков. Как одно очко, заработанное Мишей повлияет на общий счёт игры? А если игра заканчивается с первым набранным очком?
    Что касается общей формулы - то вероятность победы команды
    Pпобеды = 0.36×P(победы|Миша заработал очко) + (1 - 0.36) × P(победы|Миша не заработал очко)
    Ответ написан
    4 комментария
  • Подсчет количества автомобилей для перевозки n пассажиров?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Если нет других ограничений, то [(n-1)/30]+1 30-местных автомобилей.
    Ответ написан
    6 комментариев
  • Как слить два отсортированных массива в один?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Надо начинать процедуру слияния с конца заполненной части первого массива и, соответственно, с начала второго. Результат заносить в конец первого массива.
    Заводите индексы для движения по каждому из исходных массивов и для вставки результата. Затем сравниваете числа по индексам в исходных массивах, записываете в результат меньшее из них, сдвигаете индексы результата и записанного числа. Не забывайте проверять индексы на выход за пределы массива.
    Спойлер. Лучше решить самостоятельно.
    int n1 = 5, n2 = 5;
    int a1[10] = {1, 4, 9, 12, 54};
    int a2[] = {99, 17, 9, 8, 4};
    int i1 = 0, i2 = n2-1, i = n1+n2-1;
    while (i >= 0) {
      if (i1 > n1-1) {
        a1[i--] = a2[i2--];
      } else if (i2 < 0) {
        i = -1;
      } else if (a1[i1] < a2[i2]) {
        a1[i--] = a1[i1++];
      } else {
        a1[i--] = a2[i2--];
      }
    }
    Ответ написан
    Комментировать
  • Как сделать подобные слагаемые коэффициентов многочлена с одинаковыми степенями?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Самый простой способ - представить полином как массив [0..n], где значение элемента массива - это коэффициент при соответствующей степени.
    Ответ написан
  • Как подсчитать количество людей в помещении?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Ответ написан
    Комментировать
  • Как узнать какие товары входят в ценник, если известна итоговая сумма?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Простейшая рекурсия.
    function makeBasket($sum, $prices, $result) {
        if ($sum % $prices[0] == 0) {
            return array_merge($result, [$sum / $prices[0]]);
        }
        if (count($prices) == 1) {
            return false;
        }
        for ($i = 0; $i <= $sum / $prices[0]; $i++) {
            $res = makeBasket($sum - $prices[0] * $i, array_slice($prices, 1), array_merge($result, [$i]));
            if ($res != false) {
                return $res;
            }
        }
        return false;
    }
    
    $prices = array_values($accessories[$article]);
    $res = makeBasket($accessoriesSum, $prices, []);
    $result = [];
    $i = 0;
    foreach ($accessories[$article] as $key => $val) {
        if (($i < count($res)) && ($res[$i] != 0)) {
            $result[$key] = $res[$i];
        }
        $i++;
    }
    print_r($result);

    Возвращает первый найденный результат.
    sandbox.onlinephpfunctions.com/code/f9d233c85ed30b...
    Ответ написан
    4 комментария
  • Как найти ошибку в генерации поколения в "game of life"?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    У вас неверно описано основное условие игры. Оно звучит так:
    - в пустой (мёртвой) клетке, рядом с которой ровно три живые клетки, зарождается жизнь;
    - если у живой клетки есть две или три живые соседки, то эта клетка продолжает жить; в противном случае, если соседей меньше двух или больше трёх, клетка умирает («от одиночества» или «от перенаселённости»)

    При формализации получаем:
    - Два соседа: новое состояние = старое состояние
    - Три соседа: новое состояние = живая
    - Иначе: новое состояние = мёртвая
    У вас же при двух соседях клетка всегда становится живой.

    Ну и можно слегка упростить алгоритм, если использовать не bool, а char и обозначать живую клетку как 1, мёртвую как 0. Тогда количество соседей можно посчитать просто суммируя значения, без тернарных операторов.
    Ответ написан
    2 комментария
  • Как оптимизировать сумму ряда?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Аналитически.
    59fe144ebe173368222815.gif
    Я нашёл этому поистине чудесное доказательство, но поле ввода слишком узко для него. (C) Ферма.
    Решение
    Рассмотрим дроби - слагаемые данной суммы. Очевидно, что знаменатели могут меняться от 2 до 2k.
    Попробуем определить, какие числители будут в дробях со знаменателем n. Для этого нам надо разложить n на пары x и y всеми возможными способами, учитывая ограничения 1 ≤ x ≤ k, 1 ≤ y ≤ k и взять допустимые значения x.
    Если 2 ≤ n ≤ k, то допустимыми значениями x будут 1 ... n-1. Для k+1 ≤ n ≤ 2k допустимыми значениями x будут n-k ... k. Таким образом, мы можем записать сумму числителей для каждого знаменателя:
    59fef5831ed62261528289.png
    Теперь, с учётом полученной системы запишем, как будет выглядеть полная сумма всех дробей:
    59fef5c331774953483286.png
    Заметим, что если в первой сумме начать суммирование не с 2, а с 1, то сумма не изменится, поскольку добавленное слагаемое равняется нулю. Во второй сумме перенесём k из пределов суммирования в слагаемое. Получим две суммы с одинаковыми пределами, а значит их можно объединить в одну:
    59fef699cef72869621752.png
    Ответ написан
    2 комментария
  • Каким образом реализовать быстрое сравнение таблиц?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    "Таблицы" - это массивы в памяти? Тогда сортировать все массивы по бренду и артикулу, затем двигаясь параллельно по всем трём массивам сформировать общий.
    Ответ написан