Regex Golf: verificar una solución de Sudoku

65

Escriba una expresión regular que coincida con cualquier solución de sudoku válida y no con ninguna solución de sudoku no válida. La entrada es una versión desenrollada del sudoku, es decir, no hay delimitadores de línea. Por ejemplo, el siguiente tablero:

7 2 5 8 9 3 4 6 1
8 4 1 6 5 7 3 9 2
3 9 6 1 4 2 7 5 8
4 7 3 5 1 6 8 2 9
1 6 8 4 2 9 5 3 7
9 5 2 3 7 8 1 4 6
2 3 4 7 6 1 9 8 5
6 8 7 9 3 5 2 1 4
5 1 9 2 8 4 6 7 3

se daría como:

725893461841657392396142758473516829168429537952378146234761985687935214519284673

Las reglas son probablemente de conocimiento común por ahora, pero por si acaso ... un tablero de sudoku es válido si y solo si:

  • Cada fila contiene los dígitos desde 1hasta 9exactamente una vez.
  • Cada columna contiene los dígitos desde 1hasta 9exactamente una vez.
  • Cada uno de los nueve subcuadrículas 3x3 contenga los dígitos de 1a 9exactamente una vez.

Reglas

Su respuesta debe consistir en una única expresión regular, sin ningún código adicional (excepto, opcionalmente, una lista de modificadores de expresión regular necesarios para que su solución funcione). No debe usar las características de la expresión regular de su idioma que le permiten invocar código en el idioma de alojamiento (por ejemplo, el emodificador de Perl ).

Puede usar cualquier sabor regex que existiera antes de este desafío, pero especifique el sabor.

No asuma que la expresión regular está anclada implícitamente. Por ejemplo, si está usando Python, suponga que su expresión regular se usa con re.searchy no con re.match. Su expresión regular no necesita coincidir con toda la cadena. Solo necesita hacer coincidir al menos una subcadena (que puede estar vacía) para soluciones válidas y no producir coincidencias para soluciones no válidas.

Puede suponer que la entrada siempre será una cadena de 81 dígitos positivos.

Esto es regex golf, por lo que gana la expresión regular más corta en bytes. Si su lenguaje requiere delimitadores (generalmente /.../) para denotar expresiones regulares, no cuente los delimitadores. Si su solución requiere modificadores, agregue un byte por modificador.

Casos de prueba

Tableros válidos:

123456789456789123789123456231564897564897231897231564312645978645978312978312645
725893461841657392396142758473516829168429537952378146234761985687935214519284673
395412678824376591671589243156928437249735186738641925983164752412857369567293814
679543182158926473432817659567381294914265738283479561345792816896154327721638945
867539142324167859159482736275398614936241587481756923592873461743615298618924375
954217683861453729372968145516832497249675318783149256437581962695324871128796534
271459386435168927986273541518734269769821435342596178194387652657942813823615794
237541896186927345495386721743269158569178432812435679378652914924813567651794283
168279435459863271273415986821354769734692518596781342615947823387526194942138657
863459712415273869279168354526387941947615238138942576781596423354821697692734185
768593142423176859951428736184765923572389614639214587816942375295837461347651298
243561789819327456657489132374192865926845317581673294162758943735914628498236571
243156789519847326687392145361475892724918653895263471152684937436729518978531264
498236571735914628162758943581673294926845317374192865657489132819327456243561789
978531264436729518152684937895263471724918653361475892687392145519847326243156789
341572689257698143986413275862341957495726831173985426519234768734869512628157394

Tableros inválidos:

