Search
Write a publication
Pull to refresh
90
0
Сергей Шашков @ShashkovS

Менеджер продукта, методист, разработчик

Send message

«Почему сторонники размножения получают блага за мой (как налогоплательщика) счет?»

Ну, тут как раз легко ответить. Налоги детей сторонников размножения пойдут на будущую пенсию и прочую государственную инфраструктуру противников. Можно так же вопрошать: «Почему сторонники пару десятков лет напрягались, чтобы вырастить детей, а их налогами будут кормить противников, которые все эти годы расслаблялись».

А кто-нибудь сумел успешно собрать на CentOS?

Пока видел две ссылки с инструкциями:


Но в том или ином виде у меня с обеими проблема. Сложность в том, что аккуратно перевести с убунтовского на центосовский:

apt-get install gawk m4 libwxgtk3.0-gtk3-dev libx11-dev libxi-dev libpcre3-dev libxerces-c-dev libspdlog-dev libuchardet-dev libssh-dev libssl-dev libsmbclient-dev libnfs-dev libneon27-dev libarchive-dev cmake g++ git

Вот есть карта ветров на высоте 12км: https://www.ventusky.com/?p=1;7;1&l=wind-200hpa
250км/ч там ооочень мнгого где. 370км/ч конечно должно повезти.

Я для своих старшеклассников вот такое делал:
https://ejudge.179.ru/tasks/python/2022b/pgm50__VPS.html

Там достаточно подробно про покупку и стартовую настройку своего VPS. В целом для первого раза развлечение на несколько часов, зато на своём VPS можно развернуть сразу кучу всего.

Карты и все XXX-pay на kaspi-терминалах тоже отлично работают, так что никто QR-ом пользоваться не заставляет.
Но мотивирует: так как оплата через visa/master не бесплатна для банка (и, следовательно для магазинов), то за оплату через QR дают кешбек. А дальше каждый сам волен выбирать. Думаю, что это будет скоро во многих терминалах РФ...

Я сейчас в Казахстане, тут аналогичная система оплаты называется Kaspi.QR (Kaspi — это местный банк с самым глубоким проникновением и крутыми терминалами, но строго локальный). По началу действительно неудобно, дольше. Но в целом это вопрос привычки: готовить карту к оплате заранее мы уже привыкли, так вот и камеру для считывания QR тоже нужно готовить заранее. Обычно на кассе есть 20 секунд «свободного» времени, когда кассир что-то вбивает. В это время нужно открыть приложение банка, а в нём считыватель. И когда кассир всё сделал и даёт делать оплату, то можно сразу сканировать QR, работает примерно с 1 метра, близко подносить телефон не нужно. Дальше оплата мгновенная, но только в интерфейсе моб.приложения дополнительно отображается сумма оплаты (что удобно).

Ну, это такое. Если склейка регулярки из именованных кусков — это норм, я таки и вправду могу сунуть в console.log, то функции типа wholeInput — это провал.
Такие функции первые претендуют на то, чтобы выехать в какой-то общий для всех модуль.
И вот после этого, чтобы собрать регулярку в консоли, мне нужно искать по проекту, где живут эти функции, копировать их отдельно в консольку, после этого уже собирать регулярку.
Кроме того, хоть слова wholeInput довольно понятные, но регулярки очень формальный язык, в которых каждый символ может иметь большое значение. Если я такое увижу в коде, то мне придётся полезть посмотреть, что именно имел в виду автор. А то мало ли, может он исходил из того, что у регулярки ещё какие-то флаги не выставлены?
Если я сделаю так:
const reg = new RegExp(wholeInput('\d+'), 'gm'); // wholeInput же умная, наверное?
// [...'123\nasdf\n53'.matchAll(reg)] — это два match'а

то могу получить не тот результат, который ожидаю.
function wholeInput(regex) {
   return  "/^" + regex + "$/";
}
function zeroOrMore(regex) {
   return "(" + regex + ")*";
}
const or = "|"
const onlyOneWhiteSpace="\\s(?!\\s)";
const suffix = zeroOrMore ("[a-zA-Z0-9\\!\\#\\%]" + or + onlyOneWhiteSpace)
const someEngPattern = wholeInput( "[A-Z0-9]+" + suffix)


