惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Forbes - Security
Forbes - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
P
Palo Alto Networks Blog
Martin Fowler
Martin Fowler
T
Threatpost
D
Docker
S
Schneier on Security
M
MIT News - Artificial intelligence
G
Google Developers Blog
L
LINUX DO - 热门话题
J
Java Code Geeks
月光博客
月光博客
博客园 - 三生石上(FineUI控件)
IT之家
IT之家
博客园 - Franky
C
Cyber Attacks, Cyber Crime and Cyber Security
K
Kaspersky official blog
Google DeepMind News
Google DeepMind News
N
News and Events Feed by Topic
V
Vulnerabilities – Threatpost
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
人人都是产品经理
人人都是产品经理
Spread Privacy
Spread Privacy
T
Tailwind CSS Blog
爱范儿
爱范儿
阮一峰的网络日志
阮一峰的网络日志
U
Unit 42
C
CERT Recently Published Vulnerability Notes
The GitHub Blog
The GitHub Blog
Simon Willison's Weblog
Simon Willison's Weblog
NISL@THU
NISL@THU
MongoDB | Blog
MongoDB | Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
H
Heimdal Security Blog
Recorded Future
Recorded Future
云风的 BLOG
云风的 BLOG
SecWiki News
SecWiki News
P
Privacy International News Feed
P
Proofpoint News Feed
O
OpenAI News
B
Blog
腾讯CDC
F
Full Disclosure
Apple Machine Learning Research
Apple Machine Learning Research
T
Tor Project blog
H
Hacker News: Front Page
Project Zero
Project Zero
Hugging Face - Blog
Hugging Face - Blog
C
Cisco Blogs
S
Security Affairs

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Самовлюблённые числа: когда нарциссизм и бесполезность вдохновляют
LilouX · 2026-05-19 · via Все публикации подряд на Хабре

Самовлюблённые числа: когда нарциссизм и бесполезность вдохновляют

9 мин

9.9K

Самовлюблённые числа (они же числа Армстронга, в оригинале Narcissistic numbers) — это числа, равные сумме своих цифр, возведённых в степень количества этих цифр. Например, 153 — самовлюблённое число, потому что 

153 = 1³ + 5³ + 3³

Известный математик Г. Харди отзывался об этом свойстве так: «Всё это забавные факты, весьма подходящие для газетных колонок с головоломками, способные позабавить любителей, но ничего в них не затронет сердце математика». 

Но действительно ли самовлюблённые числа настолько бесполезны? Чтобы узнать ответ, зайдите под кат.

Годфри Харди смотрит на самовлюблённые числа неодобрительно. Источник

Годфри Харди смотрит на самовлюблённые числа неодобрительно. Источник

Математика нарциссизма

Поговорим о математических свойствах самовлюблённых чисел. 

Первое свойство довольно очевидно. Факт, что число является или не является самовлюблённым, зависит от системы счисления. Например, число 153 самовлюблённое в обычной (десятичной) системе счисления. Но в восьмеричной системе оно записывается как 231₈.

2³ + 3³ + 1³ = 36 = 44₈

Таким образом, в восьмеричной системе счисления это число уже не будет самовлюблённым.

Второе очевидное свойство: всякое число, состоящее из одной цифры (в данной системе счисления), самовлюблённое.

1¹ = 1, 2¹ = 2, 3¹ = 3, и так далее.

Число лепестков нарцисса является Narcissistic number в системах счисления с основанием 7 и выше. Совпадение? Не думаю

Число лепестков нарцисса является Narcissistic number в системах счисления с основанием 7 и выше. Совпадение? Не думаю

Третье очевидное свойство: в единичной (унарной) системе счисления любое число самовлюблённое, поскольку записывается количеством единиц, равным самому числу. Например:

1111111₁ = 1⁶ + 1⁶ + 1⁶ + 1⁶ + 1⁶ + 1⁶

Теперь перейдём к неочевидным свойствам. Во‑первых, в любой системе счисления, кроме унарной, количество самовлюблённых чисел конечно. Для простоты покажем это на примере привычной десятичной системы.

Самое маленькое n‑значное число — это единица с (n-1) нулями, то есть 10^(n-1).

Самое большое значение, которое может принимать сумма энных степеней цифр — это n * 9^n.

Посмотрим, как ведут себя эти две функции с ростом n. 