519284673725893461841657392396142758473516829168429537952378146234761985687935214
839541267182437659367158924715692843624973518573864192298316475941285736456729381
679543182158926473432817659567381294914256738283479561345792816896154327721638945
867539142324167859159482736275398684936241517481756923592873461743615298618924375
754219683861453729372968145516832497249675318983147256437581962695324871128796534
271459386435168927986273541518734269769828435342596178194387652657942813823615794
237541896186927345378652914743269158569178432812435679495386721924813567651794283
168759432459613278273165984821594763734982516596821347615437829387246195942378651
869887283619214453457338664548525781275424668379969727517385163319223917621449519
894158578962859187461322315913849812241742157275462973384219294849882291119423759
123456789456789123564897231231564897789123456897231564312645978645978312978312645
145278369256389147364197258478512693589623471697431582712845936823956714931764825
243561789829317456657489132374192865916845327581673294162758943735924618498236571
243156789529847316687392145361475892714928653895263471152684937436719528978531264
498236571735924618162758943581673294916845327374192865657489132829317456243561789
978531264436719528152684937895263471714928653361475892687392145529847316243156789
342571689257698143986413275861342957495726831173985426519234768734869512628157394
345678192627319458892451673468793521713524986951862347179246835534187269286935714
341572689257698143986413275862341957495726831173985426519234768734869512628517394

Para otros casos de prueba, puede usar este script CJam que toma un tablero válido como entrada y lo baraja aleatoriamente para dar un nuevo tablero válido (formato de entrada irrelevante siempre que contenga solo dígitos y opcionalmente espacios en blanco).

