Perl, 43 bytes
map{say if$_==eval s/./+$&**$+[0]/gr}<>..<>
Experimente online!
Regex é realmente poderoso, pessoal.
Explicação
A primeira coisa que o código faz é ler dois números inteiros como entrada via <>
e cria um intervalo do primeiro ao segundo com ..
. Em seguida, ele usa o padrão map
função para percorrer esta faixa, e aplica-se o seguinte código para cada valor: say if$_==eval s/./+$&**$+[0]/gr
. Parece bobagem, e meio que é, mas aqui está o que realmente está acontecendo.
map
armazena implicitamente seu valor atual na variável $_
. Muitas funções e operações perl usam esse valor quando nenhum é fornecido. Isso inclui expressões regulares, como o s///
operador de substituição.
Há quatro partes em uma regex de substituição:
- String a ser manipulada. Normalmente, o operador
=~
é usado para aplicar uma regex a uma string, mas se esse operador estiver ausente, a regex será aplicada à variável implícita $_
, que contém nosso número atual por meio da map
função
- String para procurar. Nesse caso, estamos procurando por qualquer caractere que não seja de nova linha, indicado pelo curinga
.
. Na verdade, estamos capturando cada dígito individual.
- String para substituir. Estamos substituindo um sinal de mais
+
seguido por uma expressão matemática, misturada com algumas variáveis Perl mágicas que tornam tudo significativamente mais fácil.
A variável escalar especial $&
sempre contém a totalidade da última captura bem-sucedida de regex, que neste caso é um único dígito. A variável de matriz especial @+
sempre contém uma lista de deslocamentos pós-correspondência para a última correspondência bem-sucedida, ou seja, o índice do texto após a correspondência. $+[0]
é o índice $_
do texto imediatamente a seguir $&
. No caso de 135
, capturamos o dígito 1
e o índice 135
do texto imediatamente depois (ou seja, 35
) é 1, que é o nosso expoente. Então, queremos aumentar $&
(1) a potência de $+[0]
(1) e obter 1. Queremos aumentar 3 à potência de 2 e obter 9. Queremos aumentar 5 à potência de 3 e obter 125.
Se a entrada foi 135
, a sequência resultante é +1**1+3**2+5**3
.
- Sinalizadores de modificação de regex. Aqui estamos usando dois sinalizadores de regex -
/g
e /r
. /g
diz ao intérprete para continuar as substituições depois que a primeira for encontrada (caso contrário, acabaríamos com +1**135
). /r
diz ao intérprete para não modificar a sequência original e, em vez disso, retorne o que seria após a substituição. Isso é importante, porque, caso contrário, ele seria substituído $_
e precisamos dele para fins de comparação.
Depois que toda a substituição é concluída, obtemos uma expressão matemática, que é avaliada com a eval
função +1**1+3**2+5**3
é avaliado em 1 + 9 + 125 = 135
, comparado com o número original 135
. Como esses dois são iguais, o código imprime o número.