Ladrones: descifrar la expresión regular - Hacer una serpiente

20

Este es el hilo del ladrón. El hilo del policía está aquí .


Una matriz de serpiente es una matriz cuadrada que sigue este patrón:

3 por 3:

1  2  3
6  5  4
7  8  9

y 4 por 4:

1  2  3  4
8  7  6  5
9  10 11 12
16 15 14 13

Su tarea es escribir un código que tome una entrada ny cree dicha matriz, en el mismo idioma que una publicación policial, y con un código que coincida con la expresión regular del policía. El formato de salida de su código debe coincidir con el formato de salida del código del policía.

Deja un comentario debajo de la publicación del policía para indicar que lo has descifrado.

Criterio ganador:

El ganador será el usuario que haya obtenido la mayor cantidad de envíos. En caso de empate, habrá múltiples ganadores.

Stewie Griffin
fuente

Respuestas:

10

Jelly , 9 bytes, rompe la respuesta de @Dennis

²sµUFḤ$¦G

Pruébalo en línea!

Debería ser correcto ahora; Tenía que repensar lo que estaba haciendo.

Explicación

La parte más difícil de este problema es obtener una lista de los índices pares dentro del ¦(que aplica una operación en índices específicos). A diferencia de la mayoría de las operaciones, que usan la entrada a todo el programa como predeterminado para el segundo operando, ¦usa el valor visto más recientemente como predeterminado (porque conceptualmente tiene dos operandos izquierdos, en lugar de un operando izquierdo y derecho como la mayoría de las cosas que tomar en dos valores).

Sin embargo, podemos observar que tenemos una lista de números, incluidos todos los enteros desde 1 hasta la mitad de la entrada, ya en el valor actual en ese momento. Como tal, aplanarlo y duplicarlo nos da una lista de números pares, incluidos todos los índices pares (también algunos otros números pares, pero no nos importan esos). Incluso es posible gastar uno µsolo para evitar una ambigüedad de análisis y aún entrar con 9 caracteres.

²sµUFḤ$¦G
 s         Split
²          {the list of numbers from 1 to} the square of {the input}
  µ        into a number of pieces equal to {the input};
   U       then reverse
       ¦   the elements at indexes
    F      obtained by flattening the split list
      $    and
     Ḥ     doubling each element in the flattened list;
        G  finally, format it into a grid.         
Comunidad
fuente
Uh, la forma en que ¦funciona me mata cada vez, lo intenté ayer pero con más que Uy decidí que no estaba funcionando.
Jonathan Allan
Agradable, casi lo tuve pero me quedé atascado en la selección de todos los demás elementos también. Ffue una gran idea,
ETHproductions
Mi código original es bastante idéntico a esto. Acabo de usar en Jlugar de F.
Dennis
@ Dennis Oh, J... Lo había intentado LRpero no podía obtenerlo en menos de 11 bytes
ETHproductions
9

05AB1E, Emigna

Esta fue mi primera vez usando 05AB1E. Lo tengo con un poco de ayuda. Eso fue divertido. :)

UXFXLNX*+N2BSR1k_iR}ˆ

Pruébalo en línea

Explicación:

U                       Assign input to X
 XF                     For N in range(0,X):
   XL                   Push list [1 .. X]
     NX*+               Add N*X to each element of the list
         N2BSR1k_       Super clever way to get N%2:
                            not bool(reversed(str(bin(N))).index('1')) (N%2 is odd)
                 iR}    if N%2 is odd, then reverse the list
                    ˆ   Add row to global array
                        Implicit print

De hecho, encontré este programa similar por mi cuenta, pero el formato de salida es diferente:

UXFXLNX*+N2BSR1k_iR}=

Pruébalo en línea

[1, 2, 3, 4]
[8, 7, 6, 5]
[9, 10, 11, 12]
[16, 15, 14, 13]

Vea el historial de edición de mis dos intentos anteriores.

mbomb007
fuente
¡Buen trabajo! Muy similar a la solución original.
Emigna
55
not bool(reversed(str(bin(N))).index('1'))... Creo que esa es la forma más absurda que he visto a alguien hacer una N%2operación.
Stewie Griffin
3
@StewieGriffin Cuando la vida te da limones pero no agua ni azúcar, solo tienes que comerlos crudos. : D
mbomb007
6

Python 2, Dennis

Este es un divertido problema de golf simbólico.

while ord>eval:1;int,eval=int<1and(int,eval+1)or(-input(),1);i=int;ord=i*i;print'%*s'%(-i,(eval+~i+~-eval%-i*~1,eval)[eval/i&1])+'\nt'[:-1<eval%int],

Verificación de expresiones regulares

xsot
fuente
5

Oh, Nick Clifford.

Mi primera vez intentando Ohm.
Muy buen lenguaje que espero usar de nuevo :)

²@┼σ▓_^è?R

Explicación

²             # square input
 @            # range [1 ... input^2]
  ┼σ          # split in input sized chunks
    ▓         # perform the following block on each element of the array
     _        # current element
      ^è?     # if index is odd
         R    # reverse

Mi primer intento que no funcionó como agregar una matriz y un int no es posible:

@┼MDR┼+;W

Mi segundo intento que no coincidió con la expresión regular:

²@┼σ▓_^MR
Emigna
fuente
¡Lo hiciste exactamente como yo! ¡Gran trabajo!
Nick Clifford
5

05AB1E, Emigna (segunda presentación)

Primera vez trabajando con 05AB1E.

VYLUYFYXDˆ+RU

Pruébalo en línea! El | Verificación de expresiones regulares

Explicación

VYLUYFYXDˆ+RU  # Implicit input
V              # Save input to Y
 YL            # Push [1 .. Y]
   U           # Save list to X
    YF         # Repeat Y times:
      YX       # Push Y, then X
        Dˆ     # Add X into the global array (could've used X here instead)
          +    # Push X + Y
           R   # Reverse top of stack
            U  # Save updated list to X
               # Implicit loop end
               # Implicit global array print if stack is empty