Si su expresión regular es compatible con el sabor .NET, puede probarlo en línea con Retina. Se debe imprimir una solución válida 0para tableros no válidos y algún número entero positivo para tableros válidos. Para ejecutar todos los casos de prueba a la vez, use esta plantilla e inserte la expresión regular en la segunda línea. Si necesita modificadores de expresiones regulares, anteponga a `a la expresión regular y coloque las letras modificadoras estándar delante de ella.

Martin Ender
fuente
1
Si solo esto fuera [code-bowling], jajaja.
mbomb007
Espera ... Si estamos usando Python, ¿ solo podemos usar expresiones regulares, y nada más? Además, ¿qué tan grande es cada tablero? ¿Hay un tamaño específico? Si no, ¿cómo debemos extraer cada tabla del grupo de dígitos debajo valid boards?
R. Kap
@ R.Kap Independientemente del sabor que esté utilizando, debe enviar solo la expresión regular (y posiblemente algunos modificadores), sí. Cada entrada tiene exactamente 81 dígitos y representa una placa completa. (Cada línea en los casos de prueba es un tablero separado.)
Martin Ender
Escribí un script para resolver sudokus simples en SQL. Estoy seguro de que puede reescribirse para esta pregunta. Sin embargo, SQL no tiene mucho REGEX. ¿Eso descalifica la respuesta? (El script probablemente estaría un poco por debajo de los 400 caracteres)
t-clausen.dk

Respuestas:

40

Ruby regex, 71 78 73 bytes

^(?!.*(?=(.))(.{9}+|(.(?!.{9}*$))+|(?>.(?!.{3}*$)|(.(?!.{27}*$)){7})+)\1)

Realmente no conozco a Ruby, pero aparentemente no se queja de los cuantificadores en cascada.

Pruébalo aquí

.NET regex, 79 78 75 o 77 bytes

Porque Martin piensa que esto es posible ... Pero supongo que también incorporará estos cambios también.

^(?!(.)+((.{9})+|(?>(.{9})+
|.)+|(?((...)*
)(?>(.{27})+
|.){7}|.)+)(?<=\1))

Requiere una nueva línea final en la entrada para funcionar. No estoy seguro de si se me permite hacer esto (probablemente no).

Pruébalo aquí

La versión sana de 77 bytes:

^(?!(.)+((.{9})+|((?!(.{9})*$).)+|(?((...)*$)((?!(.{27})*$).){7}|.)+)(?<=\1))

Gracias Neil por señalar el error en mi versión anterior y jugar golf 1 byte (para el (...)*).

Pruébalo aquí

PCRE, 77 78 bytes

^(?!.*(?=(.))((.{9})+|(.(?!(?3)*$))+|(?(?=.(...)*$)(.(?!(.{27})*$)){7}|.)+)\1)

Solo por completo.

Pruébalo aquí

Otra versión, también 78 bytes:

^(?!.*(?=(.))((.{9})+|(.(?!(?3)*$))+|(?>.(?!(...)*$)|(.(?!(.{27})*$)){7})+)\1)

Pruébalo aquí

Explicación

^(?!.*                    # Match a string that doesn't contain the pattern,
                          # at any position.
  (?=(.))                 # Capture the next character.
  (
    (.{9})+               # Any 9*n characters. The next character is in
                          # the same column as the captured one.
  |
    (.(?!(.{9})*$))+      # Any n characters not followed by a positions 9*m
                          # to the end. The next character is in the same row
                          # as the captured one.
  |
    (                     # Any n occasions of...
    ?(.(...)*$)           # If it is at a position 3*k+1 to the end:
      (.(?!(.{27})*$)){7} # Then count 7*m characters that are not followed
                          # by a position 27*j to the end,
    |
      .                   # Else count any character.
    )+                    # The next character is in the same block as the
                          # captured one.
  )
  \1                      # Fail if the next character is the captured character.
)
jimmy23013
fuente
Wow buen trabajo. Solo llegué a 83 en .NET y tuve que cambiar a PCRE por 78. No tengo dudas de que terminarás superando eso también. :)
Martin Ender
@ MartinBüttner Sí.
Nic Hartley
Pensé que mi uso de lookahead para vencer a @ MartinBüttner por (en ese momento) 4 bytes era bueno, pero lo has llevado al siguiente nivel.
Neil
Lo sentimos, pero esto no detecta si las celdas en (1, 2) y (2, 1) son iguales, y de manera similar para todas las otras celdas en cuadrados donde el duplicado está debajo y a la izquierda.
Neil
1
@ MartinBüttner Me acabo de dar cuenta de que puedo traducir mi segunda versión de PCRE a Ruby ... Creo que podrías publicar tu respuesta ahora ...
jimmy23013
34

PCRE, 117 119 130 133 147 bytes

^(?!(.{27})*(...){0,2}(.{9})?.?.?(.).?.?(?=(?2)*$).{6,8}(?3)?\4.{0,17}(?1)*$|.*(.)(.{8}(?3)*|((?!(?3)*$)(|.(?7))))\5)

También debería funcionar en sabores Python, Java, etc. Ahora con recursividad! Y la función de "recursión" se usa de forma no recursiva para las "subrutinas", que olvidé por completo hasta que tuve que usar la recursión real.

Feersum
fuente
Idea genial: ¡evite las repeticiones en lugar de norepetir!
Qwertiy
1
Es una pena que no puedas escribir .{27}*.
Neil
Bah, jugué su solución de 133 bytes a 121 bytes solo para descubrir que la había reescrito, pero aquí está de todos modos:^(?!(.{27})*(.{9})?(...){0,2}.?.?(.).?.?(?=(...)*$)(.{9})?.{6,8}\4.{0,17}(.{27})*$|.*(.)((.{9})+|((?!(.{9})*$).)+)(<=\8))
Neil
@Neil ¿Qué sabor es ese? PCRE u otros que conozco no permiten referencias en retrospectiva.
feersum
@Neil (<=\8)no parece una sintaxis válida (le falta una ?). Además, el único sabor que sé que admite referencias posteriores en lookbehinds es .NET.
Martin Ender
15

.NET regex, 8339 bytes

Sí, sé que mi solución es muy ingenua, ya que Martin me dijo que lo hizo en 130 bytes. De hecho, la URL para probarlo en línea es tan larga que no pude encontrar un acortador de URL que lo aceptara.

(code removed, since it's so long nobody will read it here, 
and it made the post take forever to load. Just use the "Try it online" link.)

El siguiente enlace no funciona en IE, pero sí funciona en Chrome y Firefox.

Pruébelo en línea : todos los casos de prueba a la vez, con la ayuda de!`al principio, no incluidos en el recuento de bytes.


Aquí está el script de Python que usé para generarlo (código a continuación):

R=range(0,9)
S=range(1,10)

o = ""

