All streams
Search
Write a publication
Pull to refresh
2
0.2
Send message

Там замена (c , b) -> lcm, а оно имеет общие делители с "а", если gcd(a, c) > 1

Можно ещё упомянуть, что у спредов с квадратными скобками под капотом лежит механизм итерации, а с фигурными - доступ по перечисляемым индексам. Различие можно увидеть на примере [...'👍'] против {...'👍'}. У строк есть и то и другое, но работает слегка по разному

Стало меньше долбодятлов уткнувшихся в телефоны и не смотрящих по сторонам - уже плюс

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

Кстати, если не ошибаюсь, тут можно добиться не амортизированного, а "истинного" O(1) на элемент, если вместо базовой идеи очереди на двух стеках, использовать великую и ужасную очередь на 6 стеках (и соответственно к ним стеки с максимумами). Насколько это будет оптимально, не берусь судить, но факт любопытный

У меня работает за амортизированное O(1) на элемент, то есть за O(N) на всё про всё. Вот, опубликовал. Раз в k итераций собираю стек максимумов по окну справа налево, далее на следующих k итерациях благодаря этому под рукой имеется максимум среди тех элементов, которые покидают окно

Там по факту два разных решения, одно из которых легко придумать по мотивам реализации очереди на двух стеках и хранении максимумов для стека (у меня так и вышло)

Долго искать элемент внутри кучи. Но если знаем его позицию, то можно быстро удалить (переносим на его место последний элемент, потом просеивание вниз или вверх)

бегущий максимум/минимум, не зависящий от размера окна

https://leetcode.com/problems/sliding-window-maximum - этот?

Если массив уже отсортирован по возрастанию, то куча "max_heap" будет постоянно расти, потому что "удаленные" элементы внутри неё никогда не станут её корнями.

Навскидку, можно попробовать хранить в кучах не сами значения элементов, а их индексы в массиве. В хэш-таблице для каждого индекса хранить его позицию в куче (обновлять эти данные при просеивании), потому что зная эту позицию, можно быстро удалить элемент из кучи, даже если он не корневой. Причем вместо хэш-таблицы тогда достаточно массива длиной k, ведь "хэш" для индекса можно считать как i % k. У нас в любой момент времени всего k элементов в работе, и когда вываливается i-й элемент с хэшем h1 = i % k, то добавляется элемент h2 = (i + k) % k = h1, то есть заезжает в ту же ячейку

Вариант 4 - дублирование описаний и бойлерплейт, да и условным джунам он вряд ли покажется проще. Вариант 2 бесполезен, фактически там {type: SegmentType; coords: SegmentCoords} и непонятно, что в coords, мы не сможем проверить по ключу type.

Третий в принципе жизнеспособен, только для него нужен специальный тайпгард:

// тайпгард
const isType = <T extends SegmentType>(x: PathSegment3, type: T): x is PathSegment3<T> => x.type === type;

function func(x: PathSegment3) {
    if (x.type === 'line') {
        x.coords.length;  // 2 | 4, не сработало
    }

    if (isType(x, 'line')) {
        x.coords.length; // 4, всё окей
    }
}

Но его можно совсем чуть-чуть поменять и сделать параметрической разновидностью первого, с возможностью указывать некоторое подмножество SegmentType. Тогда isType из примера выше не понадобится, всё будет работать и так.

type PathSegment3a<T extends SegmentType = SegmentType> = T extends unknown ? {
  type: T;
  coords: SegmentCoords<T>;
} : never;

В общем, я бы советовал использовать третий "модернизированный" или первый. Это совсем не та типизация, которая может вызвать когнитивные затруднения у кого бы то ни было.

Ну эта проблема никак не связана именно с созданием через new - с фабриками было бы то же самое. Да даже созданные через new вроде бы "независимые" объекты могли обращаться к какому-то общему ресурсу. В общем, если для экземпляров какого-то класса вдруг появилось переиспользование, то наверно автор знал что делал.

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

