Ladrões: decifre o regex - faça uma cobra


20

Este é o fio do ladrão. A discussão do policial está aqui .


Uma matriz de cobra é uma matriz quadrada que segue esse padrão:

3 por 3:

1  2  3
6  5  4
7  8  9

e 4 por 4:

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

Sua tarefa é escrever um código que receba uma entrada ne crie essa matriz, no mesmo idioma que uma publicação policial e com um código que corresponda à expressão regular da polícia. O formato de saída do seu código deve corresponder ao formato de saída do código do policial.

Deixe um comentário na postagem do policial para indicar que você o violou.

Critério de vitória:

O vencedor será o usuário que obteve o maior número de envios. Em caso de empate, haverá vários vencedores.

Respostas:


10

Geléia , 9 bytes, quebra a resposta do @Dennis

²sµUFḤ$¦G

Experimente online!

Deve estar correto agora; Eu tive que repensar o que estava fazendo.

Explicação

A parte mais difícil desse problema é obter uma lista dos índices pares dentro do ¦(que aplica uma operação em índices específicos). Diferentemente da maioria das operações, que usam a entrada de todo o programa como padrão para o segundo operando, ¦usa o valor visto mais recentemente como padrão (porque conceitualmente possui dois operandos à esquerda, em vez de um operando à esquerda e à direita como a maioria das coisas que pegue dois valores).

No entanto, podemos observar que temos uma lista de números, incluindo todos os números inteiros de 1 a metade da entrada, já no valor atual no momento. Assim, o achatamento e a duplicação nos fornecem uma lista de números pares, incluindo todos os índices pares (também alguns outros números pares, mas não nos importamos com eles). É até possível gastar um µapenas para evitar uma ambiguidade de análise e ainda assim ter 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.         

Uh, a forma como ¦funciona mata-me o tempo todo, eu tentei isso ontem, mas com em vez de Ue decidiu o não estava funcionando.
Jonathan Allan

Bom, eu quase consegui, mas fiquei preso em selecionar todos os outros elementos também. Ffoi uma ótima idéia,
ETHproductions

Meu código original é praticamente idêntico a isso. Eu apenas usei em Jvez de F.
Dennis

@ Dennis Oh, J... eu tinha tentado com LR, mas não podia fazê-lo com menos de 11 bytes
ETHproductions

9

05AB1E, Emigna

Esta foi a minha primeira vez usando 05AB1E. Consegui com um pouco de ajuda. Foi divertido. :)

UXFXLNX*+N2BSR1k_iR}ˆ

Experimente online

Explicação:

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

Na verdade, eu encontrei esse programa semelhante sozinho, mas o formato de saída é diferente:

UXFXLNX*+N2BSR1k_iR}=

Experimente online

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

Veja o histórico de edições das minhas duas tentativas anteriores.


Bom trabalho! Muito semelhante à solução original.
Emigna

5
not bool(reversed(str(bin(N))).index('1'))... Eu acho que é a maneira mais absurda que eu já vi alguém fazer uma N%2operação.
Stewie Griffin

3
@StewieGriffin Quando a vida lhe dá limões, mas sem água ou açúcar, você apenas precisa comê-los crus. : D
mbomb007

6

Dennis Python 2

Este é um problema divertido de golfe com 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ção Regex


5

Ohm, Nick Clifford

Minha primeira vez tentando Ohm.
Linguagem realmente agradável que estou ansioso para usar novamente :)

²@┼σ▓_^è?R

Explicação

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

Minha primeira tentativa que não funcionou como adicionar uma matriz e um int não é possível:

@┼MDR┼+;W

Minha segunda tentativa que não corresponde ao regex:

²@┼σ▓_^MR

Você fez exatamente como eu fiz! Bom trabalho!
Nick Clifford

5

05AB1E, Emigna (2ª submissão)

Primeira vez em que trabalhei com 05AB1E.

VYLUYFYXDˆ+RU

Experimente online! | Verificação Regex

Explicação

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

Bom trabalho! Você tem a solução destina-se :)
Emigna

@Emigna thanks! Eu não teria conseguido se não fossem as outras soluções aqui (incluindo a sua) que me permitem perceber que a matriz global será impressa se a pilha estiver vazia! Se não fosse por isso, eu nunca teria descoberto; Eu continuava tentando fazer truques que terminavam )pensando que seria a única maneira de obter o resultado correto na pilha.
Value Ink