# validate rows
T = "(?=.{%s,%s}%s)"
for j in R:
    for i in S:
        o += T % (9*j,9*(j+1)-1, i)

# validate columns
# "(?=(.{%s}|.{%s}|.{%s}|.{%s}|.{%s}|.{%s}|.{%s}|.{%s}|.{%s})%s)"
T = "(?=("+"|".join([".{%s}"]*9)+")%s)"
for j in R:
    for i in S:
        o += T % (j,j+9,j+18,j+27,j+36,j+45,j+54,j+63,j+72, i)

# validate boxes
# (?=.{0,2}1|.{9,11}1|.{18,20}1)(?=.{3,5}1|.{12,14}1|.{21,23}1)
# (?=.{27,29}1|.{36,38}1|.{45,47}1)
T = ".{%s,%s}%s"
for i in S:
    for x in (0,27,54):
        for y in (0,3,6):
            o += "(?="+"|".join(T % (x+y+z,x+y+z+2, i) for z in (0,9,18))+")"

o += ".{81}"

o = o.replace(".{0}","").replace(",80}",",}")
print(o)
mbomb007
fuente
1
Te estoy apoyando
Martijn
44
¿Sabes qué es gracioso? El enlace de probarlo en línea bloqueará IE porque es demasiado largo: P
cat
15
@cat Es por eso que el único propósito real de IE es permitir al usuario descargar Firefox (o Chromium).
Byte Commander
2
@cat Sin embargo, no bloquea IE11 en Windows 8.1, aunque Regex no se procesa correctamente.
Nzall
2
@cat No bloquea mi IE 11 en Windows 7. Simplemente trunca la URL.
mbomb007
14

.NET regex, 121 bytes

^(?!(.{27})*(.{9})?(...){0,2}.?.?(.).?.?(?=(...)*$)(.{9})?.{6,8}\4.{0,17}(.{27})*$|.*(?=(.))((.{9})+|(.(?!(.{9})*$))+)\8)

Explicación:

^(?!                     Invert match (because we're excluding duplicates)
 (.{27})*                Skip 0, 3 or 6 rows
 (.{9})?                 Optionally skip another row
 (...){0,2}              Skip 0, 3 or 6 columns
 .?.?(.).?.?(?=(...)*$)  Choose any of the next three cells
 (.{9})?                 Optionally skip another row
 .{6,8}\4                Match any of the three cells below
 .{0,17}(.{27})*$        As long as they're from the same square
|                        OR
 .*(?=(.))(              Choose any cell
  (.{9})+                Skip at least one row
 |                       or
  (.                     Skip cells
   (?!(.{9})*$)          Without reaching the end of the row
  )+                     For at least one cell (i.e. the cell chosen above)
 )\8)                    Match the chosen cell to the next cell
)
Neil
fuente
Agradable, tu combinación de filas y columnas es bastante inteligente. Eso ahorra 4 bytes en mi propia solución. :)
Martin Ender
8

PCRE, 3579 bytes

Una solución de fuerza bruta absolutamente terrible. Miradas negativas ahoy!

Pasé demasiado tiempo en esto para abandonarlo, así que aquí está, por el bien de la posteridad.

En el lado positivo, si Sudoku de repente comienza a usar un conjunto diferente de 9 caracteres, supongo que esto seguirá funcionando ...

http://pastebin.com/raw/CwtviGkC

No sé cómo operar Retina, pero también puede pegarlo en https://regex101.com o similar y coincidirá.

Código Ruby utilizado para generar la expresión regular:

# Calculate the block you're in
def block(x)
    x /= 3
    x + x%3 - x%9
end

81.times do |i|
    row, col = i.divmod(9)
    neg = []
    neg += (0...col).map {|e| 9*row + e + 1}
    neg += (0...row).map {|e| 9*e + col + 1}
    neg += (0...i).map {|e| e + 1 if block(e) == block(i)}.compact
    neg = neg.uniq.sort.map {|e| "\\#{e}"}
    if neg.size > 0
        print "(?!#{neg.join '|'})"
    end
    print "(.)"
