Igor
Что-то сдаетс мне это осталось во временах директикс9...
открой юнити .. будет почти та же хрень. будет иерархия преобразований.Единственное скорее всего на кватернионах.
Igor
Это базовые вещи от них никуда не уйдешь. при всем желании хоть директ кто угодно
Igor
Поверь за 15 лет ничего не поменялось ;)
Alexander
Ты мне тайну открыл. Я никогда не интересовался этим уже лет 15
Был уверен, что сейчас всякий драгндроп юзают
Igor
Ну пока ты делаешь какие то базовые вещи да ... как только захочешь что нибудь "этакое" прийдется заморочится
Максим
Я уже сказал свое мнение но ты думаешь что я тебя троллю ... ты переоцениваешь "придумай вот это" ... далеко не все в команде должны уметь придумывать по крайней мере на сколько я себе это представляю. Достаточно одного двух придумывателей
У нас не особо большая команда. Ща двое плюсовиков, нужны еще, чтоб их разгрузить. Задачи я уже указал - там именно про "придумай, протестируй, внедрим в проект". Есть и аналитики, и фронты, и бэкендеры, и архитектор
Максим
Про задачи в соседних отделах я хз
Igor
Остановимся на этом. Я не собирался никого обидеть. Придумать бывает очень разного уровня.
A.
Максим
Остановимся на этом. Я не собирался никого обидеть. Придумать бывает очень разного уровня.
Да я и не обижаюсь =) делов-то. Просто я тоже хз как отобрать людей по-другому, чем давать им задачки от простого к сложному. Приходил чел с 4 годами олимпиадного программирования в универе и 4+ годами боевого опыта на плюсах, на изи разъебал всю калитку вопросов и ушел с запросом в 300к =) такое, например, мало кто потянет сходу
Максим
Тот самый 1 из 20
Vyacheslav
это уже другой вопрос =)
"это проблемы будущего Гомера... Не завидую же я ему"
Igor
Виталик ... так и что ? учим деревья? sqrt декомпозицию? или вероятностные структуры? ;)
Виталик Голоенко
Бухать)
Давайте это учить)
Igor
Бухать)
факт!
Vyacheslav
Давайте это учить)
Я уже выучил две бутылки сегодня Пойду почитаю про сон чего-нибудь
Igor
Гоу sqrt декомпозицию
ну тогда берешь sqrt(N) массивов ... каждый из них поддерживаешь сортированный самой простой вставкой = профит ;) ... ща чайку наебну и попробую изобразить в коде
finegorko
ребят есть ли какие то правила при ревью чужого кода? типо как комментарии помечать и тд или не критично
Igor
ребят есть ли какие то правила при ревью чужого кода? типо как комментарии помечать и тд или не критично
Главное не писать "долбайоп" ... так не принято, даже если по коду видно что его писал точно долбайоп
Сергей
ребят есть ли какие то правила при ревью чужого кода? типо как комментарии помечать и тд или не критично
в целом - зайти в его ветку и проверить как работает, воспроизвести шаги для получения результата, есть если чеклист для пул реквеста - пройти по нему, погонять тесты, код без тестов - говно, нет эдж кейсов или тесты только на позитивный результат - говно, странные имена переменных - говно, посмотреть влияет ли его код на пользователей и тд и тп
Igor
А чем sqrt декомпозиция лучше частичных сумм?
а ты можешь тут прикрутить частичные суммы?
m700
Да легко войти в этот ваш айти. После курсов ГАРАНТИРОВАННОЕ ТРУДОУСТРОЙСТВО
A
Всем привет! Я совсем новичок, за спиной только гуманитарное образование. Хотела бы попробовать себя в айти сфере. Пожалуйста, подскажите какое самое простое направление, чтобы обучиться и устроить на работу? Правда ли что QA manual and automation tester хороший старт? Спасибо
A
Могли бы посоветовать какие то бесплатные курсы для начала? Чтобы можно было вникнуть в суть?
Андрей
Могли бы посоветовать какие то бесплатные курсы для начала? Чтобы можно было вникнуть в суть?
Прошел недавно курсы от яндекса,первые уроки бесплатные, но это как капля в море
Mikhail
ребят есть ли какие то правила при ревью чужого кода? типо как комментарии помечать и тд или не критично
Использую свой тул для код ревью, ниже конфигурация чеклиста (убрал поинты, которые относятся чисто к моей компании): { "Coverlay": [ "Successful", "Code Coverage Has Not Dropped", ], "Correctness": [ "Sufficient Unit Tests", "Ran Integration Tests (Suggest writing if required)", ], "Instrumentation": [ "Appropriate Logging", ], "Design": [ "Makes Sense", "Logically Correct", ], "Clarity": [ "Align correctly when multiline", "README/Documentation has been updated if appropriate", "No Dumb Comments / Leftover statements / spelling mistakes", ], "Failure Handling": [ "Null Check for each Loop", "Edge Cases Covered", "Clear Exception Strategy", ], "Security":[ "Only required permissions are provided", "Excessive access or usage of * avoided", ], "Git":[ "Commits have been squashed", “CR link is present", “Task link is present", ], "Runbook":[ "Runbook has been updated", "Dependency API guide has been updated", ], } Можно оформить себе в виде памятки на базе этого.
Mikhail
Выглядит примерно так.
Igor
Гоу sqrt декомпозицию
для начала рейтинг могут быть не последовательные числа сделаем их последовательными rerating = {k: v for v,k in enumerate(sorted(rating))} rating = [rerating[v] for v in rating] дальше собственно сами ведра ;) ... или по русски принято называть карманы BUCKETS = 30 MAXRATING = 1000 PERBUCKET = (MAXRATING + BUCKETS - 1) // BUCKETS buckets_cnt = [0] * BUCKETS buckets = [[0] * PERBUCKET for _ in range(BUCKETS)] def clear(): buckets_cnt[:] = [0] * BUCKETS buckets[:] = [[0] * PERBUCKET for _ in range(BUCKETS)] def add(v): b = v // PERBUCKET i = v % PERBUCKET buckets[b][i] = 1 buckets_cnt[b] += 1 return sum(buckets_cnt[x] for x in range(b)) + sum(buckets[b][x] for x in range(i)) заметь что buckets на самом деле может быть просто битовой маской вместо чисел. Так можно в разы уменьшить объем памяти теперь вчерашние массивы ... считаются легко clear() l_min = [add(v) for v in rating] clear() r_min = [add(v) for v in rating[::-1]][::-1] остальной код тот же def numTeams(self, rating: List[int]) -> int: cnt = len(rating) rerating = {k: v for v,k in enumerate(sorted(rating))} rating = [rerating[v] for v in rating] clear() l_min = [add(v) for v in rating] clear() r_min = [add(v) for v in rating[::-1]][::-1] res = 0 for l in range(cnt): r = cnt - l - 1 res += l_min[l] * (r - r_min[l]) res += (l - l_min[l]) * r_min[l] return res
m700
ребят есть ли какие то правила при ревью чужого кода? типо как комментарии помечать и тд или не критично
Видел онлайн чекер, поидее свой чек-лист собрать можно под конкретную компанию
Igor
Квадратичное решение
Виталик Голоенко
для начала рейтинг могут быть не последовательные числа сделаем их последовательными rerating = {k: v for v,k in enumerate(sorted(rating))} rating = [rerating[v] for v in rating] дальше собственно сами ведра ;) ... или по русски принято называть карманы BUCKETS = 30 MAXRATING = 1000 PERBUCKET = (MAXRATING + BUCKETS - 1) // BUCKETS buckets_cnt = [0] * BUCKETS buckets = [[0] * PERBUCKET for _ in range(BUCKETS)] def clear(): buckets_cnt[:] = [0] * BUCKETS buckets[:] = [[0] * PERBUCKET for _ in range(BUCKETS)] def add(v): b = v // PERBUCKET i = v % PERBUCKET buckets[b][i] = 1 buckets_cnt[b] += 1 return sum(buckets_cnt[x] for x in range(b)) + sum(buckets[b][x] for x in range(i)) заметь что buckets на самом деле может быть просто битовой маской вместо чисел. Так можно в разы уменьшить объем памяти теперь вчерашние массивы ... считаются легко clear() l_min = [add(v) for v in rating] clear() r_min = [add(v) for v in rating[::-1]][::-1] остальной код тот же def numTeams(self, rating: List[int]) -> int: cnt = len(rating) rerating = {k: v for v,k in enumerate(sorted(rating))} rating = [rerating[v] for v in rating] clear() l_min = [add(v) for v in rating] clear() r_min = [add(v) for v in rating[::-1]][::-1] res = 0 for l in range(cnt): r = cnt - l - 1 res += l_min[l] * (r - r_min[l]) res += (l - l_min[l]) * r_min[l] return res
Жаль ток шо на питоне написали
Igor
Декомпозиция можно поиграться размером бакетов ... но суть от этого не меняется
Igor
Жаль ток шо на питоне написали
там фиксированные массивы можешь изи на си переписать
Виталик Голоенко
там фиксированные массивы можешь изи на си переписать
rerating = {k: v for v,k in enumerate(sorted(rating))} что оно делает?
Igor
там рейтинги различные но могут быть очень большими ... мы перенумеровываем ... самому маленькому рейтингу даем значение 0 ... следующему 1 ... потом 2 и т.д. фактически наши рейтинги становятся числами [0; 1000)
Igor
Ну и в идеале нужно понимать почему тут n sqrt(n) сложность ;) ...
Виталик Голоенко
Сергей
rerating = {k: v for v,k in enumerate(sorted(rating))} что оно делает?
сортированный ключ: значение словарь
Igor
ну sqrt n потому что это sqrt декомпозиция)
ну так то да ;) но "почему это работает" осознать а не просто скопировать
Igor
Да перенумерацию можно делать по разному ... мне было проще сделать так.
Igor
Вообще такая идея часто применяется ... чаще это какое нибудь "сжатие координат".Но конечная идея если значений меньше чем размер значения ... и нас интересует только порядок то проще завести новуые значения в меньшем диапазоне
Виталик Голоенко
для начала рейтинг могут быть не последовательные числа сделаем их последовательными rerating = {k: v for v,k in enumerate(sorted(rating))} rating = [rerating[v] for v in rating] дальше собственно сами ведра ;) ... или по русски принято называть карманы BUCKETS = 30 MAXRATING = 1000 PERBUCKET = (MAXRATING + BUCKETS - 1) // BUCKETS buckets_cnt = [0] * BUCKETS buckets = [[0] * PERBUCKET for _ in range(BUCKETS)] def clear(): buckets_cnt[:] = [0] * BUCKETS buckets[:] = [[0] * PERBUCKET for _ in range(BUCKETS)] def add(v): b = v // PERBUCKET i = v % PERBUCKET buckets[b][i] = 1 buckets_cnt[b] += 1 return sum(buckets_cnt[x] for x in range(b)) + sum(buckets[b][x] for x in range(i)) заметь что buckets на самом деле может быть просто битовой маской вместо чисел. Так можно в разы уменьшить объем памяти теперь вчерашние массивы ... считаются легко clear() l_min = [add(v) for v in rating] clear() r_min = [add(v) for v in rating[::-1]][::-1] остальной код тот же def numTeams(self, rating: List[int]) -> int: cnt = len(rating) rerating = {k: v for v,k in enumerate(sorted(rating))} rating = [rerating[v] for v in rating] clear() l_min = [add(v) for v in rating] clear() r_min = [add(v) for v in rating[::-1]][::-1] res = 0 for l in range(cnt): r = cnt - l - 1 res += l_min[l] * (r - r_min[l]) res += (l - l_min[l]) * r_min[l] return res
а perbucket это зачем?
Igor
а perbucket это зачем?
чтобы по значению сразу определить в каком бакете оно лежит
Igor
На самом деле я не храню значение. Просто храню 1 или ноль . Есть значение или нет.
Виталик Голоенко
для начала рейтинг могут быть не последовательные числа сделаем их последовательными rerating = {k: v for v,k in enumerate(sorted(rating))} rating = [rerating[v] for v in rating] дальше собственно сами ведра ;) ... или по русски принято называть карманы BUCKETS = 30 MAXRATING = 1000 PERBUCKET = (MAXRATING + BUCKETS - 1) // BUCKETS buckets_cnt = [0] * BUCKETS buckets = [[0] * PERBUCKET for _ in range(BUCKETS)] def clear(): buckets_cnt[:] = [0] * BUCKETS buckets[:] = [[0] * PERBUCKET for _ in range(BUCKETS)] def add(v): b = v // PERBUCKET i = v % PERBUCKET buckets[b][i] = 1 buckets_cnt[b] += 1 return sum(buckets_cnt[x] for x in range(b)) + sum(buckets[b][x] for x in range(i)) заметь что buckets на самом деле может быть просто битовой маской вместо чисел. Так можно в разы уменьшить объем памяти теперь вчерашние массивы ... считаются легко clear() l_min = [add(v) for v in rating] clear() r_min = [add(v) for v in rating[::-1]][::-1] остальной код тот же def numTeams(self, rating: List[int]) -> int: cnt = len(rating) rerating = {k: v for v,k in enumerate(sorted(rating))} rating = [rerating[v] for v in rating] clear() l_min = [add(v) for v in rating] clear() r_min = [add(v) for v in rating[::-1]][::-1] res = 0 for l in range(cnt): r = cnt - l - 1 res += l_min[l] * (r - r_min[l]) res += (l - l_min[l]) * r_min[l] return res
ну мне надо карочь минут 20 на код повтыкать шоб полностью понять что тут происходит
Igor
ждём от тебя ревью на код Игорька
Та не код то однозначно дерьмо ;) это ж write only чисто для задачи ;)
Igor
глобальные переменные все дела ;) в лучшем стиле "олимпиадники пишут говнокод" ;)
Igor
я правда не олимпиадник ;) но стиль освоил в полном объеме ;)
Igor
Вот таким не хитрым способом бакеты можно превратить в битмаски buckets_cnt = [0] * BUCKETS buckets = [0] * BUCKETS def clear(): buckets_cnt[:] = [0] * BUCKETS buckets[:] = [0] * BUCKETS def add(v): b = v // PERBUCKET i = v % PERBUCKET buckets[b] |= 1 << i buckets_cnt[b] += 1 return sum(buckets_cnt[x] for x in range(b)) + sum(bool(buckets[b]&(1<<x)) for x in range(i)) остальной код тот же
Igor
если взять пербакет 64 ... а бакеты сделать unsigned long .... то вместо второй суммы можно через попкаунт считать. там будет что то типа __builtin__popcount(buckets[b] & ((1<<i) - 1))
Виталик Голоенко
для начала рейтинг могут быть не последовательные числа сделаем их последовательными rerating = {k: v for v,k in enumerate(sorted(rating))} rating = [rerating[v] for v in rating] дальше собственно сами ведра ;) ... или по русски принято называть карманы BUCKETS = 30 MAXRATING = 1000 PERBUCKET = (MAXRATING + BUCKETS - 1) // BUCKETS buckets_cnt = [0] * BUCKETS buckets = [[0] * PERBUCKET for _ in range(BUCKETS)] def clear(): buckets_cnt[:] = [0] * BUCKETS buckets[:] = [[0] * PERBUCKET for _ in range(BUCKETS)] def add(v): b = v // PERBUCKET i = v % PERBUCKET buckets[b][i] = 1 buckets_cnt[b] += 1 return sum(buckets_cnt[x] for x in range(b)) + sum(buckets[b][x] for x in range(i)) заметь что buckets на самом деле может быть просто битовой маской вместо чисел. Так можно в разы уменьшить объем памяти теперь вчерашние массивы ... считаются легко clear() l_min = [add(v) for v in rating] clear() r_min = [add(v) for v in rating[::-1]][::-1] остальной код тот же def numTeams(self, rating: List[int]) -> int: cnt = len(rating) rerating = {k: v for v,k in enumerate(sorted(rating))} rating = [rerating[v] for v in rating] clear() l_min = [add(v) for v in rating] clear() r_min = [add(v) for v in rating[::-1]][::-1] res = 0 for l in range(cnt): r = cnt - l - 1 res += l_min[l] * (r - r_min[l]) res += (l - l_min[l]) * r_min[l] return res
а можете заново повторить что и зачем вы делаете в каждой строчке(шоб по подробней)
Igor
А какая ценность тогда всего этого действа? ;)
Igor
Если ты сам разберешься будет гораздо полезней
Виталик Голоенко
Igor
какой конкретно части?
Виталик Голоенко
вот то шо мне не понятно всеровно не понял что такое perbucket b = v // PERBUCKET i = v % PERBUCKET что это и откуда оно return sum(buckets_cnt[x] for x in range(b)) + sum(buckets[b][x] for x in range(i)) ии что это
Igor
вместо того чтобы хранить массив целых чисел мы будем хранить 1 на месте числа (класическая идея сета на битмасках) т.е у нас могут быть числа от 0 до 999 мы храним 1000 нулей ... значит массив пустой если наш массив [1,2,9] значит 1 стоят в этих позициях
Igor
дальше так как мы будем постоянно бегать по этому массиву и считать кол-во еденичек ... давай разобъем наш массив на куски ... хочешь назови чанками хочешь бакетами хочешь карманами суть не меняется давай будем хранить не массив длинной 1000 а допустим 32 массивов по 32 числа и еще один дополнительный массив тоже длинной 32 (кол-во бакетов)... который будет хранить кол-во единиц в каждом массиве теперь когда мы добавляем число v в массив мы идем в бакет b = v // PERBUCKET на позицию i = v % PERBUCKET и ставим там 1 ... не забыв добавить в счетчик 1 теперь посчитаем сколько есть числе меньше этого числа ... просуммируем единицы в предыдущих бакетах ... и единицы в текущем бакете которые левее i
Igor
бля такие вещи нужно на бумажке показывать а не в чате печатать ;)
Igor
Прочитай вдумайся идея простая до безобразия ... кажется что какая то тупорылая возня. Но не сложно показать что это работает за O(sqrt(n))
Виталик Голоенко
ну может ща не особо понимаю но если пару виддосов на ютубе глянуть и статей на хабре то думаю разберусь
Igor
sqrt декомпозиция это базовая идея ;) легко заметить что бакеты можно опять sqrt декомпозировать ;) ... они фактически делают то же самое ... и если сделать несколько таких декомпозиций в конечном итоге мы прийдем к дереву ;). т.е sqrt декомпозиция это своеобразное дерво с 1 уровнем ;)
Igor
можно разбивать не на корень ... как в случае битмасок ... просто тогда оценка будет меняться. поскольку мы работаем с кол-вом массивов и с каждым подмассивом отдельно ... то логично выбрать деление порядка корня с точки зрения ассимптотики, но не обязательно ;)
Alexander
Igor
ну может ща не особо понимаю но если пару виддосов на ютубе глянуть и статей на хабре то думаю разберусь
Начни с битмасок смотри вот так они выглядят на питоне ;) bitmsk = 0 def add(v): nonlocal bitmsk bitmsk |= 1<<v return (bitmsk & ((1<<v)- 1)).bit_count() все ;) красота? ;) очистка просто установить bitmsk = 0 остальной код тот же ) class Solution: def numTeams(self, rating: List[int]) -> int: bitmsk = 0 def add(v): nonlocal bitmsk bitmsk |= 1<<v return (bitmsk & ((1<<v)- 1)).bit_count() cnt = len(rating) rerating = {k: v for v,k in enumerate(sorted(rating))} rating = [rerating[v] for v in rating] l_min = [add(v) for v in rating] bitmsk = 0 r_min = [add(v) for v in rating[::-1]][::-1] res = 0 for l in range(cnt): r = cnt - l - 1 res += l_min[l] * (r - r_min[l]) res += (l - l_min[l]) * r_min[l] return res