Имхо, фича может быть полезна, если например был обычный класс (экземпляры которого создавались просто через new в куче мест кода), и вдруг превратился в синглтон, мультитон или объектный пул, в общем, с возвратом существующего объекта в некоторых кейсах. Можно слегка подправить конструктор и больше нигде ничего не менять.

С другой стороны, даже тщательная проверка свойства не всегда позволяет тайпскрипту понять, что у нас за объект. Пример, где внутри ифа переменная obj не сужает свой тип: https://tsplay.dev/mprvaw . Любопытно, что сам по себе obj.x при этом сужается. При проверке дискриминантного ключа (второй иф) всё окей.

fetch без чужих куков пойдёт, если не указать credentials: "include". Иначе пойдет с куками. Но в любом случае ответ сервера будет передан запросившему его js-коду, только если сервер снабдил свой ответ необходимыми заголовками (причем для запроса с куками заголовков должно быть больше). От честности автора тут ничего не зависит.

Я бы не назвал это костылем. Просто изначально были ограничения на "одинаковый origin", а спустя несколько лет добавились цивилизованные средства их обхода с согласия сервера. До этого был JSONP, который действительно костыль.

Куки можно не отсылать (как и делается в том же fetch без credentials: "include"), но этого недостаточно. Пользователь может находиться во внутренней сети и иметь доступ к каким-то ресурсам, недоступным снаружи, сайт злоумышленника не должен уметь забирать оттуда какие-либо данные, даже без кукисов.

В вашем примере просто так вышло, что реально используемый интерфейс только один - AreaCalculateable с этим своим calculateArea. А сабж про случай, когда интерфейсы совсем разные, и мы вынуждены таки определять, что за объект. Например, совсем недавно я использовал jscodeshift и работал с AST. Вот там как раз DU. У меня были некоторые свои действия с узлами, которые я не мог просто "подселить" как методы к некоторому "общему интерфейсу" и потом вызывать через точку, потому приходилось смотреть что за нода и что-то делать с её специфическими данными.

Т.е. для number Boolean не является корректным предикатом типа.

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

<T>(value?: T): value is Exclude<T, null | undefined | 0 | 0n | '' | false>;

Любопытно, что если добавить эту сигнатуру в BooleanConstructor через слияние интерфейсов, то напрямую тайпгард начинает работать (if (Boolean(v)) { ... v ... }), а в filter не подхватывается

Когда у нас значение 0, то Boolean возвращает false. Поэтому Boolean не является корректным предикатом типов для number

Почему? Boolean отсеивает значения undefined и null, и вполне мог бы быть, например, тайпгардом (x: number | undefined) => x is number. Но он протипизирован не как тайпгард, а как обычный предикат, потому и не выкидывает undefined и null, как при вызове напрямую, так и через filter.

В версии 5.5 просто добавили несколько эвристик, по которым в ряде случаев не заданное явно возвращаемое значение функции будет выведено как предикат типа, а не просто логическое, например const isNum = (x: number | undefined) => x != null;. К случаю с Boolean это не относится

С пунктом 4 есть ещё более интересный прикол. Да, в object напрямую не засунуть примитив, но можно так:

const nn: {} = 1;
const obj: object = nn;

То есть object оказался надтипом для более широкого {}, что идет вразрез с иерархией типов.

П.3 широко известен, во многих библиотеках есть его исправление, добавляющее перегрузку для метода filter.

П.5 - следствие ковариантности изменяемого массива, добавленной для удобства и в своё время вызвавшей много споров.

Из тех, кто в июне 1941 зашел на территорию СССР, большинство были патриотами, причем довольно упоротыми.

1
23 ...

Information

Rating
2,803-rd
Location
Москва, Москва и Московская обл., Россия
Registered
Activity

Specialization

Frontend Developer
Senior
JavaScript
TypeScript
React
HTML
CSS
Web development
Redux
MobX
Webpack