end
Tinta de valor
fuente
8

Sabor a rubí, 75 74 bytes

Gracias a jimmy23013 por guardar 1 byte.

^(?!(.{9}*(.|(.)){,8}|.*(\g<2>.{8})*|.{27}?.{3}?(\g<2>{3}.{6}){,2}.?.?)\3).

Pruébalo aquí.

Ahora que finalmente está vencido, puedo compartir mi propia solución. :) Descubrí una técnica de expresiones regulares interesante (¿quizás nueva?) En el proceso (la (.|(.)){,8}\3parte), que probablemente sería inmejorable en los casos en que esto no se pueda combinar con otras partes de la expresión regular (como fue el caso en la respuesta de jimmy23013) .

Explicación

Al igual que las otras respuestas cortas, estoy usando una búsqueda anticipada negativa que busca duplicados en filas, columnas o bloques. El componente básico de la solución es este:

(.|(.))...\3

Tenga en cuenta que \3se reutiliza entre tres alternativas diferentes (que utilizan el grupo 3para la detección de duplicados).

Ese grupo a la izquierda (que es grupo 2, que contiene grupo 3) se usa para cualquier posición que pueda contener la primera mitad de un dígito duplicado (dentro de un grupo que no debe contener dígitos duplicados). Entonces, ...es algo que nos lleva a la siguiente posición en la que podría ocurrir dicho dígito (si es necesario) e \3intenta encontrar la segunda mitad del duplicado mediante referencia inversa. La razón por la que esto funciona es retroceder. Cuando el motor coincide por primera (.|(.))vez, simplemente se usará .cada vez y no capturará nada. Ahora el \3al final falla. Pero ahora el motor intentará usarlo gradualmente en (.)lugar de .partidos individuales. Finalmente, si hay un duplicado, encontrará la combinación donde(.)se utilizó por última vez en el primer dígito del duplicado (de modo que la captura no se sobrescriba más tarde), y luego usa un poco más .para cerrar la brecha con la referencia inversa. Si hay un duplicado, el rastreo siempre lo encontrará.

Veamos las tres partes diferentes donde se usa esto:

.{9}*(.|(.)){,8}

Esto busca duplicados en alguna fila. Primero saltamos a cualquier fila con .{9}*. Luego emparejamos hasta 8 caracteres (es decir, cualquier cosa en esa fila, excepto el último dígito) utilizando la captura duplicada opcional e intentamos encontrar la \3siguiente.

.*(\g<2>.{8})*

Esto busca duplicados en alguna columna. Primero, tenga en cuenta que \g<2>es una llamada de subrutina, por lo que es lo mismo que:

.*((.|(.)).{8})*

donde los dos grupos que acabamos de insertar todavía se conocen como 2y 3.

Aquí, .*simplemente salta todo lo que sea necesario (sería suficiente hacer coincidir hasta 8 caracteres aquí, pero eso cuesta más bytes). Luego, el grupo externo coincide con una fila completa (que puede ajustarse en dos filas físicas) a la vez, opcionalmente capturando el primer carácter. Se \3buscará justo después de esto, lo que garantiza la alineación vertical entre la captura y la referencia inversa.

Finalmente, revisando los bloques:

.{27}?.{3}?(\g<2>{3}.{6}){,2}.?.?

Nuevamente, \g<2>es una llamada de subrutina, por lo que es lo mismo que:

.{27}?.{3}?((.|(.)){3}.{6}){,2}.?.?

Para verificar los bloques, tenga en cuenta que dado que ya hemos verificado todas las filas y columnas, solo necesitamos verificar cuatro de los bloques 3x3. Cuando sabemos que todas las filas y columnas, así como estos bloques 3x3 son correctos:

XX.
XX.
...

Entonces sabemos que no puede haber duplicados en los bloques restantes. Por lo tanto, solo estoy revisando estos cuatro bloques. Además, tenga en cuenta que no tenemos que buscar duplicados dentro de la misma fila de un bloque 3x3. Es suficiente encontrar la primera mitad del duplicado en una fila y buscar la segunda mitad en una fila más abajo.

