Ladri: rompi la regex - Crea un serpente


20

Questo è il filo del ladro. Il thread del poliziotto è qui .


Una matrice di serpenti è una matrice quadrata che segue questo schema:

3-by-3:

1  2  3
6  5  4
7  8  9

e 4 per 4:

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

Il tuo compito è quello di scrivere un codice che accetta un input ne crea tale matrice, nella stessa lingua di un post di poliziotto e con un codice che corrisponda alla regex del poliziotto. Il formato di output del tuo codice deve corrispondere al formato di output del codice del poliziotto.

Si prega di lasciare un commento sotto il post del poliziotto per indicare che è stato risolto.

Criterio vincente:

Il vincitore sarà l'utente che ha superato il maggior numero di richieste. In caso di pareggio, ci saranno più vincitori.

Risposte:


10

Jelly , 9 byte, crea la risposta di @ennis

²sµUFḤ$¦G

Provalo online!

Dovrebbe essere corretto ora; Ho dovuto piuttosto ripensare a quello che stavo facendo.

Spiegazione

La parte più difficile di questo problema è ottenere un elenco degli indici pari all'interno ¦(che applica un'operazione a indici specifici). A differenza della maggior parte delle operazioni, che utilizzano l'input per l'intero programma come predefinito per il secondo operando,¦ utilizza il valore visto più di recente come predefinito (perché concettualmente ha due operandi di sinistra, anziché un operando di sinistra e di destra come la maggior parte delle cose che prendere due valori).

Tuttavia, possiamo osservare che abbiamo un elenco di numeri, inclusi tutti i numeri interi compresi tra 1 e metà dell'input, già nel valore corrente al momento. In quanto tale, l'appiattimento e il raddoppio ci dà un elenco di numeri pari, compresi tutti gli indici pari (anche alcuni altri numeri pari, ma non ci interessa). È anche possibile spenderne uno µsolo per evitare un'ambiguità di analisi e arrivare comunque entro 9 caratteri.

²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.         

Uh, il modo in cui ¦funziona mi uccide ogni volta, l'ho provato ieri ma con piuttosto che Udeciso che non funzionava.
Jonathan Allan,

Bene, ce l'ho quasi fatta, ma mi sono bloccato a selezionare anche tutti gli altri elementi. Fè stata una grande idea,
ETHproductions

Il mio codice originale è praticamente identico a questo. Ho appena usato Jinvece di F.
Dennis

@Dennis Oh, J... ci avevo provato LRma non riuscivo a ottenere meno di 11 byte
ETHproductions

9

05AB1E, Emigna

Questa è stata la prima volta che ho usato 05AB1E. L'ho preso con un po 'di aiuto. È stato divertente. :)

UXFXLNX*+N2BSR1k_iR}ˆ

Provalo online

Spiegazione:

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

In realtà ho trovato questo programma simile da solo, ma il formato di output è diverso:

UXFXLNX*+N2BSR1k_iR}=

Provalo online

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

Vedi la cronologia delle modifiche per i miei due precedenti tentativi.


Bel lavoro! Abbastanza simile alla soluzione originale.
Emigna

5
not bool(reversed(str(bin(N))).index('1'))... Penso che sia il modo più assurdo in cui ho visto qualcuno fare N%2un'operazione.
Stewie Griffin

3
@StewieGriffin Quando la vita ti dà limoni ma senza acqua o zucchero, devi solo mangiarli crudi. : D
mbomb007

6

Python 2, Dennis

Questo è un divertente problema con il golf token.

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],

Verifica Regex


5

Oh, Nick Clifford

La mia prima volta che provo Ohm.
Linguaggio davvero carino che non vedo l'ora di usare di nuovo :)

²@┼σ▓_^è?R

Spiegazione

²             # 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

Il mio primo tentativo che non ha funzionato come l'aggiunta di un array e un int non è possibile:

@┼MDR┼+;W

Il mio secondo tentativo che non corrisponde alla regex:

²@┼σ▓_^MR

L'hai fatto esattamente come ho fatto io! Ottimo lavoro!
Nick Clifford

5

05AB1E, Emigna (seconda presentazione)

Prima volta che lavoro con 05AB1E.

VYLUYFYXDˆ+RU

Provalo online! | Verifica Regex

Spiegazione

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

Bel lavoro! Hai ottenuto la soluzione voluta :)
Emigna del

@Emigna grazie! Non l'avrei ottenuto se non fosse stato per le altre soluzioni qui (le tue incluse) che mi fanno capire che l'array globale stamperà se lo stack è vuoto! Se non fosse stato per questo non lo avrei mai capito; Ho continuato a provare a fare trucchi che finivano col )pensare che sarebbe stato l'unico modo per ottenere il risultato corretto in pila.
Value Ink

Sì, è abbastanza impossibile farlo )quando puoi usare solo 2 caratteri non alfanumerici. La parte difficile qui doveva strutturare il programma in modo da usare solo 2 caratteri jolly e averli sequenziali. Probabilmente sarebbe stato un po 'più difficile senza le altre soluzioni, ma avrebbero dovuto esserci alcuni
enigmi

@Emigna Quello che voglio sapere è se ^\w*..$è possibile.
mbomb007,

@ mbomb007: non la penso così. Con questa tattica avresti bisogno di salvare il risultato dell'aggiunta per la prossima iterazione e non puoi usare lo stack per questo significato che uno UVdeve venire dopo . Non riesco nemmeno a pensare ad un altro modo di farlo con solo 2 caratteri jolly alla fine. Tuttavia, può essere fatto con 3 caratteri jolly.
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
~~

Tutti gli avanzamenti di riga sono a scopo cosmetico e possono essere rimossi senza influire sul programma.

Provalo online!

Spiegazione

Dopo la rimozione di Lynn {|} dall'elenco dei personaggi consentiti, ho dovuto provare qualcosa di nuovo. Si scopre che possiamo ancora costruire stringhe arbitrarie e valutarle come codice.

Innanzitutto, dobbiamo ottenere un certo valore nello stack. Gli unici built-in disponibili che spingono qualcosa senza far apparire prima qualcos'altro (e senza leggere l'input) sono es, eae et. Sono sicuro che potresti iniziare da tutto questo in un modo o nell'altro, ma sono andato con ciò esche spinge l'attuale timestamp. Dal momento che non volevo fare ipotesi sul suo valore reale, collaudo la sua primalità con mp(che dà 0e 1) e testerò nuovamente la primalità di quel valore per assicurarmi di averne uno 0in pila. Una 1sarà più utile, quindi si calcola exp(0)con mee di trasformarlo in un intero con i. Quindi tutti i numeri iniziano con:

esmpmpmei

Ora abbiamo un sacco di operatori di matematica unari con cui lavorare:

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)

Possiamo anche combinare alcuni built-in per funzioni più elaborate di 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.

Usando questi, possiamo ottenere qualsiasi numero in 0 <= x < 128(e molti altri) in meno di 10 passaggi da 1. Sono sicuro che basterebbe anche un sottoinsieme molto più piccolo di questi comandi. Ho scritto un piccolo programma Mathematica, per determinare tutti questi frammenti (non è molto leggibile, scusa):

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 ciò, possiamo semplicemente spingere un elenco arbitrario di codici di caratteri, convertendoli successivamente in un carattere c. Una volta che abbiamo inviato l'intero codice che vogliamo eseguire, spingiamo 95( ]). Valutiamo quello con cui ~avvolgere tutti gli altri in una stringa e quindi valutiamo quella stringa ~.

Il codice effettivo eseguito alla fine del programma è di nuovo:

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

Vedi la mia soluzione precedente per una spiegazione.


4

Python 3, TuukkaX

Spiacente, la regex che hai usato era troppo facile da banalizzare. No 0, #o ? Nessun problema!