Tinta de valor
fuente
¡Buen trabajo! Tienes la solución deseada :)
Emigna
@ Emmigna gracias! ¡No lo habría obtenido si no fuera por las otras soluciones aquí (incluida la suya) que me permiten darme cuenta de que la matriz global se imprimirá si la pila está vacía! Si no fuera por eso, nunca lo habría descubierto; Seguí intentando hacer trucos que terminaban )pensando que sería la única forma de obtener el resultado correcto en la pila.
Value Ink
Sí, es bastante imposible hacerlo )cuando solo puedes usar 2 caracteres no alfanuméricos. La parte difícil aquí estaba destinada a estructurar el programa para usar solo 2 comodines y tenerlos secuenciales. Probablemente hubiera sido un poco más difícil sin las otras soluciones, pero debería haber sido un poco complicado :)
Emigna
@Emigna Lo que quiero saber es si ^\w*..$es posible.
mbomb007
@ mbomb007: No lo creo. Con esta táctica, necesitaría guardar el resultado de la adición para la próxima iteración y no puede usar la pila para esto, lo que significa que UVdebe venir después . No puedo pensar en otra forma de hacerlo con solo 2 comodines al final tampoco. Sin embargo, se puede hacer con 3 comodines.
Emigna
5

CJam , Lynn

esmpmpmeimtmemqmememqicelic
esmpmpmeimememqmlmtmemoc
esmpmpmeimememqmtmtmtmtmeic
esmpmpmeimememqmtmtmtmtmeic
esmpmpmeimeiscic
esmpmpmeimemeimfsic
esmpmpmeisciscimqmtmemeic
esmpmpmeiscimlmqmqmemeic
esmpmpmeimemomqmqmemeic
esmpmpmeisciscimfsimqic
esmpmpmeimeiscic
esmpmpmeisciscimfsimqic
esmpmpmeimemomqmemqmemtmemoc
esmpmpmeiscic
esmpmpmeimemomeimqmeic
esmpmpmeimemeimqmlmtmeic
esmpmpmeimtmtmqmemtmtmeic
esmpmpmeimemomqmqmtmeic
esmpmpmeimemqmqmemeic
esmpmpmeiscimlmqmqmemeic
esmpmpmeiscimqmtmtmtmqmemeic
esmpmpmeimeimemtmqmemeic
esmpmpmeimeiscimlmlmtmlmtic
esmpmpmeimemeimqmlmtmeic
~~

Todos los avances de línea son para fines cosméticos y se pueden eliminar sin afectar el programa.

Pruébalo en línea!

Explicación

Después de que Lynn fuera eliminada {|}de la lista de personajes permitidos, tuve que probar algo nuevo. Resulta que todavía podemos construir cadenas arbitrarias y evaluarlas como código.

Primero, necesitamos obtener algo de valor en la pila. Los únicos elementos integrados disponibles que empujan algo sin que aparezca otra cosa primero (y sin leer la entrada) son es, eay et. Estoy seguro de que podría comenzar desde todos estos aspectos de una forma u otra, pero fui con lo esque empuja la marca de tiempo actual. Como no quería hacer suposiciones acerca de su valor real, pruebo su primalidad con mp(que da 0y 1) y pruebo nuevamente la primalidad de ese valor para asegurarme de que tengo una 0pila. A 1será más útil, de modo que calculamos exp(0)con mey convertirlo en un número entero con i. Entonces todos los números comienzan con:

esmpmpmei

Ahora tenemos un montón de operadores matemáticos unarios para trabajar:

i    int(x) (floor for positive numbers, ceiling for negative)
me   exp(x)
ml   ln(x)
mq   sqrt(x)
mo   round(x)
mt   tan(x)

También podemos combinar algunos elementos integrados para funciones más elaboradas de x:

sci     Extract first digit of x and add 48 (convert to string, convert
        to character, convert to integer).
ceui    Convert to character, convert to upper case, convert to integer.
celi    Convert to character, convert to lower case, convert to integer.
mfsi    Get a sorted list of prime factors of x and concatenate them into 
        a new number.
mfseei  Get a sorted list of prime factors, interleave it with 1,2,3,..., and
        concatenate the result into a new number.

Con estos, podemos obtener cualquier número en 0 <= x < 128(y muchos otros) en menos de 10 pasos 1. Estoy seguro de que un subconjunto mucho más pequeño de estos comandos también sería suficiente. He escrito un pequeño programa de Mathematica para determinar todos estos fragmentos (no es muy legible, lo siento):