Ahora, para el código en sí, primero saltamos al comienzo de uno de los cuatro bloques con .{27}?.{3}?(opcionalmente salteamos tres filas, opcionalmente salteamos tres columnas). Luego intentamos hacer coincidir hasta dos de las filas del bloque 3x3 con el mismo truco que usamos para las filas anteriores:

(.|(.)){3}.{6}

Permitimos, pero no requerimos, capturar ninguna de las 3 celdas en la fila actual del bloque 3x3 y luego saltar a la siguiente fila con .{6}. Finalmente, tratamos de encontrar un duplicado en cualquiera de las 3 celdas de la fila en la que terminamos:

.?.?

Y eso es.

Martin Ender
fuente
74 ^(?!(.*((.|(.)).{8})*|.{9}*\g<3>{,8}|.{27}?.{3}?(\g<3>{3}.{6}){,2}.?.?)\4):; 73: ^(?!(.*((.|(.)|\4()).{8})*|.{9}*\g<3>{9}|.{27}?.{3}?(\g<3>{3}.{6}){3})\5).
jimmy23013
@ jimmy23013 En realidad estaba usando el \4()truco en una versión anterior para los bloques de 3x3, pero terminé por deshacerme de él, porque era más largo. : D
Martin Ender
@ jimmy23013 Sin embargo, el 73 no verifica la última fila:341572689257698143986413275862341957495726831173985426519234768734869512628517394
Martin Ender
6

Javascript regex, 532 530 481 463 caracteres

Validar filas:

/^((?=.{0,8}1)(?=.{0,8}2)(?=.{0,8}3)(?=.{0,8}4)(?=.{0,8}5)(?=.{0,8}6)(?=.{0,8}7)(?=.{0,8}8)(?=.{0,8}9).{9})+$/

Validar columnas:

/^((?=(.{9}){0,8}1)(?=(.{9}){0,8}2)(?=(.{9}){0,8}3)(?=(.{9}){0,8}4)(?=(.{9}){0,8}5)(?=(.{9}){0,8}6)(?=(.{9}){0,8}7)(?=(.{9}){0,8}8)(?=(.{9}){0,8}9).){9}/

Valide la casilla desde su primer carácter:

/(?=.?.?(.{9}){0,2}1)(?=.?.?(.{9}){0,2}2)(?=.?.?(.{9}){0,2}3)(?=.?.?(.{9}){0,2}4)(?=.?.?(.{9}){0,2}5)(?=.?.?(.{9}){0,2}6)(?=.?.?(.{9}){0,2}7)(?=.?.?(.{9}){0,2}8)(?=.?.?(.{9}){0,2}9)/

Establecer vista previa al inicio del cuadrado:

/^(((?=)...){3}.{18})+$/

Y toda la expresión:

/^(?=((?=.{0,8}1)(?=.{0,8}2)(?=.{0,8}3)(?=.{0,8}4)(?=.{0,8}5)(?=.{0,8}6)(?=.{0,8}7)(?=.{0,8}8)(?=.{0,8}9).{9})+$)(?=((?=(.{9}){0,8}1)(?=(.{9}){0,8}2)(?=(.{9}){0,8}3)(?=(.{9}){0,8}4)(?=(.{9}){0,8}5)(?=(.{9}){0,8}6)(?=(.{9}){0,8}7)(?=(.{9}){0,8}8)(?=(.{9}){0,8}9).){9})(((?=.?.?(.{9}){0,2}1)(?=.?.?(.{9}){0,2}2)(?=.?.?(.{9}){0,2}3)(?=.?.?(.{9}){0,2}4)(?=.?.?(.{9}){0,2}5)(?=.?.?(.{9}){0,2}6)(?=.?.?(.{9}){0,2}7)(?=.?.?(.{9}){0,2}8)(?=.?.?(.{9}){0,2}9)...){3}.{18})+$/

