• Base64 формат картинки, что делать на фронтенде?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    что делать на фронтенде

    Пойти к бэкендеру и сказать: ты шо, дурак, зачем нам 470киллобайт не кешируемых данных по сети каждый раз гонять?!
    И пинать чтоб присылал ссылку.
    (а на деле я так понимаю там не одна картинка такая и не кешируемых данных в разы больше гоняется, что вообще ужас)

    На серьёзном хайлоад проекте это была бы, условно, смерть серверам по трафику.
    Но клиенты с не самым хорошим интернетом отлетели бы ещё раньше. А не самый хороший это даже мобильный 4g в средних условиях приёма сигнала. 470кб это очень, очень много для всего лишь одного запроса. Тяжелее запрос - дольше время до отрисовки.
    Ну и мобильный интернет далеко не у всех безлимитный. А не в России и подавно.

    А ещё есть лимиты на длину строки. В разных движках причём разные. Так что, теоритически, наверное, можно упереться в лимит строки и картинка не отобразится или будет битая.
    Ответ написан
    7 комментариев
  • Как правильно решить задачу, используя формулу комбинаторики?

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

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

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

    Покрасьте поле как шахматную доску. Черные и белые клетки. Каждая доминошка будет лежать на двух соседних белой и черной клетках. Постройте граф. Назначьте каждой клетке вершину, а ребра проведите между соседними клетками, если там нет перегородки. Граф - двудольный, ведь черные клетки окружены белыми, а белые - черными. Любое заполнение поля доминошками будет идентично паросочетанию в этом графе и наоборт. Найдите максимальное паросочетание: если оно не полное, то поле покрыть нельзя. Иначе ребра в паросочетании будут местами, куда надо класть доминошки.

    Вот статья с описанием алгоритма и реализацией.

    Это будет решение за O(n^2m^2).

    Другое решение, которое будет быстрее, если одно из измерений очень маленькое, а второе очень большое - динамическое программирование по профилю. Гуглите эти слова. Это сложнее реализовать, но зато будет работать за O(4^n m)

    Edit:
    Alexandroppolus в коментариях предложил использовать Алгоритм Хопкрофта — Карпа для поиска паросочетания, что для данного графа будет быстрее предложенного мной алгоритма Куна и будет работать за O(nm sqrt(nm)) вместо O(n^2 m^2)
    Ответ написан
    7 комментариев
  • Как в результате вычитания получить ноль максимально быстро?

    Griboks
    @Griboks
    Я долго изучал высшую математику и теперь наконец готов поделиться с вами наибыстрейшим способом получить нуль: x=0. Это даже быстрее Saboteur .
    Ответ написан
    1 комментарий
  • Как работает умножение вероятностей?

    Griboks
    @Griboks
    Всё очень просто выводится из определения вероятности: вероятность - это отношение количества благоприятных исходов к количеству экспериментов, p=n/m. Отсюда следует, что для двух независимых событий p1=n1/m1, p2=n2/m2 количество благоприятных исходов n=n1*n2 (т.е. при каждом любом благоприятном исходе события 1 нас удовлетворит абсолютно любой благоприятный исход события 2), а количество экспериментов - m=m1*m2. Тогда p=n/m=(n1*n2)/(m1*m2)=p1*p2.

    Это обычная комбинаторика. Ещё раз обращаю внимание, что для любого конкретного отдельного благоприятного исхода события 1, например #456, нас удовлетворит любой благоприятный исход события 2, например #789. Это означает, что общий исход #123 & #789 отличается от общего исхода #456 & #789, поэтому всего таких комбинаций n1*n2, а не (как вам кажется на первый взгляд) n1+n2.
    Ответ написан
    Комментировать
  • Как вычислить координату угла А прямоугольника?

    LoliDeveloper
    @LoliDeveloper
    Линейная алгебра как смысл жизни
    По моему
    Ax = Bx - length*cosC
    Ay = By - length*sinC
    Ax, Ay - координаты точки A
    C - угол
    length - расстояние от A до B
    Ответ написан
    1 комментарий
  • Как вычислить координату угла А прямоугольника?

    Тут не важны вершины C и D. Есть отрезок AB длины length под углом a, и координаты точки B. Нужна точка A.

    Наверное, всё просто:
    Ax = Bx - length * cos(a)
    Ay = By - length * sin(a)
    Ответ написан
    1 комментарий
  • Алгоритм двоичного поиска. Почему неправильно работает алгоритм?

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

    SADFGHJAETJER
    @SADFGHJAETJER
    Document.elementFromPoint()
    Document.elementsFromPoint()


    const coords = { x: 30, y: 55, width: 704, height: 292 }
    const elements = [];
    
    for (let posY = coords.y; posY <= coords.height; posY+= 5) {
        for (let posX = coords.x; posX <= coords.width; posX += 5) {
            const element = document.elementFromPoint(posX, posY);
            elements.some(s => s.isEqualNode(element)) || elements.push(element);
        }
    }
    
    console.log(elements);
    Ответ написан
    7 комментариев
  • На сколько критичен сдвиг в массиве для алгоритмов?

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

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

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

    Вам надо только понять какие вершины в цикле, а какие на черенке. Тут можно обходом в глубину или ширину это найти. Или даже тупо циклом. В графе есть одна вершина степени 1 - она же выезд. От нее надо идти к соседним, пока не дойдете до единственной вершины степени 3. Пройденные так вершины будут черенком. Остальные - в цикле.

    А дальше вам надо посчитать длины трех маршрутов и выбрать из них лучший.
    Ответ написан
    Комментировать
  • Как получить сумму всех элементов массива справа от numbers[i], что бы потом их сравнивать?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Оставить только те элементы массива, что больше суммы всех правее.

    Двигаться справа налево. Накапливать сумму. Сранивать очередной элемент с накопленной суммой.
    const getLeaders = numbers =>
      numbers.reduceRight(
        (acc, c) => { // acc – аккумулятор, c – очередной элемент массива
          if (c > acc.sum) { // если больше суммы тех, что правее
            acc.result.unshift(c); // положить в массив результатов
          }
          acc.sum += c; // накапливать сумму
          return acc; // аккумулятор пойдёт в следующую итерацию
        },
        { result: [], sum: 0 } // начальное значение acc
      )
      .result; // в итоге интересует только массив result
    
    // использование
    getLeaders([16, 17, 5, 4, 3, 1])  // [ 17, 3, 1 ]
    Ответ написан
    3 комментария
  • Как повысить свои навыки в построении архитектуры сложных приложений?

    bingo347
    @bingo347
    Crazy on performance...
    Если по теории, то мне в свое время вот эта книга помогла:
    https://www.litres.ru/robert-s-martin/chistaya-arh...

    Притом после 1 прочтения я нифига не понял, но стал пытаться внедрять практики из книги в повседневную разработку. Выписывал в блокнот все свои затупы.
    В этот момент передо мной как раз стояла задача, привести кусок лапши в хоть как-то поддерживаемое состояние. Именно он и сподвиг меня почитать эту книгу.

    Через несколько месяцев прочел еще раз, анализируя все затупы, что записал за это время в блокнот. После прочтения начал потихоньку рефакторить в существующих проектах места, которые уж очень жить мешали.

    Еще через пол года прочел третий раз, опять же с оглядкой на личный опыт. И тут я кажется уже совсем въехал. По крайней мере многие проблемы с организацией взаимодействия между компонентами стали разрешаться. И вообще появилось достаточно четкое понимание, как структурировать приложение и где разбивать его на компоненты.
    Ну и после 3 прочтения еще помог момент: мне дали с нуля проектировать новое, достаточно крупное приложение на Rust. Притом заказчик кричал "микросервисы - это круто, хочу, хочу, хочу", а тимлид мне сказал "давай монолит, но так чтоб потом легко было распилить, а то все сроки про**ем". Вот тут прямо вообще понимание пришло. Ну и плюс в Rust архитектурные компоненты очень хорошо ложатся на отдельные крейты (это такая единица компиляции в Rust), а компилятор в принципе не дает делать циклические зависимости между крейтами.

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

    bingo347
    @bingo347
    Crazy on performance...
    Цель инкапсуляции это объединение объектов
    кто Вам такое сказал?
    Само слово инкапсуляция происходит от латинского "in capsula", что можно перевести как "закрытый в коробке".
    Цель инкапсуляции - это сокрытие сложности. Не информации, не данных, не кода, а именно сложности.

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

    Vindicar
    @Vindicar
    Координаты строго целочисленные?
    Тогда обходи точки с помощью алгоритма floodfill, с центром в исходной точке.
    Например, для небольшого участка порядок будет таким:
    5 4 3 4 5
    4 2 1 2 4
    3 1 X 1 3
    4 2 1 2 4
    5 4 3 4 5

    Цифра - на какой итерации проверяются эти позиции.
    Т.е. сначала проверяешь соседние с исходной, потом соседние с ними, потом соседние с теми, и так далее.
    Если в позиции есть точка, добавляешь её в список найденных. Когда в списке найденных набралось 3 точки, останавливаешься.
    Ответ написан
    3 комментария
  • Что есть максимальная сумма делителей?

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

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

    Далее, используя эти данные, можно подсчитать сумму всех простых делителей используя формулу S=(p1^(k1+1)-1)/(1-p1)*...*(pm^(km+1)-1)/(1-pm) (тут p1^k1...pm^km - разложение числа на простые множители).

    Надо считать эту сумму делителей от меньших чисел к большим (обозначим ее S(n)). Тогда S(n) = S(n/p^k)*(p^k*p-1)/(p-1).

    Но это так, для любопытных. Я думаю в вашей задаче достаточно для кадого числа проверять все делители до корня (а оставшиеся делители получаются как n/i, если i - делитель до корня). Надо только аккуратно разобрать случай, когда i = sqrt(n) - тогда второй делитель не надо рассматривать, ибо это вторая копия того же самого.
    Ответ написан
    3 комментария
  • Баг тайпчекинга параметров функции?

    Отличный вопрос.

    Strict function types:
    The stricter checking applies to all function types, except those originating in method or constructor declarations. Methods are excluded specifically to ensure generic classes and interfaces (such as Array) continue to mostly relate covariantly.

    При замене методов на обычные функции сразу появляется ошибка:
    type AFnc = (p: A) => void
    
    function foo(p: A): void { }
    function bar(p: AB): void { }
    
    const f: AFnc = foo;
    const b: AFnc = bar; // не компилируется с сообщением о том, что AB требует ещё и свойство b
    Ответ написан
    3 комментария
  • Как убедить тайпскрипт, что unknown можно в ReturnType?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    У TypeScript есть ряд проблем с функциональными типами в дженериках из-за их вариантности
    Вот так результат будет аналогичным, но работает без проблем:
    function call<R>(f: () => R): R {
      return f()
    }
    Ответ написан
    5 комментариев