El tipo de expresión regular es PCRE.
Escriba un programa que genere un PCRE válido de modo que coincida con todos los números naturales entre m
y n
y no coincida con nada más. No se permiten ceros a la izquierda.
Por ejemplo, let m
and n
be 123
y 4321
, entonces el programa podría salir
1(2[3-9]|[3-9]\d)|[2-9]\d\d|[123]\d\d\d|4([012]\d\d|3([01]\d|2[01]))
.
Esto coincide con la cadena exacta, por lo que ^
y $
anclajes están implícitos.
Uno debe tratar de equilibrar los dos:
La expresión regular debe tener un tamaño razonable.
El código debe ser corto.
Optimicemos para
code length in characters
+ 2 *regular expression length for input 123456 and 7654321
Nota al margen: sería interesante si podemos demostrar que la expresión regular PCRE más corta es del tamaño O (log n log log n) o algo así.
fuente
re_size*5 + prog_size
(más pequeño = mejor), dondere_size
es el máximo param
yn
hasta 5 dígitos. Hay muchas otras formas de hacerlo, lo que importa es que podamos calificar las respuestas.print .*
en algún idioma.if(min == 123456 && max == 7654321){print_hardcoded_regex}else{enumerate_range_and_join}
Respuestas:
Perl, puntaje 455
191 caracteres, 132 de longitud de expresión regular
Entrada:
123456, 7654321
Actualización: pude simplificar aún más esto cuando me di cuenta de que la mayoría de los patrones terminaban con cosas como
\d{3}
. Estos no hacían más que imponer una longitud de cadena, y lo hacían de manera muy repetitiva, ya que ocurrían en cada término. Eliminé esto usando otra búsqueda anticipada para imponer la condición "menor que", solo comprobando que: 1) la primera parte del número no excede la entrada o 2) el número tiene menos dígitos que la entrada. Luego, la expresión regular principal solo verifica que no tenga demasiados dígitos.También incorporé la idea de Peter Taylor de anticipación negativa para verificar la condición "mayor que".
La clave para simplificar este problema (al menos para mí) fue dividir la expresión regular en dos: una observación anticipada asegura que el número no sea menor que el mínimo, luego la parte principal de la expresión regular verifica que no sea mayor que el máximo. Es un poco tonto para entradas pequeñas, pero no es tan malo para entradas grandes.
Nota:
0|
al principio es excluir cualquier cosa que comience con un cero de la coincidencia. Esto es necesario debido a la naturaleza recursiva de la función regex: las partes internas de la coincidencia pueden comenzar con cero, pero el número entero no. La función regex no puede notar la diferencia, por lo que excluí cualquier número que comience con cero como un caso especial.Entrada:
1, 4
Versión Regex irrazonablemente larga, 29 caracteres:
fuente
m
es 0, entonces debe permitir 0 a pesar de tener un cero inicial.Javascript, puntaje 118740839
Supongo que si te gusta o no depende de cómo definas "un tamaño razonable". :-)
fuente
Haskell 2063 + 2 * 151 = 2365
Se garantiza que la expresión regular generada tiene una longitud O (log n log log n).
matchIntRange 12345 7654321
1(2(3(4(5[6-9]|[6-9]\d)|[5-9]\d\d)|[4-9]\d{3})|[3-9]\d{4})|[2-9]\d{5}|[1-6]\d{6}|7([0-5]\d{5}|6([0-4]\d{4}|5([0-3]\d{3}|4([012]\d\d|3([01]\d|2[01])))))
El siguiente código es una versión simple que ayuda a comprender el algoritmo, pero no hace ninguna optimización para mejorar el tamaño de la expresión regular.
matchIntRange 123 4321
La expresión regular tiene 680 caracteres. Aqui esta el codigo
fuente
GolfScript (126 + 2 * 170 = 466)
Para los valores dados da
Disección a seguir, pero la idea básica es definir un bloque de código que mapee un solo número natural a una expresión regular que coincida con cualquier número natural más pequeño, y luego convierta las entradas
lb
yub
en una búsqueda negativa (número natural menor quelb
) combinado con el regex para (número natural menor queub+1
).La lógica es bastante complicada, por lo que incluso para los estándares de GolfScript es críptico. Hasta que empiece a escribir una disección detallada, aquí hay una lista de variables:
fuente
|
ese momento, eso es un error en su motor de expresiones regulares, no en mi expresión regular.(a|)
realidad es válido. Sin embargo,[1-0]
en su expresión regular anterior no funcionó en Perl o en un probador en línea que probé.