Sim, é bem impossível fazer isso )quando você pode usar apenas 2 caracteres não alfanuméricos. A parte complicada aqui foi estruturar o programa para usar apenas 2 curingas e tê-los em seqüência. Provavelmente teria sido um pouco mais difícil sem as outras soluções, mas deve ter havido alguma confusão envolvidos :)
Emigna

@ Emigna O que eu quero saber é se ^\w*..$é possível.
mbomb007

@ mbomb007: Acho que não. Com esta tática que você precisa para salvar o resultado da adição para a próxima iteração e você não pode usar a pilha para este significado que um dos UVnecessidade de vir depois . Também não consigo pensar em outra maneira de fazer isso com apenas 2 curingas no final. Isso pode ser feito com 3 curingas.
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 os feeds de linha são para fins cosméticos e podem ser removidos sem afetar o programa.

Experimente online!

Explicação

Depois que Lynn foi removido {|}da lista de caracteres permitidos, tive que tentar algo novo. Acontece que ainda podemos construir seqüências arbitrárias e avaliá-las como código.

Primeiro, precisamos agregar algum valor à pilha. Os únicos built-ins disponíveis que enviam algo sem aparecer primeiro (e sem ler a entrada) são es, eae et. Tenho certeza de que você pode começar de todas essas formas, mas fui com o esque pressiona o timestamp atual. Como não queria fazer suposições sobre seu valor real, testo sua primalidade com mp(o que dá 0e 1) e testo novamente a primalidade desse valor para garantir que eu esteja 0na pilha. Um 1será mais útil, então calculamos exp(0)com mee transformá-lo em um inteiro com i. Então, todos os números começam com:

esmpmpmei

Agora temos vários operadores de matemática unários para trabalhar:

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)

Também podemos combinar alguns recursos internos para funções mais 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.

Usando esses, podemos obter qualquer número 0 <= x < 128(e muitos outros) em menos de 10 etapas a partir de 1. Tenho certeza de que um subconjunto muito menor desses comandos também seria suficiente. Eu escrevi um pequeno programa Mathematica, para determinar todos esses trechos (não é muito legível, desculpe):

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]

Com isso, podemos simplesmente enviar uma lista arbitrária de códigos de caracteres, convertendo cada um deles em um caractere cposteriormente. Depois de empurrarmos todo o código que queremos executar, pressionamos 95( ]). Avaliamos aquele com ~que todos os outros devem ser agrupados em uma string e, em seguida, avaliamos essa string com ~.

O código real executado no final do programa é novamente:

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

Veja minha solução anterior para uma explicação.


4

Python 3, TuukkaX

Desculpe, o regex que você usou foi muito fácil de banalizar. Não 0, #ou ? Sem problemas!

Talvez eu tenha interpretado mal o exemplo de saída, mas ainda é muito fácil ajustar, já que tenho 45 caracteres sobrando

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"

Agradável! : D FYI: Vou criar outro em Python, se você estiver interessado em resolvê-lo;) Vai demorar um pouco mais, mas a beleza está na falta de crack.
Yytsi 9/03/19

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 testes:

> 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 confirmação de regex: https://regex101.com/r/OB8ZIM/1

Eu também tive:

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

que fornece a mesma saída e corresponde ao mesmo regex .


6
lets_make_a_snake... Eu ficaria surpreso se isso era a solução pretendida: P
Stewie Griffin