Potrei aver frainteso l'output di esempio, ma è ancora abbastanza facile da modificare poiché mi rimangono 45 caratteri di riserva

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"

Bello! : D FYI: Ne creerò un altro in Python, se sei interessato a risolverlo;) Sarà un po 'più lungo, ma la bellezza sta nell'irregolarità.
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"))

Casi di test:

> 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 

E conferma regex: https://regex101.com/r/OB8ZIM/1

Ho anche avuto:

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

che fornisce lo stesso output e corrisponde allo stesso regex .


6
lets_make_a_snake... Sarei sorpreso se questa fosse la soluzione prevista: P
Stewie Griffin

@plannapus Ottimo lavoro. Il primo è fondamentalmente quello che intendevo usare ` for` e ` if`, ma molto meglio del mio.
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="||||||"}

Questa è una funzione anonima che corrisponde a questo PCRE regex: ^{(\|[^\/#\s]*){8}$.

Provalo online!


4

Bash, @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 prima parte del sottocomando genererà 1 2 3 4, 9 10 11 12e la seconda parte genererà 8 7 6 5,16 15 14 13 . L'esterno sort -nli mescolerà correttamente insieme per formare il modello di serpente.

Ho usato il trucco in /superuser//a/101760 per stampare le linee pari e dispari. Grazie Marcos, davvero divertente.


Soluzione molto bella
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))


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)

Analizzando leggermente la regex del poliziotto mostra un modello fisso:

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