Я вот не могу согласиться с тем, что этот код менее мерзкий.
Я знаю синтаксис регулярок, мне не нужно объяснять, что (regex)* — это сколько угодно повторов, я это сразу вижу. Если уж что-то и нужно объяснять, то мотивацию того, почему или зачем вы делаете именно так.
Зато регулярку текстом я могу скопировать и вставить в условный regex101, чтобы её потестировать (или поправить). А такой код мне нужно частично исполнить, чтобы получить регулярку, которую можно тестировать. И после того, как я её потестирую, мне придётся исправления назад мучительно накатывать в код (с возможными ошибками в процессе).

Вот пример того, как длинная и сложная регулярка оформена в модуле fractions.py:
_RATIONAL_FORMAT = re.compile(r"""
    \A\s*                                 # optional whitespace at the start,
    (?P<sign>[-+]?)                       # an optional sign, then
    (?=\d|\.\d)                           # lookahead for digit or .digit
    (?P<num>\d*|\d+(_\d+)*)               # numerator (possibly empty)
    (?:                                   # followed by
       (?:\s*/\s*(?P<denom>\d+(_\d+)*))?  # an optional denominator
    |                                     # or
       (?:\.(?P<decimal>d*|\d+(_\d+)*))?  # an optional fractional part
       (?:E(?P<exp>[-+]?\d+(_\d+)*))?     # and optional exponent
    )
    \s*\Z                                 # and optional whitespace to finish
""", re.VERBOSE | re.IGNORECASE)


Эту регулярку можно как есть вставить в regex101 (нужно не забывать ставить флаг extended).
Вот так это выглядит:
Там, если нужно, можно отладить все аспекты работы регулярки (группы и т.п.), а потом как есть скопировать назад в код.
Я не сумел запустить скрипт ни на python, ни на js, ни на C++.
Run configurations неактивна, в питоне Add python SDK после выбора подходящего бинаря ничего не меняется.
Я хотел сказать не это: обычные весы измеряют не то, что люди хотят в себе изменить. Но по удобному стечению обстоятельств «обычно» оно к нему очень близко.
Вместо всех сложностей в статье можно было просто тару подкрутить на 20 фунтов ровно с тем же успехом.
Забавно, но зануда_моде_он:
Есть две массы: гравитационная и инерционная.
Гравитационная — это грубо говоря m из формулы GmM/r².
Инерционная — это грубо говоря m из формулы mv²/2.

Пока похоже, что эти массы совпадают, но люди обычно хотят скинуть ту, что инерционная, хотя на весах замеряют ту, что гравитационная.
У меня после одного из посещений БР после анестезии покалывания и неприятные ощущения на части языка остались и после схода анестезии… Прошло всё только месяцев через 8…
Мне бы зуб соседний долечить в той же четверти, но теперь стрёмно немного.
больше не использую такие аппараты, как «Квадхеликс»


А в чём именно была проблема с Квадхеликсом? Чем хирургический метод лучше? (Не понял из текста)
Ну, я просил время работы 5 сообщений назад.
Я не знаю C#, чтобы не разбираться и оценить алгоритм, хорошо было бы понять хоть что-то про время. Я много раз встречал ситуацию, когда «умный велосипед» работает в 100 раз медленнее обычного.

Пришлось разобраться с запуском C#.
Сделал везде 100000 вызовов без вывода в консоль.
На одну итерацию у меня получается:
C# — 0.1013ms
cPython — 0.6469ms
PyPy — 0.1005ms
Rust — 0.0269ms (клон python-решения)

Вот теперь понятен масштаб и уже интересно, до чего можно оптимизировать.
Только вот лучше на доске 12×12 или 14×14. Иначе получается сравнение 0-1ms и 0-1ms.
Так я вообще о другом.
Более эффективный алгоритм на Python'е может быть в 100 раз быстрее неудачного алгоритма на C++ с intrinsic'ами и чем угодно.