@plannapus Ótimo trabalho. O primeiro é basicamente o que eu pretendia usar ` for` e ` if`, mas muito melhor jogado do que o meu.
MickyT 9/0317

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 é uma função anônima que corresponde a esta regex PCRE: ^{(\|[^\/#\s]*){8}$.

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

Pré-especificado:

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
)

A primeira parte do subcomando irá gerar 1 2 3 4, 9 10 11 12e a segunda parte vai gerar8 7 6 5 , 16 15 14 13. O exterior sort -nirá misturá-los adequadamente para formar o padrão de cobra.

Usei o truque em /superuser//a/101760 para imprimir as linhas pares e ímpares. Obrigado Marcos, realmente divertido.


Very nice solução
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)

Analisando levemente a regex do policial, mostra um modelo fixo:

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

onde _é qualquer caractere, exceto [ '"#]e ^é um dos [int()2/].

O "*n)final mostra claramente um eval("..."*n)ou exec("..."*n)está acontecendo, portanto, precisamos apenas garantir que a "..."impressão seja a j-ésima linha.

O for i in range(j,está muito perto do final da string, sugerindo a compreensão da lista sem nenhum if. Então, precisamos construir o i-th coluna usando aqueles i%n, 2*ncoisas.

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)

Agradável! Bem, quase sobrevivi uma semana: D vou postar meu código original.
Yytsi 9/03/2017

3

dc , Mitchell Spector

Esta foi a minha primeira participação em um desafio de policiais e ladrões, e eu me diverti muito. O regex precisava ser correspondido era simples, o ^[^# !]{59}$que basicamente transformou meu trabalho em golfe, sem usar esses três caracteres. Inicialmente, tive dificuldades em obter menos de 60 bytes, mas no fim eu o decifrei.

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

Experimente online!

Explicação:

Meu código usa um loop com N 2 iterações , mantendo um contador baseado em zero (1D) e calcula qual número precisa ser impresso com base nas coordenadas correspondentes da linha e da coluna da matriz (r, c).

Exemplo do que quero dizer, 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

Parece complicado, mas a etapa intermediária é útil. Além disso, tentei usar 2 loops desde o início, mas acabei acima do limite de caracteres de expressão regular. Geração de número em cada iteração (com base em zero):

  • se r % 2 = 0(linha normal),n = (r * N) + c = counter
  • se r % 2 = 1(linha invertida),n = ((r + 1) * N) - c - 1 = counter + N - (2 * c) - 1

Ou tudo de uma vez, como uma numeração baseada: 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 Aqui está a minha explicação. Como você vê, nós dois temos literalmente o mesmo algoritmo, apenas eu uso o comando ~para calcular os índices de linha e coluna de uma só vez. Mas uma das minhas tentativas anteriores as calculou separadamente, como você fez. Mentes brilhantes pensam igual? :)
seshoumara

1
Sim, é realmente o mesmo algoritmo. Eu gosto do seu uso ~para encurtar o código.
Mitchell Spector

Eu acho que você pode reduzi-lo por um byte se você usar o truque da raiz quadrada no teste de loop no final da macro: ?sN0[AP]sP[ddlN~_2*lN+1-r2%*+1+n32P1+dlN%0=PdvlN>L]dsLx tio.run/nexus/...
Mitchell Spector

@MitchellSpector Você está certo, e eu notei isso ao ler sua explicação, mas comentei na sala de bate - papo .
seshoumara

Sim, eu vejo isso agora - eu não tinha olhado para a sala de chat ainda esta manhã.
Mitchell Spector

3

PowerShell, ConnorLSW

Rachadura

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

Comecei com uma solução menor para o problema e preenchi meus nomes de variáveis ​​para fazer com que o regex correspondesse. Tentando encontrar um uso para o cólon, suponho que foi a parte mais difícil de entender.

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

Explicação

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

Bom, eu usei uma $scriptvariável e alguns loops muito bagunçados para preenchê-lo, o [array]::Reverse()estava correto, parabéns - acho que você pode querer equilibrar o comprimento $ie o tamanho $MySnakeIndex.
colsw

@ConnorLSW Eu sei que você não seria capaz de dormir à noite sabendo que eu tinha erros no meu assaltante. Eu consertei isso.
Matt

3

CJam, Lynn

Algo assim:

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 o espaço em branco é para ... "legibilidade" ... e pode ser omitido para estar em conformidade com a regex de Lynn.

Experimente online!

Explicação

A regex exige que resolvamos o problema usando apenas:

  • Letras minúsculas.
  • {}, que pode ser usado para criar blocos.
  • |, usado principalmente para OR bit a bit.
  • ~, "eval" e bit a bit NOT (também "dump array", mas não vou usá-lo).

Como temos ~, se podemos construir seqüências arbitrárias, podemos executar código arbitrário. No entanto, a princípio não é óbvio como fazer isso.

A primeira peça do quebra-cabeça é que os blocos são pedaços de código não avaliados, que podem se transformar em strings s. Então {abc}snos dá "{abc}". Em seguida, podemos usar eupara converter essas strings em maiúsculas.

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

O benefício disso é que as letras maiúsculas são variáveis ​​pré-inicializadas, para que possamos obter muitos valores constantes criando uma string e avaliando-a duas vezes (uma vez para transformar a string novamente em um bloco e outra para executar esse bloco). Não podemos obter todas as letras, porque algumas, como xcomandos não são válidos (o CJam se recusará a analisar um bloco que as contenha). Não podemos usarf como estão, porque ele precisa ser seguido por outro comando, mas podemos usar fbe depois OU os dois valores juntos. Da mesma forma, podemos usar em eevez de e. Com isso, podemos obter os números 0, -1, 3, e 10para 19. O -1é conveniente, porque se o transformarmos em uma string ( "-1"), em um caractere ('-) e, em seguida, avaliá-lo, podemos obter subtração ou definir diferença. Como eu disse, não podemos obter X(por 1), mas podemos assumir o valor absoluto de -1with z.

Também podemos usar spara obter uma string contendo um espaço e ctransformá-la em um caractere de espaço :

{s}seu~~c

Isso é conveniente, pois a partir daí podemos obter muitos comandos úteis no intervalo ASCII mais baixo, ORing o espaço com vários números. Para obter alguns dos caracteres acima do ponto de código 48, usamos o caractere '0como base:

{t}seu~~si

Isso já é suficiente para construir cadeias arbitrárias, porque podemos obter '+(adição e concatenação de cadeias) do seguinte trecho:

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

E nós temos um literal 1para podermos simplesmente empurrar caracteres de espaço, incrementá-los para o valor que precisamos e concatená-los todos juntos, mas isso é um pouco chato e o código se tornaria maciço.

Em vez disso, eu criei [e] e evalled-los, de modo que todos os personagens que eu empurro entre são embrulhados em uma corda automaticamente. Essas são as duas linhas:

{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, finalmente, precisaremos fe ~na string que estamos gerando. Embora esses caracteres já sejam válidos, não temos literais de seqüência de caracteres ou literais de caracteres, portanto, teríamos que gerá-los também, e construir pontos de código maiores a partir do espaço é um pouco chato. Em vez disso, usei a subtração definida aqui, mas subtraindo dois blocos (para se livrar da{} ):

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

Isso é praticamente tudo o que existe. Nós avaliamos [. Empurramos todos os caracteres, obtidos por vários cálculos das poucas constantes internas que temos |,,- (via eval) e +(via eval). Nós avaliamos ]. Achatamos a coisa toda em uma string, porque em algum momento adicionei algumas strings ou números à lista. Avaliamos nossa string arbitrária com ~.

Eles ri...pfazem parte do programa final real, mas eu os extraí porque eles não precisam de codificação.

Finalmente, este é o programa que estamos executando:

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

Experimente online!

Isso define uma função fque retorna a resposta. Ele também imprime os nomes das funções que defini para stdout, mas presumo que isso não importe, pois [podemos escolher nosso fluxo de saída] para o código golf, pelo menos. Se for um grande negócio, acho que posso ajustá-lo para não imprimi-los. Como eu fiz isso? Comecei com algo bastante padrão:

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

Então, observei que é possível transformar definições de funções como esta:

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

torna-se

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

E chamadas de função assim:

(a x y)

torna-se

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

Usei essa macro recursiva do Vim, armazenada em registrador q, para fazer a segunda (eu jkmapeei <Esc>):f s(v(h(q(jkea))))jk@q .

Essas duas transformações foram suficientes para eliminar todos os espaços.


Bem feito! Meu código original é bastante semelhante, embora eu tenha escrito uma macro auxiliar para torná-lo um pouco menos doloroso de escrever. Estou curioso para saber como evitar a impressão dos símbolos definidos - se você quiser compartilhá-los, estarei na sala de bate-papo tinylisp .
DLosc 16/03/19

@ DLosc Feito, eu postei 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ção: https://regex101.com/r/7ukrM0/1


Recebo "Expressão resolve para uma função não utilizada" com isso por conta própria, mas não estou familiarizado com tudo que faz uma resposta aceitável. É o exemplo `let a = <code>; a (CShort (4)); necessário para fazê-lo funcionar não é necessário?
James Webster

@ JamesWebster Não tenho certeza das regras exatas, pois "um código" é bastante ambíguo. Para o código-golfe, a submissão pode ser um programa ou função , então apenas forneço uma função anônima aqui. De que outra forma recebemos os argumentos de entrada?
kennytm

Meu original era o corpo de uma função, então não tenho certeza se o meu também é válido! Então, eu vou com "Claro, isso está bom" e vou votar. :)
James Webster

@ JamesWebster Você pode chamar a coisa toda como (…)(4), não há necessidade de converter o literal inteiro no CShort.
Kennytm 9/03

Ah sim! Eu nunca teria pensado nisso.
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 é muito longo (portanto, a cobra), e a falta de espaço em branco pode ser facilmente contornada.

Pré-especificado:

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

Variante agradável. Minha culpa não era de pensar em uma função e fazer apenas uma saída
Jörg Hülsermann

2

Jelly, comprimento 12, @JonathanAllan

Ḷ-*m@"s@²$G

Experimente online!

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

2

Jelly , 12 bytes, rachaduras Segunda resposta de JonathanAllan

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

Experimente online!

Explicação

Isso é quase o mesmo que minha outra resposta . Acabei de fazer duas alterações:

Primeiro, mudei U("reverter cada elemento") para Ṛ€("reverter" "cada elemento"). Isso não ajuda por si só, porque também é proibido.

Em seguida, mudei o ("reverse") para ;@/( /"fold by" ;"concatenating" @"na ordem oposta à lista original"). Isso evita todos os caracteres proibidos, fornecendo uma solução válida.

Suponho que o próximo passo seria começar a banir as rápidas de manipulação de array , além dos átomos.


Uh, eu sabia que deveria ter proibido ...
Jonathan Allan

Você pode escrever em termos de /também. É apenas mais detalhado do que esta solução.

Sim e se poderia ;@\ṫ0, o regex está ficando longo.
Jonathan Allan

2

Jelly, comprimento 13, @JonathanAllan

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

Experimente online!

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

Oh espera, o que, eu perdi 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)
}

Não tocamos em Scala por um tempo, foi divertido revisitar. Infelizmente, esta solução perde muitos dos recursos interessantes do Scala.

Experimente aqui

Confirmação de Regex


2

QBasic (QB64), @DLosc

Observe que, como .não corresponde \n(U + 000A, LF), a nova linha aqui é \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 >

A principal dificuldade é como inserir uma palavra após o ;. Felizmente, o QB64 trata o CR como uma nova linha, enquanto o regex do Python não, para que possamos escorregar umREM\r aqui. Dos cinco sabores permitidos de regex,

Portanto, esse crack é bom, desde que não mencionemos JavaScript ... 🤐


Aceito isso, pois funciona em QB64. No entanto, também direi que o QBasic do archive.org (que eu acho que é o QBasic real, e não uma emulação) reclama REMimediatamente após uma declaração sem separador de declarações. Minha solução original não usou comentários. Tenho outra variação que estarei postando em breve. : D
DLosc 11/03/19


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

O programa não pode conter números, mas podemos obter números via:

  1. c, comumente conhecido como "argc", que é sempre 2.
  2. +e -estão disponíveis, para que possamos criar 0 com n-ne criar 1 com o=c;--o.

Problema menor: a versão policial era delimitada por tabulação, em vez de justificada por espaço, mas sem grandes problemas.

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 "Eu posso escrever o que quiser :)"


Ah, eu estraguei tudo isso, não eu
Value Ink

1

tinylisp, @DLosc

Uma solução muito simples e totalmente não otimizada :)

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

Ligar como (disp (f 4)).

  • (p m n)calcula m + n usando subtração s(m + n == m - ((1 - 1) - n))
  • (j f g) gera (f f+1 f+2 ... g-1)
  • (r f g) gera (g-1 g-2 g-3 ... f)
  • (k m o f g n)gere uma linha da matriz de cobra e, em seguida, recurve-se para a próxima linha, até que n linhas sejam criadas. Os argumentos m, osão substituídos por j/ rpara gerar aumentando ou diminuindo linhas. Os argumentos f, gestão em execução índices para saber qual linha em que estamos.
  • (f n)chamadas (k j r 1 1 n)para iniciar a geração.

Bom trabalho. (Aliás, é mais idiomática apenas para fazer (f 4)--o dispestá implícita.)
DLosc

1

PHP, @Ionut Botizan

No momento, não tenho nenhuma idéia melhor para quebrar a solução original.

Suporta n <= 15

É a primeira vez que uso getopt. Talvez não seja a melhor ideia para usar opções como entrada.

comece na linha de comando como esta

php hack.php -a=4

Regex original

Nível 1:

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

Muito boa combinação de letras. Sinta-se livre para votar no tópico da polícia.

Ele me bloqueia funções como - strrev - array_reverse - get_defined_vars

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

Nível 2:

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

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

Solução

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

Nível 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)
)
?>
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.