dove _è qualsiasi personaggio tranne [ '"#]ed ^è uno di[int()2/] .

Alla "*n)fine mostra chiaramente un eval("..."*n)o exec("..."*n)sta succedendo, quindi dobbiamo solo assicurarci che le "..."stampe siano nella j-esima riga.

Il for i in range(j,è troppo vicino alla fine della stringa, accennando di lista senza alcuna if. Quindi abbiamo bisogno di costruire la i-esima colonna utilizzando quelli i%n, 2*nroba.

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)

Bello! Bene, quasi sopravvissuto una settimana: D posterò il mio codice originale.
Yytsi

3

dc , Mitchell Spector

Questa è stata la mia prima partecipazione a una sfida di poliziotti e ladri e mi sono divertito molto. Il regex doveva essere abbinato era semplice, il ^[^# !]{59}$che sostanzialmente trasformava il mio lavoro in golf, senza usare quei 3 personaggi. Inizialmente ho avuto difficoltà a scendere sotto i 60 byte, ma alla fine l'ho risolto.

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

Provalo online!

Spiegazione:

Il mio codice usa un loop con N 2 iterazioni, mantenendo un contatore a base zero (1D) e calcola quale numero deve essere stampato in base alle corrispondenti coordinate di riga matrice e colonna (r, c).

Esempio di cosa intendo, se 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

Sembra complicato, ma il passaggio intermedio è utile. Inoltre, ho provato a usare 2 loop dall'inizio, ma sono finito sopra il limite del carattere regex. Generazione di numeri ad ogni iterazione (base zero):

  • Se r % 2 = 0 (riga normale),n = (r * N) + c = counter
  • if r % 2 = 1(riga rovesciata),n = ((r + 1) * N) - c - 1 = counter + N - (2 * c) - 1

O tutto in una volta, come una numerazione basata su: 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.

@MitchellSpector Ecco la mia spiegazione. Come vedi, entrambi abbiamo letteralmente lo stesso algoritmo, solo io uso il comando ~per calcolare gli indici di riga e colonna in una volta sola. Ma uno dei miei precedenti tentativi li ha calcolati separatamente come hai fatto tu. Grandi menti pensano allo stesso modo? :)
seshoumara,

1
Sì, è davvero lo stesso algoritmo. Mi piace il tuo uso ~per abbreviare il codice.
Mitchell Spector

Penso che puoi accorciarlo di un byte se usi il trucco della radice quadrata nel test del loop alla fine della macro: ?sN0[AP]sP[ddlN~_2*lN+1-r2%*+1+n32P1+dlN%0=PdvlN>L]dsLx tio.run/nexus/…
Mitchell Spector

@MitchellSpector Hai ragione, e l'ho notato mentre leggevo la tua spiegazione, ma ho commentato nella chat room invece .
seshoumara,

Sì, lo vedo ora - non avevo ancora guardato la chatroom questa mattina.
Mitchell Spector

3

PowerShell, ConnorLSW

Crepa

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

Ho iniziato con una soluzione più piccola al problema e ho riempito i nomi delle mie variabili per far corrispondere il regex. Cercare di trovare un uso per il colon suppongo sia stata la parte più difficile da avvolgere la testa.

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

Spiegazione

# 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" "

Bene, ho usato una $scriptvariabile e alcuni loop davvero disordinati per completarlo, il fatto [array]::Reverse()era corretto, complimenti - penso che potresti voler uniformare la lunghezza $ie il pensiero $MySnakeIndex.
Colsw,

@ConnorLSW So che non saresti in grado di dormire la notte sapendo che ho avuto errori nel mio ladro. L'ho risolto.
Matt

3

CJam, Lynn

Qualcosa come questo:

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

Tutto lo spazio bianco è per ... "leggibilità" ... e può essere omesso per rispettare la regex di Lynn.

Provalo online!

Spiegazione

Il regex richiede che risolviamo il problema usando solo:

  • Lettere minuscole.
  • {}, che può essere utilizzato per creare blocchi.
  • |, utilizzato principalmente per OR bit a bit.
  • ~, "eval" e bit a bit NOT (anche "dump array", ma non lo userò).

Dal momento che abbiamo, ~ se possiamo costruire stringhe arbitrarie, possiamo eseguire codice arbitrario. Tuttavia, all'inizio non è ovvio come farlo.

Il primo pezzo del puzzle è che i blocchi sono frammenti di codice non valutati, che possono trasformarsi in stringhe con s. Quindi {abc}sci dà "{abc}". Successivamente, possiamo usare euper convertire queste stringhe in maiuscolo.

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

Il vantaggio di questo è che le lettere maiuscole sono variabili preinizializzate, quindi possiamo ottenere molti valori costanti creando una tale stringa e valutandola due volte (una volta per trasformare la stringa in un blocco e una volta per eseguire quel blocco). Non possiamo ottenere tutte le lettere, perché alcune, come xnon sono comandi validi (quindi CJam rifiuterà di analizzare un blocco che le contiene). Non possiamo usare così fcom'è, perché deve essere seguito da un altro comando, ma possiamo usare fbe quindi OR i due valori insieme. Allo stesso modo, possiamo usare eeinvece di e. Con questo, siamo in grado di ottenere i numeri 0, -1, 3, e 10a 19. Il-1 è conveniente, perché se trasformarlo in una stringa ( "-1") poi in un carattere ('-) e quindi valutarlo, possiamo ottenere la sottrazione o impostare la differenza. Come ho detto, non possiamo ottenere X(per .1), ma possiamo prendere il valore assoluto di -1withz

Possiamo anche usare sper ottenere una stringa contenente uno spazio e usare cper trasformarla in un carattere spazio :

{s}seu~~c

Questo è conveniente, perché da lì possiamo ottenere molti comandi utili nell'intervallo ASCII inferiore ORingando lo spazio con vari numeri. Per ottenere alcuni dei caratteri sopra il punto di codice 48, utilizziamo invece il carattere '0come base:

{t}seu~~si

Questo è già abbastanza per costruire stringhe arbitrarie, perché possiamo ottenere '+(addizione e concatenazione di stringhe) dal seguente frammento:

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

E abbiamo un letterale 1 quindi possiamo semplicemente spingere i caratteri dello spazio, incrementarli al valore di cui abbiamo bisogno e poi concatenarli tutti insieme, ma è un po 'noioso e il codice diventerebbe enorme.

