Ответы пользователя по тегу Алгоритмы
  • Как найти пересечения среди N временных отрезков?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Надо отсортировать по времени события вида {id: 2, type: "start"} или {id: 4, type: "end"}
    Один раз перебрать эти времена, двигаясь по одному, и отслеживая текущее окно: кто в нём. Из этого понятно, кто с кем пересекся.
    Ответ написан
    1 комментарий
  • Как посчитать коэффициенты выигрышей в лото?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    10 из 40 случайно выбирает машина, 3 из 40 выбирает игрок. Надо, для примера, найти вероятность выпадения всего 2.

    Общее число случаев C(10,40) * C(3,40) – на него поделим число благоприятных вариантов. Это выбор 10 выигрышных C(10,40); из 10 надо выбрать 2 попадания C(2,10); из оставшихся 30 надо выбрать 1 промахнувшийся C(1,30) и всех их перемножить. Итого
    Q(40,10,3,2) = C(10,40) * C(2,10) * C(1,30) / (C(10,40) * C(3,40))
    Наверняка можно неплохо сократить что-то.

    C(N, M) – число сочетаний
    C(N, M) = M! / ( N! * (M-N)! )
    Ответ написан
  • Как найти самое близкое значение в многомерном массиве?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Раз отсортирован, значит надо просто идти подряд, пока не найдётся элемент, превышающий заданные значения. Вернуть предыдущий.

    function nearest( $sample, $arr) {
      $found = false;
      foreach( $arr AS $row) {
        if($row[0] <= $sample[0]  &&  $row[1] <= $sample[1]  &&  $row[2] <= $sample[2]) $found = $row;
        else break;
      }
      
      return $found;
    }
    
    $data = [
      [1, 1, 1],
      [1, 2, 1],
      [1, 2, 2],
      [1, 5, 4],
      [1, 5, 6],
      [2, 1, 6],
      [2, 2, 2],
    ];
    
    echo implode(',', nearest( [1,5,5], $data)); //  1,5,4
    Ответ написан
    1 комментарий
  • Как оценить "качество" тренда?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Похоже, вас интересует значение минимизируемой при линейной регрессии функции. Обычно это сумма квадратов расстояний каждой из точек до прямой. Собственную реализацию написать несложно. Как называются готовые функции в перечисленных продуктах, не подскажу, увы.

    Если со 100% всё понятно – когда все точки на прямой и сумма = 0; то что брать за максимум, за 0% аккуратность, хуже которой быть уже не может? : )
    Ответ написан
    Комментировать
  • Как понять условие задачи?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    В данной задаче "span" это протяженность, длина отрезка.

    В примере 1, 2, 1, 1, 3 это расстояние между самой левой единицей и самой правой, включая концы. Позиция самой правой (3) минус позиция самой левой (0) плюс 1.
    Ответ написан
    Комментировать
  • Как, имея число, получить близжайшее большее число, состоящее из тех же цифр?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Upd. Алгоритм ниже неверный, т.к. не работает в случае, когда необходимо переставить сразу несколько цифр.

    Рассматриваем пары неодинаковых цифр в числе.
    Взаимной их перестановкой можно увеличить число только когда левая цифра меньше правой. 23 -> 32
    Размер увеличения тем меньше, чем правее обе цифры. Они могут идти и не подряд, а, скажем, через одну.

    Коэффициент, который требуется минимизировать – это десятичное число из нулей с единицами в этих позициях. Скажем, лучше поменять позиции 2 и 3, чем 4 и 1, т.к. 110 < 1001 Т.е. при переборе позиций меньше всего хотим двигать левую позицию, пока не переберем все варианты правой:
    Варианты для 4
    0011
    0101
    0110
    1001
    1010
    1100

    Отсюда алгоритм.
    1. справа налево перебираем пары цифр пока не найдётся первая пара, где
      левая меньше правой
    2. меняем их местами.

    Всё.
    Ответ написан
    9 комментариев
  • Как лучше всего хранить диаграмму Вороного?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    «Хранить диаграмму» нет смысла.

    Я бы хранил только координаты точек и при запросе делал поиск ближайшего соседа. Ведь весь смысл диаграммы Вороного - в разбиении на области, где ближайший сосед - одна из контрольных точек.

    Upd. Возможно, я ошибался и хранить диаграмму можно как binary tree, что даст более быстрый поиск ответа на принадлежность точки к области – обходом дерева. (или не даст?)
    Ответ написан
    Комментировать
  • Различие в конечных автоматах НКА ДКА?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Основное отличие ДКА и НКА состоит в том, что ДКА в процессе работы может находится только в одном состоянии, а НКА в нескольких состояниях одновременно.

    — пост «Регулярные выражения изнутри» на Хабре неплохо объясняет суть конечных автоматов.
    Ответ написан
  • Как называется такая задача?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Не знаю, как называется такая задача.

    Решается сортировкой времени событий и их перебором: в каждый такой момент надо принять решение "остаться / переключиться".

    Есть приоритет текущей передачи (если она ещё не заканчивается). И есть приоритеты других передач в этот момент (особенно интересуют начинающиеся).
    Ответ написан
    Комментировать
  • Как покрыть полигон прямыми?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Два параметра можно варьировать: угол решетки и её фазу, смещение линий параллельно самим себе в рамках одного шага решётки.

    При относительно сложной форме фигуры остаётся только перебор вариантов. Сначала с большим шагом, затем уменьшая шаг и уточняя.

    Не совсем понятно, как задана фигура?
    «даны точки границ ее» – это массив точек с небольшим шагом, т.е. контур задан пунктиром, или «углы» прямых отрезков (вся фигура составлена из множества прямых отрезков разной длины).

    Алгоритм примерно такой. Пара (угол, фаза) задаёт множество прямых. Надо пройтись по контуру фигуры, считая пересечения или близость очередной точки контура к одной из прямых. Если контур задан прямыми отрезками ещё проще: для каждого отрезка посчитать число пересечений, исходя только из расстояния краевых точек от одной master-прямой. Например, расстояния 5.2 и 7.3 при шаге решетки 3. 0 не пересекает, 3 пересекает, 6 пересекает, 9 уже нет. Итого 2 пересечения.

    Прямая задаётся уравнением Ax + By + C = 0 Или с угловым коэффициентом y = x(-A/B) - (C/B) Параллельные прямые отличаются значением C.

    Расстояние между параллельными прямыми = |C1 - C2| / sqrt( A2 + B2)

    Расстояние от точки (X,Y) до прямой |AX + BY + C| / sqrt(A2 + B2)
    Ответ написан
    Комментировать
  • Как найти наибольшую поседовательность за O(n)?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    На англ. проблема называется "longest increasing subsequence"

    Вот публикация алгоритма решения этой проблемы за n log n−n log log n + O(n)

    Upd. По-русски называется Задача о наибольшей возрастающей подпоследовательности (НВП).
    Ответ написан
    2 комментария
  • Существует ли простой способ вычисления данного примера в уме?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Можно ещё чуть упростить. Это по сути 1/x, смещённый на 1 вправо и вверх:
    y = 1 / (1-(1/x)) = x / (x - 1) = 1 + 1 / (x - 1)
    5a761135a920e232839800.png
    1. вычитайте 1, получая диапазон от 0.01 до 14;
    2. один раз делите 1/x
    3. прибавляйте 1


    Задача сводится к быстрому определению обратного числа. С точностью до двух знаков, делите 100 на x с точностью до целых, и двигайте запятую влево на 2 знака:
    1/7 = 100/7 (/100) ≈ 0.14

    Например, для x = 1.14
    я бы так считал
    x - 1 = 0.14
    1 / 0.14 = 100 / 14 = 50 / 7
    с точностью до 2 знаков считаем целые в 5000 / 7
    50 / 7 ≈ 7
    ... 700               (сотни)
    ... + 10 / 7 = 710  (десятки)
    ... + 30 / 7 = 714  (единицы)
    итого 7.14
    +1 = 8.14
    Ответ: 8.14
    Ответ написан
    5 комментариев
  • Как найти числа фибоначчи в заданном интервале?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Найдите первое число Фибоначчи, попадающее в диапазон, по приближенной формуле, и дальше генерите сложением.

    function fibRange( from, to) {
      if( isNaN(from) || isNaN(to) || from < 2 || from > to) {
        throw "Bad argument(s)";
      }
      
      var root5 = Math.sqrt(5), phi = (1 + root5)/2, logPhi = Math.log(phi);
      var nFrom = Math.ceil( Math.log((from - 0.5) * root5) / logPhi);
      var nTo = Math.floor( Math.log((to+0.5) * root5) / logPhi);
    
      function nthFib(n) {
        return Math.round( (Math.pow(phi, n) - Math.pow( -phi, -n)) / (2 * phi - 1));
      }
      
      var a = nthFib(nFrom);
      var result = [a];
      if( nFrom === nTo) return result;
      var i = nFrom + 1;
      var b = nthFib(i);
      while( i <= nTo) {
        result.push(b);
        b = a + b;
        a = b - a;
        i++;
      }
      
      return result;
    }
    
    
    fibRange(10,377)
    /*
    13,21,34,55,89,144,233,377
    */
    Ответ написан
    Комментировать
  • Как вывести все числа являющиеся произведением простых чисел?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Все, являющиеся произведением – это все, кроме простых.
    Значит, надо получить все числа, кроме простых, в интервале 1..1400.
    Для поиска простых в таком небольшом диапазоне подойдёт алгоритм решета Эратосфена. Чтобы не писать вам целиком готовое решение, вот код, который только получает массив простых чисел от 2 до N:

    function primes(n) {
      var i, j, isPrime = Array(n), result= [];
      for(i=2; i<n; i++) isPrime[i] = true;
      for(i=2; i * i <= n; i++) {
        if( isPrime[i]) {
          for(j = i * i; j <= n; j += i) isPrime[j] = false;
        }
      }
      
      for(i=2; i<n; i++) {
        if(isPrime[i] === true) result.push(i);
      }
      return result;
    }


    Дальше вы уж сами, пожалуйста.
    Ответ написан
    3 комментария
  • Есть онлайн сервис по анализу данных?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Нейронная сеть достаточной сложности может «подстроиться» под любую функцию, обучаясь на данных. Это даст возможность по новым входным данным прогнозировать выходные. Но вот красивую и лаконичную формулу так не получить.
    Ответ написан
    Комментировать
  • Как выполнить проверку всех возможных вариантов?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Кажется, вам подойдёт такой простой алгоритм: перебрать все числа в двоичной записи от 1 до 2n, и брать те элементы строки, которым соответствует 1.

    Набросал функцию, подбирающую из данных элементов комбинацию, дающую наиболее близкую сумму к заданной:
    function nearest(arr, total) {
      var len = arr.length
        , i
        , bit
        , sum
        , n = Math.pow(2, len)
        , currDist
        , index = undefined
        , dist = undefined
        , result = []
      ;
      
      for( i = 1; i < n; i++) {
        sum = 0;
        for( bit = 0; bit < len; bit++) {
          if( i & (1 << bit)) sum += arr[bit];
        }
        
        currDist = Math.abs(total - sum);
        if( typeof dist === 'undefined' || dist > currDist) {
          index = i;
          dist = currDist;
          if( dist === 0) break;
        }
      }
      
      for(bit = 0; bit < len; bit++) {
        if( index & (1 << bit)) result.push(arr[bit]);
      }
      
      return result;  
    }
    
    nearest([1,3,4,6,8], 12) // [1,3,8]
    nearest([1,2,4,6,8], 12) // [2,4,6]
    nearest([7,9,13,19,28], 12) // [13] dist = 1
    nearest([7,9,13,19,28], 28) // [9,19] не [28] т.к. останавливается на первом найденном варианте
    Ответ написан
    Комментировать
  • Как выполнить поиск количества чисел удовлетворяющих условию в промежутке[x,y]?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Наверное, надо не искать, а генерить такую последовательность.

    Одна из цифр уже обязана быть «5». Для остальных надо собрать все варианты (с учётом порядка) разложения 5 в сумму цифр: от 11111 до 5.

    Теперь нужно собрать все варианты размещения пятёрки и каждой из комбинаций, вписывающиеся в диапазон [1 .. 23е5]. Можно рекурсивно набирать слева направо. На первую позицию годятся цифры 0, 1, 2. На вторую при первой "2" 0, 1, 2, 3, или любый при 0 или 1. С третьей по седьмую - любые.

    Для каждого варианта набора суммы ещё все варианты положения неучаствующих цифр.
    Ответ написан
    Комментировать
  • Хранение хеша в скрипте?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    грубо перебрать все возможные варианты «5–6 букв» получится весьма быстро.
    Ответ написан
  • Как правильно списать бонусы?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    В БД держать записи про каждое начисление бонуса:
    1. dt_created дата-время поступления;
    2. dt_void дата-время обнуления этого бонуса: через 2 года, а может, и другие правила введете;
    3. value_in сколько начислено;
    4. value_out сколько списано.
    Алгоритмы:
    • Для подсчёта числа актуальных баллов, бежим по непросроченным (Now() < dt_void) и суммируем (value_in - value_out).
    • Для списания при покупке бежим от старых к новым, набирая максимально допустимое для списания число баллов и обновляем value_out.
    Ответ написан
    2 комментария