Coincide con toda la cadena.


Prueba en Javascript ES6:

r = /^(?=((?=.{0,8}1)(?=.{0,8}2)(?=.{0,8}3)(?=.{0,8}4)(?=.{0,8}5)(?=.{0,8}6)(?=.{0,8}7)(?=.{0,8}8)(?=.{0,8}9).{9})+$)(?=((?=(.{9}){0,8}1)(?=(.{9}){0,8}2)(?=(.{9}){0,8}3)(?=(.{9}){0,8}4)(?=(.{9}){0,8}5)(?=(.{9}){0,8}6)(?=(.{9}){0,8}7)(?=(.{9}){0,8}8)(?=(.{9}){0,8}9).){9})(((?=.?.?(.{9}){0,2}1)(?=.?.?(.{9}){0,2}2)(?=.?.?(.{9}){0,2}3)(?=.?.?(.{9}){0,2}4)(?=.?.?(.{9}){0,2}5)(?=.?.?(.{9}){0,2}6)(?=.?.?(.{9}){0,2}7)(?=.?.?(.{9}){0,2}8)(?=.?.?(.{9}){0,2}9)...){3}.{18})+$/
;`123456789456789123789123456231564897564897231897231564312645978645978312978312645
725893461841657392396142758473516829168429537952378146234761985687935214519284673
395412678824376591671589243156928437249735186738641925983164752412857369567293814
679543182158926473432817659567381294914265738283479561345792816896154327721638945
867539142324167859159482736275398614936241587481756923592873461743615298618924375
954217683861453729372968145516832497249675318783149256437581962695324871128796534
271459386435168927986273541518734269769821435342596178194387652657942813823615794
237541896186927345495386721743269158569178432812435679378652914924813567651794283
168279435459863271273415986821354769734692518596781342615947823387526194942138657
863459712415273869279168354526387941947615238138942576781596423354821697692734185
768593142423176859951428736184765923572389614639214587816942375295837461347651298`
.split`
`.every(r.test.bind(r))
&&
`519284673725893461841657392396142758473516829168429537952378146234761985687935214
839541267182437659367158924715692843624973518573864192298316475941285736456729381
679543182158926473432817659567381294914256738283479561345792816896154327721638945
867539142324167859159482736275398684936241517481756923592873461743615298618924375
754219683861453729372968145516832497249675318983147256437581962695324871128796534
271459386435168927986273541518734269769828435342596178194387652657942813823615794
237541896186927345378652914743269158569178432812435679495386721924813567651794283
168759432459613278273165984821594763734982516596821347615437829387246195942378651
869887283619214453457338664548525781275424668379969727517385163319223917621449519
894158578962859187461322315913849812241742157275462973384219294849882291119423759
123456789456789123564897231231564897789123456897231564312645978645978312978312645
145278369256389147364197258478512693589623471697431582712845936823956714931764825`
.split`
`.every(s => !r.test(s))
Qwertiy
fuente
Creo que las columnas deberían ser mucho más fáciles que las filas, por lo que me parece curioso que la expresión regular de su columna sea más larga que la fila uno.
Peter Taylor
@PeterTaylor, tienen la misma estructura, pero para las columnas tengo que omitir 9 caracteres en lugar de 1, por lo que .aparece entre (.{9})paréntesis debido a lo siguiente {0,8}. ¿Por qué crees que las columnas deberían ser más cortas?
Qwertiy
@PeterTaylor, sí, las columnas habrían sido más sencillas si supusiera verificar la negación.
Qwertiy
@ SuperJedi224, ¿por qué JavaScript? Espero que esta expresión regular sea válida en todas partes.
Qwertiy
66
@Qwertiy Si bien su expresión regular debería funcionar en muchos sabores, se basa en lookaheads (no disponible en Lua u OCaml, por ejemplo). También es una expresión regular básica o extendida inválida, que utiliza una sintaxis completamente diferente. Es mejor elegir sabor para el reclamo de validez, incluso si la solución funciona en muchos otros.
Dennis