codes = SortBy[
  Select[Nest[Select[DeleteDuplicatesBy[SortBy[Join @@ (Through[{
               List,
               If[1 <= # < 50, {Exp@#, #2 <> "me"}, Nothing] &,
               If[# >= 1, {Log@#, #2 <> "ml"}, Nothing] &,
               If[# > 1, {Sqrt@#, #2 <> "mq"}, Nothing] &,
               {If[# > 0, Floor@#, Ceiling@#], #2 <> "i"} &,
               {Floor[# + 1/2], #2 <> "mo"} &,
               {Tan@#, #2 <> "mt"} &,               
               If[NumberQ@# && # >= 0, {First@
                   ToCharacterCode@ToString@#, #2 <> "sci"}, 
                 Nothing] &,
               If[IntegerQ@# && 
                  32 < # < 65536, {First@
                   ToCharacterCode@
                    ToUpperCase@FromCharacterCode@#, #2 <> "ceui"}, 
                 Nothing] &,
               If[IntegerQ@# && 
                  32 < # < 65536, {First@
                   ToCharacterCode@
                    ToLowerCase@FromCharacterCode@#, #2 <> "celi"}, 
                 Nothing] &,
               If[IntegerQ@# && # > 0, ## & @@ {
                   {FromDigits[
                    "" <> (ToString /@ (f = 
                    Join @@ Table @@@ FactorInteger@#))], #2 <> 
                    "mfsi"},
                   {FromDigits[
                    "" <> (ToString /@ 
                    MapIndexed[## & @@ {#2[[1]] - 1, #} &, f])], #2 <>
                     "mfeesi"}
                   }, Nothing] &
               }@##] &) @@@ #, StringLength@*Last], 
       First], #[[1]] < 1000000 &] &, {{1, "esmpmpmei"}}, 9], 
   IntegerQ@# && 0 <= # < 128 &@*First], First]

Con eso, simplemente podemos empujar una lista arbitraria de códigos de caracteres, convirtiendo cada uno de ellos en un carácter con cposterioridad. Una vez que hemos empujado todo el código que queremos ejecutar, presionamos 95( ]). Evaluamos ese con ~para envolver todos los demás en una cadena, y luego evaluamos esa cadena con ~.

El código real que se ejecuta al final del programa es nuevamente:

ri__2#,:)/2/[1W]f.%:~<p

Vea mi solución anterior para una explicación.

Martin Ender
fuente
4

Python 3, TuukkaX

Lo sentimos, la expresión regular que usaste fue demasiado fácil de trivializar. No hay 0, #o ? ¡No hay problema!

Es posible que haya malinterpretado el resultado del ejemplo, pero todavía es bastante fácil de modificar, ya que me sobran 45 caracteres de repuesto.

n=int(input())
print(str(n)+":")
x=1-1
exec("print([*range(1+x*n,1+n*-~x)][::(1,-1)[x%2]]);x+=1;"*n)
"no-op:a_string_that_doesnt_actually_matter"
Tinta de valor
fuente
¡Agradable! : D FYI: Crearé otro en Python, si estás interesado en resolverlo;) Será un poco más largo, pero la belleza radica en lo indescifrable.
Yytsi
4

R, MickyT

lets_make_a_snake<-function(n)`for`(i,1:n,cat(i*n+1-`if`(i%%2,n:1,1:n),"\n"))

Casos de prueba:

> lets_make_a_snake(4)
1 2 3 4 
8 7 6 5 
9 10 11 12 
16 15 14 13 
> lets_make_a_snake(7)
1 2 3 4 5 6 7 
14 13 12 11 10 9 8 
15 16 17 18 19 20 21 
28 27 26 25 24 23 22 
29 30 31 32 33 34 35 
42 41 40 39 38 37 36 
43 44 45 46 47 48 49 

Y confirmación de expresiones regulares: https://regex101.com/r/OB8ZIM/1

También tenía:

invisible(sapply(1:(n=scan()),function(i)cat(i*n+1-`if`(i%%2,n:1,1:n),"\n")))

que da la misma salida y coincide con la misma expresión regular .

plannapus
fuente
66
lets_make_a_snake... Me sorprendería si esa fuera la solución prevista: P
Stewie Griffin
@plannapus Buen trabajo. El primero es básicamente lo que pretendía usar ` for` y ' if', pero mucho mejor golf que el mío.
MickyT
4

Röda , fergusq

{|i|;a=1;while[a<=i]do;b=a*i-i+1;c=[];while[b<=a*i]do;c+=b;b++;done;{d=[];x=0;while[x<i]do;d+=c[i-x-1];x++;done[d]}if[a%2<1]else{[c]};a++;done;r="||||||"}

Esta es una función anónima que coincida con esta expresión regular PCRE: ^{(\|[^\/#\s]*){8}$.

Pruébalo en línea!

Kritixi Lithos
fuente
4

Golpetazo, @Marcos M

sort -n <(seq 1 $((n * n)) | xargs -n$n | sed -n 'p;n'; seq $((n * n)) 1 | xargs -n$n | sort -n | sed -n 'n;p')

Prettified:

sort -n <(               # feed the stdout of this subshell into stdin for `sort -n`
    seq 1 $((n * n)) |   #   generate 1 2 3 ... n²
        xargs -n$n |     #     add line break every n numbers
        sed -n 'p;n';    #     print only odd lines
    seq $((n * n)) 1 |   #   generate n² ... 3 2 1
        xargs -n$n |     #     add line break every n numbers
        sort -n |        #     reverse all lines (keeping each row decreasing)
        sed -n 'n;p'     #     print only even lines
)

La primera parte de la subcomando generará 1 2 3 4, 9 10 11 12y la segunda parte generará8 7 6 5 , 16 15 14 13. El exterior sort -nlos mezclará adecuadamente para formar el patrón de serpiente.

Utilicé el truco en /superuser//a/101760 para imprimir las líneas pares e impares. Gracias Marcos, realmente divertido.

kennytm
fuente
Muy buena solución
Mitchell Spector
3

Javascript, Tom

f=(a,i=1,j=0)=>Array(a).fill(0).map(b=>Array(a).fill(0).map(a=>i++)).map(a=>j++%2?a.reverse():a).map(a=>a)

console.log(f(4))

ovs
fuente
3

Python 3, @TuukkaX

n=int(input());j=0;exec("print([(j-+i%n-n++2*n-0,j+i%n+1)[1&int(i/n)//1^(0x1)//1]*(2*(i%n)*0+2222222//2222222)for i in range(j,j+n)]);j+=n;"*n)

Al analizar ligeramente la expresión regular del policía, se muestra una plantilla fija:

________________________"___________i%n____2*n-____i%n__________i/n)//1_____)//1___2*(i%n)____^^^^^^^^^^^^^^^^for i in range(j,____])______"*n)

donde _es cualquier caracter excepto [ '"#]y^ es cualquiera de [int()2/].

Al "*n)final muestra claramente un eval("..."*n)oexec("..."*n) está sucediendo, por lo que solo debemos asegurarnos de que "..."imprima la fila j.

El for i in range(j,está demasiado cerca del final de la cadena, insinuando la comprensión de la lista sin ninguna if. Por lo que necesitamos para construir la i-ésima columna usando aquellos i%n, 2*nesas cosas.

n = int(input())
j=0
exec("""print([
    (
        j - +i%n - n ++ 2*n - 0,    # equivalent to (n + j - i%n) for the decreasing rows
        j + i%n + 1                 # equivalent to (j + i%n + 1 == i + 1) for the increasing rows
    )[1 & int(i/n)//1 ^ (0x1)//1]   # int(i/n)   ->    get row number 0, 1, 2, 3, ...; 
                                    # 1 & int(i/n)//1    ->    0 for increasing rows, 1 for decreasing rows, 
                                    # 1 & int(i/n)//1 ^ (0x1)//1    ->   flip 0 and 1
    * (2*(i%n)*0+2222222//2222222)  # multiply by the constant 1.
    for i in range(j,j+n)
]); j+=n; "*n)
kennytm
fuente
¡Agradable! Bueno, casi sobreviví una semana: D Publicaré mi código original.
Yytsi
3

dc , Mitchell Spector

Esta fue mi primera entrada a un desafío de policías y ladrones, y me divertí mucho. La expresión regular que necesitaba coincidir era simple, lo ^[^# !]{59}$que básicamente convirtió mi trabajo en golf, sin usar esos 3 caracteres. Inicialmente tuve dificultades para llegar a menos de 60 bytes, pero al final lo resolví.

?sN0[AP]sP[ddlN~_2*lN+1-r2%*+1+n32P1+dlN%0=PdlNd*>L]dsLxqqq

Pruébalo en línea!

Explicación:

Mi código usa un bucle con N 2 iteraciones de , manteniendo un contador basado en cero (1D), y calcula qué número debe imprimirse en función de las coordenadas de fila y columna de matriz (r, c) correspondientes.

Ejemplo de lo que quiero decir, si N = 4:

 0  1  2  3            (0,0) (0,1) (0,2) (0,3)             1  2  3  4
 4  5  6  7     ->     (1,0) (1,1) (1,2) (1,3)     ->      8  7  6  5
 8  9 10 11            (2,0) (2,1) (2,2) (2,3)             9 10 11 12
12 13 14 15            (3,0) (3,1) (3,2) (3,3)            16 15 14 13

Parece complicado, pero el paso intermedio es útil. Además, intenté usar 2 bucles desde el principio, pero terminé por encima del límite de caracteres regex. Generación de números en cada iteración (basada en cero):

  • Si r % 2 = 0 (fila normal),n = (r * N) + c = counter
  • si r % 2 = 1(fila invertida),n = ((r + 1) * N) - c - 1 = counter + N - (2 * c) - 1

O todo a la vez, como una numeración basada en uno: n = counter + ((N - (2 * c) - 1) * (r % 2)); n++

?sN0             # read input, save as N, initialize iteration counter
[AP]sP           # macro 'P' that prints a newline (ASCII code 10 = A)
[                # start loop
    ddlN~        # push N, calculate row and column coordinates:
                 #r = int(counter / N), c = counter % N, '~' calculates both
    _2*lN+1-     # c is on top, so this does: N - (2 * c) - 1
    r2%*+        # now r is on top, do: (r % 2) * (previous result) + counter
    1+n32P       # do: n++, print space (ASCII code 32)
    1+           # increment counter
    dlN%0=P      # call macro 'P' every Nth printed number
    dlNd*>L      # if: N * N > counter, repeat loop
]dsLx            # this saves the loop to macro 'L', then executes it
qqq              # my script was shorter, so I added a bunch of quit commands to
                 #fit the regex limit. Use of comments ('#') was prohibited.
seshoumara
fuente
@ MitchellSpector Aquí está mi explicación. Como puede ver, ambos tenemos literalmente el mismo algoritmo, solo yo uso el comando ~para calcular los índices de fila y columna de una vez. Pero uno de mis intentos anteriores los calculó por separado como lo hizo. ¿Grandes mentes piensan igual? :)
seshoumara
1
Sí, realmente es el mismo algoritmo. Me gusta su uso ~para acortar el código.
Mitchell Spector
Creo que puede acortarlo en un byte si usa el truco de raíz cuadrada en la prueba de bucle al final de la macro: ?sN0[AP]sP[ddlN~_2*lN+1-r2%*+1+n32P1+dlN%0=PdvlN>L]dsLx tio.run/nexus/…
Mitchell Spector
@ MitchellSpector Tienes razón, y lo noté cuando leí tu explicación, pero en su lugar comenté en la sala de chat .
seshoumara
Sí, lo veo ahora, todavía no había mirado la sala de chat esta mañana.
Mitchell Spector
3

Potencia Shell, ConnorLSW

Grieta

$mySnakeIndex=1;$seq=1..$args[0];$seq|%{$rowNum=$seq|%{($mySnakeIndex++)};if(!($_%2)){[array]::Reverse($rowNum)};$rowNum-join" "}

Comencé con una solución más pequeña para el problema y rellené mis nombres de variables para que la expresión regular coincida. Tratar de encontrar un uso para el colon, supongo, fue la parte más difícil de entender.

$a=1..$args[0];$i=1;$a|%{$r=$a|%{($i++)};if(!($_%2)){[array]::Reverse($r)};$r-join" "}

Explicación

# Initialize a counter that starts at one.
$mySnakeIndex=1
# Save the integer array from 1 to the input value. 
$seq=1..$args[0]
# For each row of the output...
$seq|%{
    # Build the integer array for this row sequentially
    $rowNum=$seq|%{
        # Increase the integer index while sending it down the pipeline
        ($mySnakeIndex++)}
        # Check if this is and odd row. If so reverse the integer array.
        if(!($_%2)){[array]::Reverse($rowNum)}
        # Take this row and join all the numbers with spaces.
        $rowNum-join" "
Mate
fuente
Agradable, usé una $scriptvariable y algunos bucles realmente desordenados para rellenarlo, sin embargo, [array]::Reverse()fue correcto, felicidades, creo que es posible que desee igualar la longitud de $iy $MySnakeIndexsin embargo.
colsw
@ConnorLSW Sé que no podrías dormir por la noche sabiendo que tuve errores en mi ladrón. Lo he arreglado
Matt
3

CJam, Lynn

Algo como esto:

ri
{s}seu~~ci{zs}seu~~c{a}seu~~|~{w}seu~~z{w}seu~~sc~c{z}seu~~{w}seu~~sc~c{w}seu~~z{w}seu~~sc~c~

{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{w}seu~~z{w}seu~~sc~c
{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{w}seu~~z{w}seu~~sc~c
{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{w}seu~~z{w}seu~~sc~c
{s}seu~~c{a}seu~~|
{s}seu~~c{c}seu~~|
{t}seu~~sc{a}seu~~|
{s}seu~~c{a}seu~~|{w}seu~~z{w}seu~~sc~c
{s}seu~~sc{fb}seu~~||
{s}seu~~sc{i}seu~~|
{s}seu~~sc{fb}seu~~||
{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{w}seu~~z{w}seu~~sc~c{z}seu~~{w}seu~~sc~c{w}seu~~z{w}seu~~sc~c
{a}seu~~scs
{w}seu~~
{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{z}seu~~{w}seu~~sc~c
{fb}s{b}s{w}seu~~sc~
{s}seu~~sc{ee}seu~~||
{s}seu~~sc{z}seu~~|{w}seu~~{w}seu~~sc~{w}seu~~{w}seu~~sc~
{t}seu~~sc{a}seu~~|
{~}s{}s{w}seu~~sc~
{t}seu~~sc{c}seu~~|

{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{z}seu~~{w}seu~~sc~c~
s~
p

Todo el espacio en blanco es para ... "legibilidad" ... y puede omitirse para cumplir con la expresión regular de Lynn.

Pruébalo en línea!

Explicación

La expresión regular requiere que resolvamos el problema usando solo:

  • Letras minusculas.
  • {}, que se puede usar para crear bloques.
  • |, utilizado principalmente para OR bit a bit.
  • ~, "eval" y NO a nivel de bits (también "dump array", pero no lo voy a usar).

Como lo hemos hecho, ~si podemos construir cadenas arbitrarias, podemos ejecutar código arbitrario. Sin embargo, al principio no es obvio cómo hacerlo.

La primera pieza del rompecabezas es que los bloques son bits de código no evaluados, que pueden convertirse en cadenas con s. Eso {abc}snos da "{abc}". A continuación, podemos usar eupara convertir estas cadenas a mayúsculas.

{abc}seu  e# gives "{ABC}"

El beneficio de esto es que las letras mayúsculas son variables preinicializadas, por lo que podemos obtener muchos valores constantes al crear una cadena de este tipo y evaluarla dos veces (una para volver a convertir la cadena en un bloque y otra para ejecutar ese bloque). No podemos obtener todas las letras, porque algunas, como xno son comandos válidos (por lo que CJam se negará a analizar un bloque que las contenga). No podemos usarlo ftal cual, porque necesita ser seguido por otro comando, pero podemos usar fby luego O los dos valores juntos. Del mismo modo, podemos usar en eelugar de e. Con esto, podemos obtener los números 0, -1, 3, y 10a 19. El-1 es conveniente, porque si lo convertimos en una cadena ( "-1"), entonces en un carácter ('-) y luego evaluarlo, podemos obtener la resta o establecer la diferencia. Como dije, no podemos obtener X(for 1), pero podemos tomar el valor absoluto de -1with z.

También podemos usar spara obtener una cadena que contenga un espacio, y usar cpara convertir eso en un carácter de espacio :

{s}seu~~c

Esto es conveniente, porque a partir de ahí podemos obtener muchos comandos útiles en el rango ASCII más bajo OR al espacio con varios números. Para obtener algunos de los caracteres sobre el punto de código 48, usamos el carácter '0como base en su lugar:

{t}seu~~si

Esto ya es suficiente para construir cadenas arbitrarias, porque podemos obtener '+(suma y concatenación de cadenas) del siguiente fragmento:

{s}seu~~c{b}seu~~|

Y tenemos un literal 1 para que podamos empujar los caracteres de espacio, incrementarlos al valor que necesitamos y luego concatenarlos todos juntos, pero eso es un poco aburrido y el código se volvería masivo.

En cambio, los he generado [y ]evaluado, de modo que todos los caracteres que introduzco se envuelven en una cadena automáticamente. Estas son dos líneas:

{s}seu~~ci{zs}seu~~c{a}seu~~|~{w}seu~~z{w}seu~~sc~c{z}seu~~{w}seu~~sc~c{w}seu~~z{w}seu~~sc~c~

...

{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{z}seu~~{w}seu~~sc~c~

Y finalmente, necesitaremos fy ~en la cadena que estamos generando. Si bien estos ya son caracteres válidos, no tenemos literales de cadena o literales de caracteres, por lo que también tendríamos que generarlos y construir puntos de código más grandes desde el espacio es un poco molesto. En cambio, he hecho uso de la resta establecida aquí, pero restando dos bloques (para deshacerme de {}):

{fb}s{b}s{w}seu~~sc~
...
{~}s{}s{w}seu~~sc~

Eso es casi todo lo que hay que hacer. Nos Eval [. Empujamos todos los caracteres, obtenidos por varios cálculos de las pocas constantes incorporadas que tenemos |, -(a través de eval) y +(a través de eval). Nos Eval ]. Aplanamos todo en una cadena, porque en algún momento agregué algunas cadenas o números a la lista. Evaluamos nuestra cadena arbitraria con~ .

los ri...p forman parte del programa final real, pero yo los he extraído, ya que no necesitan codificación.

Finalmente, este es el programa que realmente estamos ejecutando:

ri___*,:)/2/[1-1]f.%:~<p

ri      e# Read input and convert to integer.
__      e# Make two copies.
_*      e# Square the last copy.
,       e# Turn into range [0 1 ... n^2-1].
:)      e# Increment each to get [1 2 ... n^2].
/       e# Split into chunks of length n, creating a square.
2/      e# Split into pairs of lines.
[1-1]   e# Push [1 -1].
f.%     e# Use this to reverse the second line in each pair. If n was odd,
        e# this will pair a -1 with the last line.
:~      e# Flatten the pairs back into the square.
<       e# Truncate to n lines to get rid of that extraneous -1 for odd inputs.
p       e# Pretty-print.
Martin Ender
fuente
3

tinylisp , @DLosc

(v(c(h(q(d)))(c(h(q(f)))(q((c(q(n))(q((g(v(h(q(n))))(s(v(h(q(n))))(v(h(q(1)))))())))))))))(v(c(h(q(d)))(c(h(q(mod)))(q((c(c(h(q(x)))(q(y)))(q((i(l(v(h(q(x))))(v(h(q(y)))))x(mod(s(v(h(q(x))))(v(h(q(y)))))y))))))))))(v(c(h(q(d)))(c(h(q(range)))(q((c(c(h(q(x)))(c(h(q(y)))(c(h(q(z)))(q(w)))))(q((i(l(times(v(h(q(z))))(v(h(q(x))))(v(h(q(0)))))(times(v(h(q(z))))(v(h(q(y))))(v(h(q(0))))))(range(v(h(q(x))))(s(v(h(q(y))))(v(h(q(z)))))z(c(s(v(h(q(y))))(v(h(q(z)))))w))w)))))))))(v(c(h(q(d)))(c(h(q(times)))(q((c(c(h(q(x)))(c(h(q(y)))(q(acc))))(q((i(l(v(h(q(x))))(v(h(q(0)))))(times(s(v(h(q(0))))(v(h(q(x)))))(s(v(h(q(0))))(v(h(q(y)))))acc)(i(e(v(h(q(x))))(v(h(q(0)))))acc(times(s(v(h(q(x))))(v(h(q(1)))))y(a(v(h(q(y))))(v(h(q(acc))))))))))))))))(v(c(h(q(d)))(c(h(q(g)))(q((c(c(h(q(n)))(c(h(q(w)))(q(r))))(q((i(l(v(h(q(w))))(v(h(q(0)))))r(g(v(h(q(n))))(s(v(h(q(w))))(v(h(q(1)))))(c(i(e(v(h(q(0))))(mod(v(h(q(w))))(v(h(q(2))))))(range(a(v(h(q(1))))(times(v(h(q(w))))(v(h(q(n))))(v(h(q(0))))))(a(a(v(h(q(1))))(times(v(h(q(w))))(v(h(q(n))))(v(h(q(0))))))n)1())(range(a(times(v(h(q(w))))(v(h(q(n))))(v(h(q(0)))))n)(times(v(h(q(w))))(v(h(q(n))))(v(h(q(0)))))(s(v(h(q(0))))(v(h(q(1)))))()))r)))))))))))

Pruébalo en línea!

Esto define una función fque devuelve la respuesta. También imprime los nombres de las funciones que definí para stdout, pero supongo que eso no importa, ya que [al menos se nos permite elegir nuestro flujo de salida] para el código de golf. Si es un gran problema, creo que puedo modificarlo para no imprimirlos. Como lo hice Empecé con algo bastante estándar:

(d f (q ((n)
  (g n (s n 1) ()))))

(d mod (q((x y)
  (i (l x y) x
    (mod (s x y) y)))))

(d range (q((x y z w)
  (i (l (times z x 0) (times z y 0))
    (range x (s y z) z (c (s y z) w))
    w))))

(d times (q ((x y acc)
  (i (l x 0) (times (s 0 x) (s 0 y) acc)
  (i (e x 0) acc
    (times (s x 1) y (a y acc)))))))

(d g (q ((n w r)
  (i (l w 0) r
    (g n (s w 1)
       (c (i (e 0 (mod w 2))
             (range (a 1 (times w n 0)) (a (a 1 (times w n 0)) n) 1 ())
             (range (a (times w n 0) n) (times w n 0) (s 0 1) ()))
          r))))))

Luego, observé que uno puede transformar definiciones de funciones como esta:

(d mod (q ((x y) (body))))

se convierte

(v(c(h(q(d)))(c(h(q(mod)))(q((c(c(h(q(x)))(q(y)))(q((body)))))))))

Y la función llama así:

(a x y)

se convierte

(a(v(h(q(x))))y)

Usé esta macro recursiva de Vim, almacenada en el registro q, para hacer la segunda (me he jkasignado <Esc>):f s(v(h(q(jkea))))jk@q .

Estas dos transformaciones fueron suficientes para eliminar todos los espacios.

Brian McCutchon
fuente
¡Bien hecho! Mi código original es bastante similar, aunque escribí una macro auxiliar para que sea un poco menos doloroso de escribir. Tengo curiosidad sobre sus pensamientos sobre cómo evitar imprimir los símbolos definidos; si desea compartirlos, estaré en la sala de chat de tinylisp .
DLosc
@DLosc Hecho, publiqué allí.
Brian McCutchon
2

Swift, @James Webster

{n in for j in 0..<n{print((1...n).map{j%2==0 ?$0+j*n:j*n+n+1-$0})}} as(CShort)->()

Verificación: https://regex101.com/r/7ukrM0/1

kennytm
fuente
Obtengo "Expression resuelve una función no utilizada" con esto por sí solo, pero no estoy familiarizado con todo lo que hace una respuesta aceptable. Es, por ejemplo, `let a = <code>; a (CShort (4)); requerido para que funcione no es necesario?
James Webster
@JamesWebster No estoy seguro acerca de las reglas exactas ya que "un código" es bastante ambiguo. Para code-golf, el envío puede ser un programa o función , por lo que solo proporciono una función anónima aquí. ¿De qué otra forma recibimos los argumentos de entrada?
kennytm
Mi original era el cuerpo de una función, ¡así que tampoco estoy seguro de que el mío sea válido! Así que voy a ir con "Claro, esto está bien" y lo votaré. :)
James Webster el
@JamesWebster Puede llamar todo (…)(4), ya que no es necesario convertir el entero literal a CShort.
kennytm
¡Ah sí! Nunca hubiera pensado en eso.
James Webster
2

PHP, @ JörgHülsermann

<?=(function($n,$snake){foreach(array_chunk(range(1,$n*$n),$n)as$i=>$a){if($i%2)$a=array_reverse($a);echo"\n",join('',array_map(function($e){return(sprintf("%3d",$e));},$a));}})($argv[1],'-=-=-=-=-=-=-=-=-=-=-=-=-=-o~')?>

221 bytes es demasiado largo (por lo tanto, la serpiente), y la falta de espacios en blanco se puede solucionar fácilmente.

Prettified:

<?=
(
    function($n, $snake) {
        foreach (array_chunk(range(1, $n*$n), $n) as $i => $a) {
            if($i % 2)
                $a = array_reverse($a);
            echo "\n", join('', array_map(function($e) {
                return (sprintf("%3d", $e));
            }, $a));
        }
    }
)($argv[1], '-=-=-=-=-=-=-=-=-=-=-=-=-=-o~')
?>
kennytm
fuente
Bonita variante. Mi culpa no fue pensar en una función y hacer una sola salida
Jörg Hülsermann
2

Jelly, longitud 12, @JonathanAllan

Ḷ-*m@"s@²$G

Pruébalo en línea!

Cómo funciona

Ḷ-*m@"s@²$G  Main link. Argument: n

Ḷ            Unlength; yield [0, ..., n-1].
 -*          Yield [(-1)**0, ..., (-1)**(n-1)].
         $   Combine the two links to the left into a chain.
        ²    Yield n².
      s@     Split [1, ..., n²] into chunks of length n.
   m@"       Take the lists to the right modulo the units to the left, 1 being
             normal order and -1 being reversed.
Dennis
fuente
2

Jelly , 12 bytes, descifra la segunda respuesta de @ JonathanAllan

²sµ;@/€FḤ$¦G

Pruébalo en línea!

Explicación

Esto es casi lo mismo que mi otra respuesta . Acabo de hacer dos cambios:

Primero, cambié U("invertir cada elemento") a Ṛ€("invertir" "cada elemento"). Eso no ayuda por sí solo, porque también está prohibido.

Luego, cambié el ("reverso") a ;@/( /"doblar por" ;"concatenando" @"en el orden opuesto a la lista original"). Eso evita todos los personajes prohibidos, dando una solución válida.

Supongo que el siguiente paso sería comenzar a prohibir las manipulaciones rápidas de la matriz , además de los átomos.

Comunidad
fuente
Sabía que debería haber prohibido ...
Jonathan Allan
Puedes escribir en términos de /también. Es bastante más detallado que esta solución.
Sí, y uno podría ;@\ṫ0, la expresión regular se está alargando.
Jonathan Allan
2

Jelly, longitud 13, @JonathanAllan

1r-*Nm@"s@²$G

Pruébalo en línea!

Cómo funciona

1r-*Nm@"s@²$G  Main link. Argument: n

1r             Range 1; yield [1, ..., n].
 -*            Yield [(-1)**1, ..., (-1)**n].
   N           Negate each unit.
           $   Combine the two links to the left into a chain.
          ²    Yield n².
        s@     Split [1, ..., n²] into chunks of length n.
     m@"       Take the lists to the right modulo the units to the left, 1 being
               normal order and -1 being reversed.
Dennis
fuente
Oh espera, ¿qué, me perdí m?
Jonathan Allan
2

Jelly, longitud 14, @JonathanAllan

²sµðạ"J×2$$¦GµL.xị"ḅ1µ$

Pruébalo en línea!

Dennis
fuente
Eso es impresionante: D
Jonathan Allan
¡Gracias! :) Por alguna razón, estaba convencido de que mi código no podía contener nuevas líneas, lo que me obligó a descubrir algunos trucos de la cadena.
Dennis
2

Scala, @Soapy

def g(n:Int) = {
    var vec = Vector.fill(0)(Vector.fill(0)(1))
    for (p <- 1 to n) {
        var vec2 = Vector.fill(0)(1)
        for (q <- (p-1)*n+1 to p*n) {
            vec2 = vec2 ++ Vector(q)
        }
        if (p%2==1) vec = vec ++ Vector(vec2)
        else vec = vec ++ Vector(vec2.reverse)

    }
    println(vec)
}

Hace tiempo que no toco a Scala, fue divertido volver a visitarlo. Desafortunadamente, esta solución se pierde muchas de las características interesantes de Scala.

Pruébalo aquí

Confirmación de expresiones regulares

adicto a las matemáticas
fuente
2

QBasic (QB64), @DLosc

Tenga en cuenta que dado que el .no coincide \n(U + 000A, LF), la nueva línea aquí es un \r(U + 000D, CR).

INPUT N:ZERO=N-N:ONE=N/N:FOR I=ZERO TO N-ONE:FOR J=ONE TO N:IF ZERO=I MOD(ONE+ONE)THEN PRINT I*N+J;ELSE PRINT I*N+N-J+ONE;REM
NEXT:PRINT:NEXT

Verificar:

>>> re.match('^([A-Z]+.)+$', 'INPUT N:ZERO=N-N:ONE=N/N:FOR I=ZERO TO N-ONE:FOR J=ONE TO N:IF ZERO=I MOD(ONE+ONE)THEN PRINT I*N+J;ELSE PRINT I*N+N-J+ONE;REM\rNEXT:PRINT:NEXT')
<_sre.SRE_Match object; span=(0, 141), match='INPUT N:ZERO=N-N:ONE=N/N:FOR I=ZERO TO N-ONE:FOR >

La principal dificultad es cómo insertar una palabra después de ;. Afortunadamente, QB64 trata la RC como una nueva línea, mientras que la expresión regular de Python no lo hace, por lo que podríamos deslizarnos REM\raquí. De los cinco sabores de expresiones regulares permitidos,

Así que esta grieta está bien siempre que no mencionemos JavaScript ... 🤐

kennytm
fuente
Aceptaré esto, ya que funciona en QB64. Sin embargo, también diré que el QBasic de archive.org (que creo que es el QBasic real en lugar de una emulación) se queja REMinmediatamente después de una declaración sin separador de declaraciones. Mi solución original no utilizó comentarios. Tengo otra variación que publicaré en breve. : D
DLosc
2

> <>, torcado

!v &0_!
_<>~ao1+>_v_
?______;__>:&:&=?;::2%:}+&:&*{3+0$.
?!v1+:n' 'o:&:&%_
?!v:n' 'o1-:&:&%_
Aaron
fuente
1

C, @Yimin Rong

main(int c,char**p){int n=atoi(*++p),i=n-n,t,o=c;for(--o;i<n;++i)for(t=o;t<=n;++t)printf("%-*d%c",n-o,i%c?i*n+n+o-t:i*n+t,t%n?' ':'\n');}

El programa no puede contener números, pero podemos obtener números a través de:

  1. c, comúnmente conocido como "argc", que siempre es 2.
  2. +y -están disponibles, por lo que podemos crear 0 con n-ny crear 1 con o=c;--o.
kennytm
fuente
Problema menor, la versión de policía estaba delimitada por tabuladores en lugar de estar justificada por el espacio, pero no era grande.
1

Ruby, @Value Ink

->n{(1..n).map{|r|x=(r*n-n+1..r*n).to_a;if(r.modulo(2)==1)then(x)else(x.reverse)end}}#1-2-3-4-5-6--

[(-=Z-~]* significa "Puedo escribir lo que quiera :)"

kennytm
fuente
Ah, lo arruiné, ¿verdad?
Value Ink
1

tinylisp, @DLosc

Una solución muy sencilla y totalmente optimizada :)

(d p(q((m n)(s m(s(s 1 1)n)))))(d j(q((f g)(i(l f g)(c f(j(p f 1) g))()))))(d r(q((f g)(i(l f g)(c(s g 1)(r f(s g 1)))()))))(d k(q((m o f g n)(i(l n g)()(c(m f(p f n))(k o m(p f n)(p g 1) n))))))(d f(q((n)(k j r 1 1 n))))

Llamar como (disp (f 4)).

  • (p m n)calcula m + n usando la resta s(m + n == m - ((1 - 1) - n))
  • (j f g) genera (f f+1 f+2 ... g-1)
  • (r f g) genera (g-1 g-2 g-3 ... f)
  • (k m o f g n)genera una fila de la matriz de serpiente y luego se repite para la siguiente fila, hasta que se creen n filas. Los argumentos m, oson sustituidos por j/ rpara generar aumento o disminución de filas. Los argumentos f, gestán ejecutando índices para saber en qué fila estamos.
  • (f n)llama (k j r 1 1 n)a comenzar la generación.
kennytm
fuente
Buen trabajo. (Por cierto, es más idiomático sólo para hacer (f 4)--el dispestá implícito.)
DLosc
1

PHP, @Ionut Botizan

Por el momento no tengo una mejor idea para descifrar la solución original.

Soporta n <= 15

Es la primera vez que uso getopt. Tal vez no sea la mejor idea para usar las opciones como entrada.

comenzar desde la línea de comando como esta

php hack.php -a=4

Regex original

Nivel 1:

^<[^'"\d{vV;<$]+$

Muy buena combinación de letras. Siéntase libre de votar el hilo de la policía.

Me bloquea funciones como - strrev - array_reverse - get_defined_vars

https://regex101.com/r/5rGTnw/2

Nivel 2:

^<[^'"\d{v;<$_~|&A-Z]+$

https://regex101.com/r/XtVl9G/1

Solución

 <?php
    error_reporting(~E_NOTICE)&
    define(A,a.chr(E_COMPILE_ERROR-E_NOTICE+E_WARNING))
    &define(B,getopt(A,[])[a])&print_r(array_chunk(
    array_slice(
    array_merge(
    range(E_ERROR,B)
    ,range(E_WARNING*B,E_ERROR+B)
    ,range(E_WARNING*B+E_ERROR,(E_WARNING+E_ERROR)*B)
    ,range(E_PARSE*B,+E_ERROR+(E_WARNING+E_ERROR)*B)
    ,range(E_PARSE*B+E_ERROR,(E_PARSE+E_ERROR)*B)
    ,range((E_PARSE+E_WARNING)*B,+E_ERROR+(E_PARSE+E_ERROR)*B)
    ,range((E_PARSE+E_WARNING)*B+E_ERROR,(E_NOTICE-E_ERROR)*B)
    ,range(E_NOTICE*B,+E_ERROR+(E_NOTICE-E_ERROR)*B)
    ,range(E_NOTICE*B+E_ERROR,(E_NOTICE+E_ERROR)*B)
    ,range((E_NOTICE+E_WARNING)*B,E_ERROR+(E_NOTICE+E_ERROR)*B)
    ,range((E_NOTICE+E_WARNING)*B+E_ERROR,(E_NOTICE+E_WARNING+E_ERROR)*B)
    ,range((E_NOTICE+E_PARSE)*B,E_ERROR+(E_NOTICE+E_WARNING+E_ERROR)*B)
    ,range((E_NOTICE+E_PARSE)*B+E_ERROR,(E_NOTICE+E_PARSE+E_ERROR)*B)
    ,range((E_CORE_ERROR-E_WARNING)*B,E_ERROR+(E_NOTICE+E_PARSE+E_ERROR)*B)
    ,range((E_CORE_ERROR-E_WARNING)*B+E_ERROR,(E_CORE_ERROR-E_ERROR)*B)
    )
    ,B-B,B*B
    ),B)
    )
    ?>

Nivel 2:

<?php
define(aa,a.chr(ord(strtoupper(a))-ord(h)+ord(a)))and
define(bb,getopt(aa,[])[a])and
define(us,chr(ord(a)-true-true))and
(prin.t.(us).r)(
(arra.y.(us).chunk)(
(arra.y.(us).slice)(
(arra.y.(us).merge)(
range((ord(b)-ord(a)),bb)
,range((ord(c)-ord(a))*bb,(ord(b)-ord(a))+bb)
,range((ord(c)-ord(a))*bb+(ord(b)-ord(a)),((ord(c)-ord(a))+(ord(b)-ord(a)))*bb)
,range((ord(e)-ord(a))*bb,+(ord(b)-ord(a))+((ord(c)-ord(a))+(ord(b)-ord(a)))*bb)
,range((ord(e)-ord(a))*bb+(ord(b)-ord(a)),((ord(e)-ord(a))+(ord(b)-ord(a)))*bb)
,range(((ord(e)-ord(a))+(ord(c)-ord(a)))*bb,+(ord(b)-ord(a))+((ord(e)-ord(a))+(ord(b)-ord(a)))*bb)
,range(((ord(e)-ord(a))+(ord(c)-ord(a)))*bb+(ord(b)-ord(a)),((ord(e)-ord(a))-(ord(b)-ord(a)))*bb)
,range((ord(e)-ord(a))*bb,+(ord(b)-ord(a))+((ord(e)-ord(a))-(ord(b)-ord(a)))*bb)
,range((ord(e)-ord(a))*bb+(ord(b)-ord(a)),((ord(e)-ord(a))+(ord(b)-ord(a)))*bb)
,range(((ord(e)-ord(a))+(ord(c)-ord(a)))*bb,(ord(b)-ord(a))+((ord(e)-ord(a))+(ord(b)-ord(a)))*bb)
,range(((ord(e)-ord(a))+(ord(c)-ord(a)))*bb+(ord(b)-ord(a)),((ord(e)-ord(a))+(ord(c)-ord(a))+(ord(b)-ord(a)))*bb)
,range(((ord(e)-ord(a))+(ord(e)-ord(a)))*bb,(ord(b)-ord(a))+((ord(e)-ord(a))+(ord(c)-ord(a))+(ord(b)-ord(a)))*bb)
,range(((ord(e)-ord(a))+(ord(e)-ord(a)))*bb+(ord(b)-ord(a)),((ord(e)-ord(a))+(ord(e)-ord(a))+(ord(b)-ord(a)))*bb)
,range(((ord(q)-ord(a))-(ord(c)-ord(a)))*bb,(ord(b)-ord(a))+((ord(e)-ord(a))+(ord(e)-ord(a))+(ord(b)-ord(a)))*bb)
,range(((ord(q)-ord(a))-(ord(c)-ord(a)))*bb+(ord(b)-ord(a)),((ord(q)-ord(a))-(ord(b)-ord(a)))*bb)
)
,bb-bb,bb*bb
),bb)
)
?>
Jörg Hülsermann
fuente