При увеличении количеством цифр на единицу к самому маленькому числу с этим приписывается ноль, то есть оно увеличивается в 10 раз. А самое большое значение суммы степеней цифр становится (n+1)*9^(n+1), то есть оно увеличивается в 9*(1 + 1/n)раз. Поначалу и второе число, и скорость его роста выше. Но довольно быстро 9*(1 + 1/n)становится меньше десяти. С этого момента разрыв начинает сокращаться, и в какой‑то момент оказывается, что сумма степеней цифр даже не сможет иметь столько же цифр. А значит, самовлюблённые числа с таким (и большим) количеством цифр невозможны.

Если конкретнее, этот момент наступает при n = 61:

61⋅ 9^(61) =986 558 654 653 022 734 516 835 726 400 773 166 812 580 119 518 280 257 414 149

В последнем числе 60 цифр (можете пересчитать). Значит, в десятичной системе счисления самовлюблённое число может иметь не более 60 цифр. А следовательно, количество таких чисел конечно.

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

Второе неочевидное свойство самовлюблённых чисел состоит в том, что… его нет. В каком‑то смысле Харди был прав. За этими числами не стоит какой‑то глубокой и интересной математической теории. Просто в некоем божественно‑математическом ГИБДД им выдали козырные номера. 

На этом статью можно было бы закончить. И всё же она не заканчивается. 

Самовлюблённое программирование

Задолго до того, как появился LeetCode, доисторические программисты любили решать бесполезные задачи. То посчитают число расстановок на шахматной доске восьми ферзей, не бьющих друг друга, то какое другое безобразие учинят.

И в этом качестве самовлюблённые числа вызвали у программистов интерес. Почему? Из‑за огромной размерности задачи. Наивное и неинтересное решение — перебрать все числа‑кандидаты и для каждого из них проверить, является ли оно самовлюблённым. Но верхняя граница для самовлюблённых чисел в десятеричной системе счисления — 10^60, а значит, чисел‑кандидатов очень много. Если каждую наносекунду проверять по триллиону триллионов чисел, то для завершения перебора понадобится в два триллиона миллиардов раз больше времени, чем текущий возраст Вселенной.

 Когда неинтересное решение не подходит, программистам становится интересно, и они начинают выдумывать разные хитрости. О них и пойдёт речь в оставшейся части статьи.

Главная хитрость

Конечно, по законам драматургии стоило бы придерживать главную хитрость до конца, чтобы сохранять интригу и нагнетать саспенс. Увы, здесь драматургия вступает в конфликт с логикой повествования. Если бы программисты не придумали главную хитрость, задача так и осталась бы трансвычислительной, и остальные хитрости были бы бессмысленны. Поэтому начнём сразу с неё.

Рассмотрим маленький и удобный пример: пусть мы ищем самовлюблённые числа из трёх цифр в четверичной системе счисления. Если действовать простым перебором, то потребуется перебрать 4^3  - 4^2 =48 чисел:

100₄

101₄

102₄

103₄

110₄

…

329₄

330₄

331₄

332₄

333₄

Для каждого из них нам потребуется вычислить функцию: f( d_1   d_2   d_3  ) (( = d)_1 )^3  + (d_2 )^3   ((+d)_3 )^3

— а затем сравнить значение функции с исходным числом. Однако заметим следующее: значение функции не зависит от порядка цифр! При наивном решении мы вычисляем её несколько раз для одного и того же набора цифр. Но можно пойти от обратного — взять набор цифр, вычислить от него функцию, затем проверить, что результат состоит из того же набора цифр. 

Наборы цифр можно кодировать массивами из четырёх чисел:

[количество нулей, количество единиц, количество двоек, количество троек]

Можно посчитать, что существует всего 18 наборов из трёх четверичных цифр:

[3, 0, 0, 0]
[2, 1, 0, 0]
[2, 0, 1, 0]
[2, 0, 0, 1]
[1, 2, 0, 0]
[1, 1, 1, 0]
[1, 1, 0, 1]
[1, 0, 1, 1]
[1, 0, 0, 2]
[0, 3, 0, 0]
[0. 2, 1, 0]
[0, 2, 0, 1]
[0, 1, 2, 0]
[0, 1, 1, 1]
[0, 0, 3, 0]
[0, 0, 2, 1]
[0, 0, 1, 2]
[0, 0, 0, 3]

