Regex (sabor PCRE), 66 (65🐌) bytes
Inspirado ao ver que Martin Ender e Jaytea , dois gênios do regex, escreveram soluções regex para esse código de golfe, escrevi o meu a partir do zero. O famoso regex de verificação principal não aparece em nenhum lugar da minha solução.
Não leia isso se você não quiser que você estrague uma mágica regex unária. Se você quiser tentar descobrir essa mágica, recomendo começar resolvendo alguns problemas no regex do ECMAScript:
- Corresponder números primos (se você ainda não está familiarizado com isso na regex)
- Combine potências de 2 (se você ainda não o fez). Ou simplesmente trabalhe no Regex Golf , que inclui Prime e Powers. Certifique-se de executar os conjuntos de problemas Classic e Teukon.
Encontre a maneira mais curta de combinar as potências de N, onde N é alguma constante (ou seja, especificada no regex, não na entrada) que pode ser composta (mas não é necessária). Por exemplo, combine potências de 6.
Encontre uma maneira de combinar os enésimos poderes, em que N é uma constante> = 2. Por exemplo, combine quadrados perfeitos. (Para um aquecimento, combine os poderes principais .)
Corresponder as instruções de multiplicação corretas. Combine números triangulares.
Combine os números de Fibonacci (se você é tão louco quanto eu), ou se quiser ficar com algo mais curto, combine as declarações corretas de exponenciação (para um aquecimento, retorne como o logaritmo na base 2 de uma potência de 2 - bônus, faça o mesmo para qualquer número, arredondando-o como quiser) ou números fatoriais (para um aquecimento, combine os números primários ).
Combine números abundantes (se você é tão louco quanto eu)
Calcule um número irracional com a precisão solicitada (por exemplo, divida a entrada pela raiz quadrada de 2, retornando o resultado arredondado como uma correspondência)
(O mecanismo de regex que escrevi pode ser útil, pois é muito rápido em regexes matemáticas unárias e inclui um modo numérico unário que pode testar intervalos de números naturais (mas também possui um modo de seqüências de caracteres que pode avaliar expressões regulares não unárias ou unárias). Por padrão, ele é compatível com ECMAScript, mas possui extensões opcionais (que podem adicionar seletivamente subconjuntos de PCRE, ou mesmo de visual molecular, algo que nenhum outro mecanismo de expressão regular possui).)
Caso contrário, continue lendo e também leia este GitHub Gist (aviso, muitos spoilers) que narra a jornada de pressionar o regex do ECMAScript para lidar com funções numéricas naturais de dificuldade crescente (começando com o conjunto de quebra-cabeças de teukon, nem todos matemáticos, o que provocou isso viagem).
Assim como as outras soluções regex para esse problema, a entrada é fornecida como dois números em bijetivo unário, separados por vírgula, representando um intervalo inclusivo. Somente um número é retornado. A regex pode ser modificada para retornar todos os números que compartilham o mesmo menor fator primo maior, como correspondências separadas, mas isso exigiria uma aparência de comprimento variável e a colocação \K
de uma lookahead ou a devolução do resultado como uma captura em vez de uma correspondência.
A técnica usada aqui de divisão implícita repetida pelo menor fator primo é idêntica à usada nas seqüências de caracteres Match, cujo comprimento é a quarta resposta de potência que eu postei há um tempo.
Sem mais delongas:
((.+).*),(?!.*(?=\1)(((?=(..+)(\5+$))\6)*)(?!\2)).*(?=\1)\K(?3)\2$
Você pode experimentá-lo aqui.
E a versão de espaço livre, com comentários:
# No ^ anchor needed, because this algorithm always returns a
# match for valid input (in which the first number is less than
# or equal to the second number), and even in /g mode only one
# match can be returned. You can add an anchor to make it reject
# invalid ranges.
((.+).*), # \1 = low end of range; \2 = conjectured number that is the
# smallest number in the set of the largest prime factor of each
# number in the range; note, it is only in subsequent tests that
# this is implicitly confined to being prime.
# We shall do the rest of our work inside the "high end of range"
# number.
(?! # Assert that there is no number in the range whose largest prime
# factor is smaller than \2.
.*(?=\1) # Cycle tail through all numbers in the range, starting with \1.
( # Subroutine (?3):
# Find the largest prime factor of tail, and leave it in tail.
# It will both be evaluated here as-is, and later as an atomic
# subroutine call. As used here, it is not wrapped in an atomic
# group. Thus after the return from group 3, backtracking back
# into it can increase the value of tail – but this won't mess
# with the final result, because only making tail smaller could
# change a non-match into a match.
( # Repeatedly divide tail by its smallest prime factor, leaving
# only the largest prime factor at the end.
(?=(..+)(\5+$)) # \6 = tool to make tail = \5 = largest nontrivial factor of
# current tail, which is implicitly the result of dividing it
# by its smallest prime factor.
\6 # tail = \5
)*
)
(?!\2) # matches iff tail < \ 2
)
# now, pick a number in the range whose largest prime factor is \2
.*(?=\1) # Cycle tail through all numbers in the range, starting with \1.
\K # Set us up to return tail as the match.
(?3) # tail = largest prime factor of tail
\2$ # Match iff tail == \2, then return the number whose largest
# prime factor is \2 as the match.
O algoritmo pode ser facilmente portado para o ECMAScript substituindo a chamada de sub-rotina por uma cópia da sub-rotina e retornando a correspondência como um grupo de captura em vez de usar \ K. O resultado é 80 bytes de comprimento:
((x+)x*),(?!.*(?=\1)((?=(xx+)(\4+$))\5)*(?!\2)).*(?=\1)(((?=(xx+)(\8+$))\9)*\2$)
Experimente online!
Observe que ((.+).*)
pode ser alterado para ((.+)+)
, reduzindo o tamanho em 1 byte (de 66 a 65 bytes ) sem perda da funcionalidade correta - mas o regex explode exponencialmente em lentidão.
Experimente online! (Versão de desaceleração exponencial ECMAScript de 79 bytes)