Invece, li ho generati [e ]li ho evitati, in modo che tutti i personaggi tra cui inserisco siano automaticamente avvolti in una stringa. Ecco queste due linee:

{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~

E infine, avremo bisogno fe ~nella stringa che stiamo generando. Mentre quelli sono già caratteri validi, non abbiamo letterali stringa o letterali di caratteri, quindi dovremmo generare anche questi e costruire punti di codice più grandi dallo spazio è un po 'fastidioso. Invece, ho fatto uso della sottrazione impostata qui, ma sottraendo due blocchi (per sbarazzarmi di {}):

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

È praticamente tutto quello che c'è da fare. Noi valutiamo [. Spingiamo tutti i personaggi, ottenuti da vari calcoli dalle poche costanti incorporate che abbiamo |, -(via eval) e +(via eval). Noi valutiamo] . Abbiamo appiattito il tutto in una stringa, perché a un certo punto ho aggiunto alcune stringhe o numeri all'elenco. Valutiamo la nostra stringa arbitraria con~ .

Il ri...p fanno parte del programma finale vero e proprio, ma li ho estratti perché non hanno bisogno di codifica.

Infine, questo è il programma che stiamo effettivamente eseguendo:

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.

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)))))))))))

Provalo online!

Questo definisce una funzione fche restituisce la risposta. Stampa anche i nomi delle funzioni che ho definito su stdout, ma suppongo che non contino, dal momento che [ci è consentito scegliere il nostro flusso di output] per il codice golf, almeno. Se è un grosso problema, penso di poterlo modificare per non stamparli. Come l'ho fatto? Ho iniziato con qualcosa di abbastanza standard:

(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))))))

Quindi, ho osservato che si possono trasformare le definizioni delle funzioni in questo modo:

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

diventa

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

E la funzione chiama in questo modo:

(a x y)

diventa

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

Ho usato questa macro Vim ricorsiva, memorizzata nel registro q, per fare la seconda (ho jkmappato a <Esc>):f s(v(h(q(jkea))))jk@q .

Queste due trasformazioni sono state sufficienti per eliminare tutti gli spazi.


Ben fatto! Il mio codice originale è abbastanza simile, anche se ho scritto una macro di supporto per renderla un po 'meno dolorosa da scrivere. Sono curioso di sapere cosa pensi di come evitare di stampare i simboli definiti: se ti interessa condividerli, sarò nella chat room tinylisp .
DLosc

@DLosc Fatto, l'ho pubblicato lì.
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)->()

Verifica: https://regex101.com/r/7ukrM0/1