Более того, есть изящный алгоритм перебора этих наборов.

  1. Начинаем с набора из одних нулей. В нашем примере это [3, 0, 0, 0]

  2. Чтобы получить следующий набор, идём по массиву справа налево и находим первый элемент, из которого можно взять единицу и «переложить» направо. Например, в наборе [0, 2, 0, 1] этим элементом будет двойка. Единица не подходит, поскольку она уже в крайней правой позиции, из неё нельзя ничего переложить направо. Правый нуль не подходит, потому что из него нельзя взять единицу.

  3. Если мы нашли такой элемент, берём из него единицу и перекладываем направо, а затем к этой же единице перекладываем всё, что есть в последнем элементе. Например, [0, 2, 0, 1] превращается в [0, 1, 2, 0].

  4. Если же такого элемента не нашлось, значит мы закончили перебор.

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

Итак, с помощью Главной хитрости™ мы сократили перебор с 48 до 18 итераций. Точнее, на самом деле до 17 (набор из одних нулей заведомо не подходит). Но всё равно это меньше чем втрое. Звучит не очень круто. Одна треть вечности — это всё равно вечность, так? 

Но всё начинает звучать намного круче, если увеличить количество цифр. Количество наборов цифр растёт намного медленнее, чем количество чисел из этих цифр. Количество наборов десятичных цифр выражается следующей формулой: (n+9)!/(n!⋅9!), где n — количество цифр. И эта функция растёт намного медленнее, чем 10^n — 10^(n-1) (количество чисел с n цифрами). Например, количество наборов из девяти цифр — 92 378, что примерно в 10 000 раз меньше, чем количество чисел из девяти цифр (900 000 000). Количество наборов из 60 цифр — 56 672 074 888. Жалкие 56 миллиардов. 

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

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

Хитрости поменьше

Техники, о которых говорится ниже, не могут сократить вычисления в настолько огромное число раз, как Главная хитрость™. Но если использовать несколько техник, каждая из которых ускоряет вычисления в несколько раз, то можно нивелировать разницу между современными компьютерами и компьютерами 80-х.

Использование lookup‑таблицы

Вместо того чтобы каждый раз вычислять 0^n  ,  1^n  ,  2^n  ... 9^n , можно вычислить их один раз и сохранить значения в массив. В дальнейшем вместо вычисления можно просто брать их из массива. Это уже даёт очень большое ускорение по сравнению с наивной реализацией.

Быстрое отсечение по величине

Если мы вычислили сумму степеней, и оказалось, что она больше 10^n или меньше 10^(n-1) — сразу понятно, что в ней неправильное количество цифр. Можно пропустить этап с разбором на цифры и сравнением наборов цифр.

Быстрое отсечение ветвей

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

Быстрое отсечение по признаку делимости

Известный факт: число имеет тот же остаток от деления на 9, что и сумма цифр этого числа. Можно заранее вычислить остатки от деления 0^n  ,  1^n  ,  2^n  … 9^nна 9 и быстро проверять, имеет ли сумма степеней цифр тот же остаток, что и сумма самих цифр. Если нет, можно пропустить дальнейшие вычисления.

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

Эффективная «длинная арифметика»

Большинство не‑программистов (и даже некоторые программисты, чего уж греха таить) не задумываются об этом, однако компьютер не умеет нативно работать с очень длинными числами. Он внутренне представляет их как массивы более маленьких чисел, а при выполнении арифметических действий применяет к этим массивам специальные алгоритмы. Время работы этих алгоритмов зависит от длины чисел. Например, сложение 60-значных чисел вдвое медленнее, чем сложение 30-значных. А умножение и деление замедлятся даже более чем вдвое.

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

Параллельные вычисления, SIMD, GPU и прочее

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

«Встретимся посередине»

Это эзотерическая и действительно сложная техника, поэтому её мы обсудим последней. Если вкратце, суть её в следующем: цифры числа разбиваются на две по возможности равные половины. Для каждой половины заранее рассчитывается, какие суммы степеней могут получиться и какие комбинации цифр этим суммам соответствуют. Эти данные сохраняются в памяти в виде специальной структуры, чтобы затем можно было быстро получить их, не вычисляя заново.

После этого алгоритм пытается «состыковать» две половинки — ищет, какой комбинация из первого и второго набора цифр даст правильную сумму. Благодаря предварительно сохранённым данным этот перебор становится очень быстрым.

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