Regex inverso de interés compuesto

9

Koronkorko es la palabra finlandesa para interés compuesto . No queremos interés compuesto en nuestras cadenas, así que busquemos la expresión regular más corta posible para excluirla.

Dada una cadena que consta solo de los caracteres alfabéticos en mayúscula AZ, determine la expresión regular más corta posible que coincida con la cadena si no contiene la subcadena KORONKORKO. Cualquier cadena que contenga KORONKORKOcomo una subcadena no debe coincidir con la expresión regular.

Sólo los caracteres A- Z, [, ], -, ^, , ?, *, +, |, (, y )deben ser utilizados en la expresión.

Creo que esto se puede hacer con 118 caracteres en la expresión. ¿Puedes hacerlo más corto?

Nota: Este desafío es de Ohjelmointiputka (en finlandés).

invitado
fuente
Si !fuera un personaje permitido, podría haberlo hecho ^((?!KORONKORO).)*$por 19 bytes.
Mama Fun Roll
3
@MamaFunRoll Creo que es por eso ! que no está permitido .
Alex A.
Me divertí tratando de abrirme camino en el sitio finlandés, y creo que lo que estás buscando son expresiones teóricas de expresiones regulares que coincidan / rechacen la cadena de entrada. Por ejemplo, el sitio solo parece permitir el uso de -y ^dentro de las clases de caracteres (por ^lo que no se puede usar como un ancla), y una coincidencia solo se cuenta si la expresión regular coincide con toda la cadena (es decir, un entorno implícito ^$, como en oposición a las "expresiones regulares" normales que cuentan una cadena como coincidente si alguna parte de ella coincide con la expresión regular)
Sp3000
Como tal, he eliminado mi respuesta PCRE que, si bien debería funcionar incluso en PHP, casi definitivamente no es intencional en este caso.
Sp3000
Olvidé decir que el sitio verifica si la expresión es válida por la función ereg de PHP. Se dijo en discusión en ohjelmointiputka.net/keskustelu/…
invitado

Respuestas:

6

204 caracteres

(K((O(R(O(NKORO)*(NK(O(RK)?)?)?)?)?)?K)*(O(R(O(NKORO)*(N(K(O(RK?[^KO]|[^KR])|[^KO])|[^K])|[^KN])|[^KO])|[^KR])|[^KO])|[^K])*(K((O(R(O(NKORO)*(NK(O(RK)?)?)?)?)?)?K)*(O(R(O(NKORO)*(N(K(O(RK?)?)?)?)?)?)?)?)?

Generado convirtiéndose .*KORONKORKO.*en una máquina de estados finitos, invirtiendo la máquina de estados finitos y volviéndola a una expresión regular.

orlp
fuente
¿Por qué se convirtió en la mejor respuesta?
Bálint
1

Python, 77 79 97 118 bytes

Edición 3: reescribir. Utiliza lookaheads anidados

^([^K]|K(?=$|[^O]|O(?=$|[^R]|R(?=$|[^O]|O(?=$|[^N]|N(?=$|[^K]|K(?=$|[^O]|O(?=$|[^R]|R(?=$|[^K]|K(?=$|[^O]))))))))))*$

Regex 101

Edición 2: se agregó '$ |' a lo largo de la expresión regular. Ahora, si se ha emparejado un prefijo de KORONKORKO, el siguiente elemento que debe coincidir es el final de la cadena, un carácter que termina el prefijo o un carácter que extiende el prefijo si es seguido por algo que termina el prefijo.

Esta expresión regular funciona re.fullmatch(), que se agregó en Python 3.4. Para usar con re.match(), ^y $debe agregarse al principio y al final del patrón, respectivamente, para 2 bytes más.

([^K]|K($|[^O]|O($|[^R]|R($|[^O]|O($|[^N]|N($|[^K]|K($|[^O]|O($|[^R]|R($|[^K]|K($|[^O]))))))))))*

Enlace Regex101

Solución incorrecta anterior (ver comentarios):

K|([^K]|K([^O]|O([^R]|R([^O]|O([^N]|N([^K]|K([^O]|O([^R]|R([^K]|K[^O])))))))))*

Editar: Agregado solo K

RootTwo
fuente
2
No creo que esto coincida K.
orlp
@orip - Buena captura. Fijo.
RootTwo
La última actualización ahora falla paraKKORONKORKO
Sp3000
¿Es reparable? ¿Algunas ideas?
RootTwo
1
El comienzo ^y el final $no son necesarios. Además, =y $no están permitidos.
LegionMammal978