Perl, 43 байта
map{say if$_==eval s/./+$&**$+[0]/gr}<>..<>
Попробуйте онлайн!
Regex действительно мощные, ребята.
объяснение
Первое, что делает код, это читает два целых числа как ввод через <>
и создает диапазон от первого до второго с помощью ..
. Затем он использует стандартную map
функцию для перебора этого диапазона, и применяет следующий код для каждого значения: say if$_==eval s/./+$&**$+[0]/gr
. Это похоже на бред, и вроде как, но вот что на самом деле происходит.
map
неявно сохраняет свое текущее значение в переменной $_
. Многие функции и операции perl используют это значение, если ни одна не указана. Это включает в себя регулярные выражения, такие как s///
оператор подстановки.
Регулярное выражение подстановки состоит из четырех частей:
- Строка, которой нужно манипулировать. Обычно оператор
=~
используется для применения регулярного выражения к строке, но если этот оператор отсутствует, то регулярное выражение применяется к неявной переменной $_
, которая содержит наше текущее число через map
функцию.
- Строка для поиска. В этом случае мы ищем любой отдельный символ перевода строки, обозначенный подстановочным знаком
.
. По сути, мы фиксируем каждую отдельную цифру.
- Строка для замены на. Мы подставляем знак плюс,
+
за которым следует математическое выражение, смешанное с некоторыми магическими переменными Perl, которые значительно упрощают все.
Специальная скалярная переменная $&
всегда содержит весь последний успешный захват регулярного выражения, который в данном случае представляет собой одну цифру. Специальная переменная массива @+
всегда содержит список смещений после последнего совпадения, т. Е. Индекс текста после совпадения. $+[0]
индекс в $_
тексте сразу после $&
. В случае 135
мы фиксируем цифру 1
, и индекс в 135
тексте сразу после этого (а именно 35
) равен 1, что является нашим показателем степени. Итак, мы хотим повысить $&
(1) до степени $+[0]
(1) и получить 1. Мы хотим повысить 3 до степени 2 и получить 9. Мы хотим повысить 5 до степени 3 и получить 125.
Если вход был 135
, результирующая строка +1**1+3**2+5**3
.
- Regex-модифицирующие флаги. Здесь мы используем два флага регулярных выражений -
/g
и /r
. /g
говорит интерпретатору продолжить замены после того, как первый найден (в противном случае мы бы закончили +1**135
). /r
говорит интерпретатору не изменять исходную строку , а вместо этого возвращать, какой будет строка после замен. Это важно, потому что в противном случае он будет перезаписан $_
, и нам это нужно для сравнения.
После полной замены мы получаем математическое выражение, которое оценивается eval
функцией. +1**1+3**2+5**3
оценивается в 1 + 9 + 125 = 135
, который сравнивается с исходным числом 135
. Поскольку эти два равны, код печатает число.