Ottengo "L'espressione si risolve in una funzione non utilizzata" con questa da sola, ma non ho familiarità con tutto ciò che rende una risposta accettabile. È ad esempio `let a = <code>; un (CShort (4)); richiesto per farlo funzionare non necessario?
James Webster,

@JamesWebster Non sono sicuro delle regole esatte poiché "un codice" è piuttosto ambiguo. Per code-golf l'invio può essere un programma o una funzione , quindi fornisco solo una funzione anonima qui. In quale altro modo riceviamo gli argomenti di input?
kennytm,

Il mio originale era il corpo di una funzione, quindi non sono sicuro che il mio sia valido! Quindi andrò con "Certo, va bene" e lo voterò. :)
James Webster

@JamesWebster Puoi chiamare tutto come (…)(4), senza bisogno di lanciare il numero intero letterale in CShort.
kennytm

Ah sì! Non ci avrei mai pensato.
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 byte è troppo lungo (quindi il serpente) e la mancanza di spazi bianchi può essere facilmente risolta.

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~')
?>

Bella variante. La mia colpa non è stata quella di pensare a una funzione e fare solo un'uscita
Jörg Hülsermann

2

Jelly, lunghezza 12, @JonathanAllan

Ḷ-*m@"s@²$G

Provalo online!

Come funziona

Ḷ-*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.

2

Jelly , 12 byte, crepa nella seconda risposta di JonathanAllan

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

Provalo online!

Spiegazione

Questa è quasi la stessa della mia altra risposta . Ho appena apportato due modifiche:

Innanzitutto, ho cambiato U("inverti ogni elemento") in Ṛ€("inverti" "ogni elemento"). Questo non aiuta da solo, perché è anche vietato.

Quindi, ho cambiato il ("reverse") in ;@/( /"fold by" ;"concatenando" @"nell'ordine opposto alla lista originale"). Ciò evita tutti i personaggi vietati, dando una soluzione valida.

Suppongo che il prossimo passo sarebbe iniziare a vietare le manipolazioni di array veloci , oltre agli atomi.


Uh, sapevo che avrei dovuto bandire ...
Jonathan Allan il

Puoi anche scrivere in termini di /. È solo più dettagliato di questa soluzione.

Sì e uno potrebbe ;@\ṫ0, la regex sta diventando lunga.
Jonathan Allan,

2

Jelly, lunghezza 13, @JonathanAllan

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

Provalo online!

Come funziona

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.

Oh aspetta, cosa, mi sono perso m?!
Jonathan Allan


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)
}

Non ho toccato la Scala per un po ', è stato divertente rivisitare. Sfortunatamente, questa soluzione perde molte delle fantastiche funzioni di Scala.

Provalo qui

Conferma Regex


2

QBasic (QB64), @DLosc

Si noti che poiché .non corrisponde \n(U + 000A, LF), la nuova riga qui è 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

Verificare:

>>> 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 difficoltà principale è come inserire una parola dopo il ;. Per fortuna, QB64 tratta CR come una nuova riga, mentre il regex di Python no, quindi potremmo sfuggire REM\rqui. Dei cinque sapori regex consentiti,

Quindi questa crepa va bene fintanto che non menzioniamo JavaScript ... 🤐


Accetterò questo, dal momento che funziona in QB64. Tuttavia, dirò anche che il QBasic di Archive.org (che penso sia il vero QBasic piuttosto che un'emulazione) si lamenta REMimmediatamente dopo una dichiarazione senza separatore di dichiarazioni. La mia soluzione originale non utilizzava commenti. Ho un'altra variante che pubblicherò a breve. : D
DLosc


2

> <>, torcado

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

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');}

Il programma non può contenere numeri, ma possiamo ottenere numeri tramite:

  1. c, commonly known as "argc", which is always 2.
  2. + and - are available, so we can create 0 with n-n, and create 1 with o=c;--o.

Minor issue, cop version was tab-delimited as opposed to space-justified, but no biggy.

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-~]* means "I can write anything I like :)"


Ah, I messed that up didn't I
Value Ink

1

tinylisp, @DLosc

A very straightforward solution, and totally unoptimized :)

(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))))

Call as (disp (f 4)).

  • (p m n) computes m + n using subtraction s (m + n == m - ((1 - 1) - n))
  • (j f g) generates (f f+1 f+2 ... g-1)
  • (r f g) generates (g-1 g-2 g-3 ... f)
  • (k m o f g n) generate one row of the snake matrix, and then recurve itself for the next row, until n rows are created. The arguments m, o are substituted by j/r to generate increasing or decreasing rows. The arguments f, g are running indices to know which row we are on.
  • (f n) calls (k j r 1 1 n) to start the generation.

Good work. (BTW, it's more idiomatic just to do (f 4)--the disp is implied.)
DLosc

1

PHP, @Ionut Botizan

In the moment I have no better idea to crack the original solution.

Supports n<=15

It is the first time that I use getopt. Maybe not the best idea to use options as input.

start from the command line like this

php hack.php -a=4

Original Regex

Level 1:

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

Very nice combination of letters. Feel free to vote up the cops thread.

It blocks me functions like - strrev - array_reverse - get_defined_vars

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

Level 2:

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

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

Solution

 <?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)
    )
    ?>

Level 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)
)
?>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.