ИМХО, ваша реализация неудачная, и даже версия на C++ не обгонит Python.
А на большие доски она вообще очень тяжело масштабируется. А pypy обсчитывает доску 14х14 за 2 секунды.
Какой смысл в «распределить на множестве ядер/процессоров» и «и видюху сунуть и в FPGA», если нормальный алгоритм на одном ядре на тормозном питоне с доской 8×8 работает за 0.650мс?

Запустил ваш код вот здесь, получается 30мс, что в 10 раз медленнее питона на том же onlinegdb.

Уж не знаю, что вы там оптимизировали, но получилось медленно.
Ну ок, для доски 8×8 у вас какое время работы?
Просто битовая «магия» (когда она не нужна сама по себе) хорошо работает, когда чисел много и они не лезут в кеш процессора. Тогда битовые маски, сжатие и т.п. отлично работают. Здесь же хоть и перебор большой, но чисел и bool'ов в любой момент очень мало.
Что-то у вас получилось очень сложно. Обычный перебор с возвратом работает здесь очень хорошо: идём по столбцам, храним позиции ферзей в предыдущих столбцах, а также занятые строки и диагонали. Бонусом в первом столбце ферзя ставим только в верхней половине доски, что ускоряет код в два раза.
Код на медленном cPython: доска 8×8 за 0.000655с, доска 12×12 за 0.302с, доска 14×14 за 10 секунд на cPython и за 2 секунды на PyPy.
У вас есть возможность запустить ваш код на досках 12×12? Какое время работы?
Код на питоне
from time import perf_counter


def queens(n, cur_column=None, all_positions=None, pos_in_prev_columns=None, used_rows=None, used_diags1=None, used_diags2=None):
    # При стартовом вызове заполняем все необходимые массивы
    if cur_column is None:
        cur_column = 0
        all_positions = []  # Список всех найденных позиций
        pos_in_prev_columns = []
        used_rows = [False] * n  # Список ферзей в предыдущих столбцах (True=занято)
        used_diags1 = [False] * (2 * n - 1)  # Список занятых диагоналей первого типа
        used_diags2 = [False] * (2 * n - 1)  # Список занятых диагоналей второго типа
    # В первом столбце перебираем только верхнюю половину доски, дальше по симметрии. Ускоряет в 2 раза
    if cur_column == 0:
        check_rows_in_this_column = (n + 1) // 2
    else:
        check_rows_in_this_column = n
    for row_num in range(check_rows_in_this_column):
        # Если горизонталь или диагональ заняты, идём дальше
        if used_rows[row_num] or used_diags1[row_num + cur_column] or used_diags2[row_num - cur_column]:
            continue
        # Если дошли до конца, то это победа!
        elif cur_column == n - 1:
            all_positions.append(pos_in_prev_columns + [row_num])
            # При необходимости добавляем симметричный вариант
            if pos_in_prev_columns[0] < n // 2:
                all_positions.append([n - 1 - x for x in all_positions[-1]])
        else:
            # Стандартный перебор с возвратом. Ставим нового ферзя, запускаем рекурсию, откатываемся
            used_rows[row_num] = used_diags1[row_num + cur_column] = used_diags2[row_num - cur_column] = True
            pos_in_prev_columns.append(row_num)
            queens(n, cur_column + 1, all_positions, pos_in_prev_columns, used_rows, used_diags1, used_diags2)
            pos_in_prev_columns.pop()
            used_rows[row_num] = used_diags1[row_num + cur_column] = used_diags2[row_num - cur_column] = False
    return all_positions


n = 8
st = perf_counter()
all_pos = queens(n)
en = perf_counter()
print(f'Всего {len(all_pos)} позиций для доски {n}×{n}')
print('time:', '{:.3}'.format(en - st))
for pos in sorted(all_pos):
    print(', '.join('ABCDEFGHIJKLMNOP'[col_n] + str(row_n + 1) for col_n, row_n in enumerate(pos)))

Information

Rating
9,684-th
Location
Россия
Date of birth
Registered
Activity

Specialization

Backend Developer, Product Manager
Lead
Python
Project management
Algorithms and data structures
asyncio