22
\$\begingroup\$

This is the robber's thread. The cop's thread is here.


A snake matrix is a square matrix that follows this pattern:

3-by-3:

1  2  3
6  5  4
7  8  9

and 4-by-4:

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

Your task is to write a code that takes an input n and creates such a matrix, in the same language as a cop post, and with a code that matches the cop's regex. The output format of your code must match the output format of the cop's code.

Please leave a comment under the Cop's post to indicate that you have cracked it.

Winning criterion:

The winner will be the user that has cracked the most submissions. In case of a tie, then there will be multiple winners.

\$\endgroup\$

41 Answers 41

10
\$\begingroup\$

Jelly, 9 bytes, cracks @Dennis' answer

²sµUFḤ$¦G

Try it online!

Should be correct now; I had to rather rethink what I was doing.

Explanation

The hardest part of this problem is getting a list of the even indices inside the ¦ (which applies an operation at specific indices). Unlike most operations, which use the input to the whole program as a default for the second operand, ¦ uses the most recently seen value as a default (because it conceptually has two left operands, rather than a left and a right operand like most things that take in two values).

However, we can observe that we have a list of numbers, including all integers from 1 to half the input, already in the current value at the time. As such, flattening and doubling it gives us a list of even numbers, including all the even indices (also some other even numbers but we don't care about those). It's even possible to spend one µ solely to avoid a parsing ambiguity and still come in within 9 characters.

²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.         
\$\endgroup\$
4
  • \$\begingroup\$ Uh, the way ¦ works kills me every time, I tried this yesterday but with rather than U and decided the was not working out. \$\endgroup\$ Mar 9, 2017 at 12:25
  • \$\begingroup\$ Nice, I nearly had it but got stuck at selecting every other element as well. F was a great idea, \$\endgroup\$ Mar 9, 2017 at 12:38
  • \$\begingroup\$ My original code is pretty much identical to this. I just used J instead of F. \$\endgroup\$
    – Dennis
    Mar 9, 2017 at 12:39
  • \$\begingroup\$ @Dennis Oh, J... I had tried with LR but couldn't get it under 11 bytes \$\endgroup\$ Mar 9, 2017 at 12:41
9
\$\begingroup\$

05AB1E, Emigna

This was my first time using 05AB1E. Got it with a little bit of help. That was fun. :)

UXFXLNX*+N2BSR1k_iR}ˆ

Try it online

Explanation:

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

I actually found this similar program on my own, but the output format is different:

UXFXLNX*+N2BSR1k_iR}=

Try it online

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

See the edit history for my previous two attempts.

\$\endgroup\$
3
  • \$\begingroup\$ Nice job! Quite similar to the original solution. \$\endgroup\$
    – Emigna
    Mar 8, 2017 at 22:55
  • 5
    \$\begingroup\$ not bool(reversed(str(bin(N))).index('1'))... I think that's the most absurd way I've seen anyone do a N%2 operation. \$\endgroup\$ Mar 9, 2017 at 7:29
  • 3
    \$\begingroup\$ @StewieGriffin When life gives you lemons but no water or sugar, you just have to eat them raw. :D \$\endgroup\$
    – mbomb007
    Mar 9, 2017 at 14:24
6
\$\begingroup\$

Python 2, Dennis

This is a fun token golfing problem.

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

Regex verification

\$\endgroup\$
5
\$\begingroup\$

Ohm, Nick Clifford

My first time attempting Ohm.
Really nice language that I look forward to use again :)

²@┼σ▓_^è?R

Explanation

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

My first attempt that didn't work as adding an array and an int is not possible:

@┼MDR┼+;W

My second attempt that didn't match the regex:

²@┼σ▓_^MR
\$\endgroup\$
1
  • \$\begingroup\$ You did it exactly how I did! Great job! \$\endgroup\$ Mar 9, 2017 at 12:50
5
\$\begingroup\$

05AB1E, Emigna (2nd submission)

First time working with 05AB1E.

VYLUYFYXDˆ+RU

Try it online! | Regex verification

Explanation

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
\$\endgroup\$
6
  • \$\begingroup\$ Nice job! You got the intended solution :) \$\endgroup\$
    – Emigna
    Mar 10, 2017 at 21:11
  • \$\begingroup\$ @Emigna thanks! I wouldn't have gotten it if it weren't for the other solutions on here (yours included) that let me realize that the global array will print if the stack is empty! If it weren't for that I'd never have figured it out; I kept trying to do tricks that ended with ) thinking it'd be the only way to get the correct result on the stack. \$\endgroup\$
    – Value Ink
    Mar 10, 2017 at 23:03
  • \$\begingroup\$ Yeah it's pretty impossible to do with ) when you can only use 2 non-alphanumeric characters. The tricky part here was meant to be structuring the program to only use 2 wildcards and have them sequential. Would likely have been a bit harder without the other solutions but there should have been some puzzling involved :) \$\endgroup\$
    – Emigna
    Mar 11, 2017 at 8:53
  • \$\begingroup\$ @Emigna What I want to know is if ^\w*..$ is possible. \$\endgroup\$
    – mbomb007
    Mar 14, 2017 at 16:55
  • \$\begingroup\$ @mbomb007: I don't think so. With this tactic you'd need to save the result of the addition for the next iteration and you can't use the stack for this meaning that one of UV need to come after . I can't think of another way to do it with only 2 wildcards at the end either. It can be done with 3 wildcards though. \$\endgroup\$
    – Emigna
    Mar 14, 2017 at 17:03
5
\$\begingroup\$

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

All linefeeds are for cosmetic purposes and can be removed without affecting the program.

Try it online!

Explanation

After Lynn removed {|} from the list of allowed characters, I had to try something new. It turns out we can still construct arbitrary strings and evaluate them as code.

First, we need to get some value onto the stack. The only available built-ins that push something without popping something else first (and without reading the input) are es, ea and et. I'm sure you could start from all of these one way or another, but I went with es which pushes the current timestamp. Since I didn't want to make any assumptions about its actual value, I test its primality with mp (which gives 0 and 1) and test that value's primality again to ensure I've got a 0 on the stack. A 1 will be more useful, so we compute exp(0) with me and turn it into an integer with i. So all the numbers start with:

esmpmpmei

Now we've got a whole bunch of unary maths operators to work with:

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)

We can also combine a few built-ins for more elaborate functions of 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.

Using these, we can obtain any number in 0 <= x < 128 (and many others) in less than 10 steps from 1. I'm sure a much smaller subset of these commands would also suffice. I've written a small Mathematica program, to determine all of these snippets (it's not very readable, sorry):

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]

With that, we can simply push an arbitrary list of character codes, converting each of them to a character with c afterwards. Once we've pushed the entire code we want to execute, we push 95 (]). We eval that one with ~ to wrap all the others in a string, and then we eval that string with ~.

The actual code run at the end of the program is again:

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

See my previous solution for an explanation.

\$\endgroup\$
4
\$\begingroup\$

Python 3, TuukkaX

Sorry, the regex you used was too easy to trivialize. No 0, # or ? No problem!

I might've misinterpreted the example output but it's still pretty easy to tweak since I have 45 spare characters left over

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"
\$\endgroup\$
1
  • \$\begingroup\$ Nice! :D FYI: I'll create another one in Python, if you're interested to solve it ;) It'll be a bit longer, but the beauty lies in the uncrackfulness. \$\endgroup\$
    – Yytsi
    Mar 9, 2017 at 9:17
4
\$\begingroup\$

R, MickyT

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

Tests cases:

> 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 

And regex confirmation: https://regex101.com/r/OB8ZIM/1

I also had:

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

which gives the same output and match the same regex.

\$\endgroup\$
2
  • 6
    \$\begingroup\$ lets_make_a_snake... I'd be surprised if that was the intended solution :P \$\endgroup\$ Mar 9, 2017 at 9:48
  • \$\begingroup\$ @plannapus Great job . The first one is basically what I was intending using ` for ` and ` if `, but a lot better golfed than mine. \$\endgroup\$
    – MickyT
    Mar 9, 2017 at 17:27
4
\$\begingroup\$

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="||||||"}

This is an anonymous function that matches this PCRE regex: ^{(\|[^\/#\s]*){8}$.

Try it online!

\$\endgroup\$
4
\$\begingroup\$

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
)

The first part of the subcommand will generate 1 2 3 4, 9 10 11 12, and the second part will generate 8 7 6 5, 16 15 14 13. The outer sort -n will properly mix them together to form the snake pattern.

I used the trick in https://superuser.com/a/101760 to print the odd and even lines. Thank you Marcos, really a fun one.

\$\endgroup\$
1
  • \$\begingroup\$ Very nice solution \$\endgroup\$ Mar 11, 2017 at 18:13
3
\$\begingroup\$

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

\$\endgroup\$
3
\$\begingroup\$

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)

Slightly analyzing the cop's regex shows a fixed template:

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

where _ is any character except [ '"#] and ^ is any of [int()2/].

The "*n) at the end clearly shows an eval("..."*n) or exec("..."*n) is going on, so we just need to make sure the "..." prints the j-th row.

The for i in range(j, is too close to the end of the string, hinting list comprehension without any if. So we need to construct the i-th column using those i%n, 2*n stuff.

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)
\$\endgroup\$
1
  • \$\begingroup\$ Nice! Well, almost survived a week :D I'll post my original code. \$\endgroup\$
    – Yytsi
    Mar 9, 2017 at 21:13
3
\$\begingroup\$

dc, Mitchell Spector

This was my first entry to a cops and robbers challenge, and I had a lot of fun. The regex needed to be matched was simple, ^[^# !]{59}$, which basically turned my job into a golfing one, without using those 3 characters. Initially I had difficulties getting below 60 bytes, but I cracked it in the end.

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

Try it online!

Explanation:

My code uses one loop with N 2 iterations, keeping a zero based counter (1D), and calculates what number needs to be printed based on the corresponding matrix row and column (r, c) coordinates.

Example of what I mean, if 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

It looks complicated, but the intermediary step is helpful. Plus, I've tried using 2 loops from the start, but I ended up above the regex character limit. Number generation at each iteration (zero based):

  • if r % 2 = 0 (normal row), n = (r * N) + c = counter
  • if r % 2 = 1 (reversed row), n = ((r + 1) * N) - c - 1 = counter + N - (2 * c) - 1

Or all at once, as one based numbering: 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.
\$\endgroup\$
5
  • \$\begingroup\$ @MitchellSpector Here is my explanation. As you see, we both have literally the same algorithm, only I use the command ~ to calculate the row and column indexes in one go. But one of my previous attempts did calculate them separately as you did. Great minds think alike? :) \$\endgroup\$
    – seshoumara
    Mar 10, 2017 at 18:46
  • 1
    \$\begingroup\$ Yes, it really is the same algorithm. I like your use of ~ to shorten the code. \$\endgroup\$ Mar 10, 2017 at 19:15
  • \$\begingroup\$ I think you can shorten it by one byte if you use the square-root trick in the loop test at the end of the macro: ?sN0[AP]sP[ddlN~_2*lN+1-r2%*+1+n32P1+dlN%0=PdvlN>L]dsLx tio.run/nexus/… \$\endgroup\$ Mar 10, 2017 at 19:23
  • \$\begingroup\$ @MitchellSpector You're right, and I did notice it when reading your explanation, but commented in the chat room instead. \$\endgroup\$
    – seshoumara
    Mar 10, 2017 at 19:29
  • \$\begingroup\$ Yes, I see that now -- I hadn't looked at the chatroom this morning yet. \$\endgroup\$ Mar 10, 2017 at 19:44
3
\$\begingroup\$

PowerShell, ConnorLSW

Crack

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

I started with a smaller solution to the issue and padded my variable names to get the regex to match. Trying to find a use for the colon I suppose was the hardest part to wrap my head around.

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

Explanation

# 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" "
\$\endgroup\$
2
  • \$\begingroup\$ Nice, I used a $script variable and some really messy looping to pad it out, the [array]::Reverse() was correct though, congrats - I think you might want to even out the length of $i and $MySnakeIndex though. \$\endgroup\$
    – colsw
    Mar 10, 2017 at 21:22
  • \$\begingroup\$ @ConnorLSW I know you would not be able to sleep at night knowing I had errors in my robber. I have fixed it. \$\endgroup\$
    – Matt
    Mar 11, 2017 at 1:23
3
\$\begingroup\$

CJam, Lynn

Something like this:

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

All whitespace is for... "readability"... and can be omitted to comply with Lynn's regex.

Try it online!

Explanation

The regex requires that we solve problem using only:

  • Lower-case letters.
  • {}, which can be used to create blocks.
  • |, mostly used for bitwise OR.
  • ~, "eval" and bitwise NOT (also "dump array", but I'm not going to use it).

Since we have, ~, if we can construct arbitrary strings, we can run arbitrary code. However, at first it's not obvious how to do that.

The first piece of the puzzle is that blocks are unevaluated bits of code, which can turn into strings with s. So {abc}s gives us "{abc}". Next, we can use eu to convert these strings to upper case.

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

The benefit of this is that upper-case letters are pre-initialised variables, so we can get a lot of constant values by creating such a string, and eval'ing it twice (once to turn the string back into a block and once to execute that block). We can't get all the letters, because some, like x aren't valid commands (so CJam will refuse to parse a block containing them). We can't use f as is, because it needs to be followed by another command, but we can use fb and then OR the two values together. Likewise, we can use ee instead of e. With that, we can get the numbers 0, -1, 3, and 10 to 19. The -1 is convenient, because if we turn it into a string ("-1") then into a character ('-) and then eval it, we can get either subtraction or set difference. Like I said, we can't get X (for 1), but we can take the absolute value of -1 with z.

We can also use s to get a string containing a space, and use c to turn that into a space character:

{s}seu~~c

This is convenient, because from there we can get lots of useful commands in the lower ASCII range by ORing the space with various numbers. To get some of the characters above code point 48, we use the character '0 as the basis instead:

{t}seu~~si

This is already enough to construct arbitrary strings, because we can get '+ (addition and string concatenation) from the following snippet:

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

And we have a literal 1 so we can just push space characters, increment them to the value we need and then concatenate them all together, but that's a bit boring and the code would become massive.

Instead, I've generated [ and ] and evalled them, so that all the characters I push in between are wrapped in a string automatically. That's these two lines:

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

And finally, we'll need f and ~ in the string we're generating. While those are valid characters already, we don't have string literals or character literals, so we'd have to generate these as well and building up larger code points from the space is a bit annoying. Instead, I've made use of the set subtraction here, but subtracting two blocks (to get rid of the {}):

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

That's pretty much all there is to it. We eval [. We push all the characters, obtained by various computations from the few built-in constants we have, |, - (via eval) and + (via eval). We eval ]. We flatten the entire thing into a string, because at some point I added some strings or numbers into the list. We eval our arbitrary string with ~.

The ri...p are part of the actual final program, but I've extracted them because they don't need encoding.

Finally, this is the program we're actually running:

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.
\$\endgroup\$
3
\$\begingroup\$

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

Try it online!

This defines a function f that returns the answer. It also prints the names of the functions I defined to stdout, but I assume that doesn't matter, since [we're allowed to choose our output stream] for code golf, at least. If it's a big deal, I think I can tweak it to not print those. How did I do it? I started with something fairly 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))))))

Then, I observed that one can transform functions definitions like this:

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

becomes

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

And function calls like this:

(a x y)

becomes

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

I used this recursive Vim macro, stored in register q, to do the second one (I have jk mapped to <Esc>): f s(v(h(q(jkea))))jk@q.

These two transformations were sufficient to eliminate all spaces.

\$\endgroup\$
2
  • \$\begingroup\$ Nicely done! My original code is quite similar, though I wrote a helper macro to make it a bit less painful to write. I'm curious as to your thoughts on how to avoid printing the defined symbols--if you'd care to share them, I'll be in the tinylisp chat room. \$\endgroup\$
    – DLosc
    Mar 16, 2017 at 7:03
  • \$\begingroup\$ @DLosc Done, I posted there. \$\endgroup\$ Mar 16, 2017 at 16:43
2
\$\begingroup\$

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

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

\$\endgroup\$
6
  • \$\begingroup\$ I get "Expression resolves to an unused function" with this on its own, but I'm unfamiliar with everything that makes an acceptable answer. Is the e.g. `let a = <code>; a(CShort(4)); required to make it run not necessary? \$\endgroup\$ Mar 9, 2017 at 13:11
  • \$\begingroup\$ @JamesWebster I'm not sure about the exact rules since "a code" is pretty ambiguous. For code-golf the submission can be a program or function, so I just provide an anonymous function here. How else do we receive the input arguments? \$\endgroup\$
    – kennytm
    Mar 9, 2017 at 13:17
  • \$\begingroup\$ My original was the body of a function, so not sure mine is valid either! So I'm just gonna go with "Sure, this is fine" and upvote it. :) \$\endgroup\$ Mar 9, 2017 at 13:18
  • \$\begingroup\$ @JamesWebster You can call the whole thing as (…)(4), no need to cast the integer literal to CShort. \$\endgroup\$
    – kennytm
    Mar 9, 2017 at 13:18
  • \$\begingroup\$ Ah yeah! I would never have thought of that. \$\endgroup\$ Mar 9, 2017 at 13:19
2
\$\begingroup\$

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 is too long (thus the snake), and the lack of whitespace can be easily worked-around.

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~')
?>
\$\endgroup\$
1
  • \$\begingroup\$ Nice variant. My fault was not to think about a function and make only one output \$\endgroup\$ Mar 9, 2017 at 14:11
2
\$\begingroup\$

Jelly, length 12, @JonathanAllan

Ḷ-*m@"s@²$G

Try it online!

How it works

Ḷ-*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.
\$\endgroup\$
2
\$\begingroup\$

Jelly, 12 bytes, cracks @JonathanAllan's second answer

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

Try it online!

Explanation

This is almost the same as my other answer. I just made two changes:

First, I changed U ("reverse each element") to Ṛ€ ("reverse" "each element"). That doesn't help by itself, because is also banned.

Then, I changed the ("reverse") to ;@/ (/ "fold by" ; "concatenating" @ "in the opposite order to the original list"). That avoids all the banned characters, giving a valid solution.

I assume the next step would be to start banning array-manipulation quicks, in addition to the atoms.

\$\endgroup\$
3
  • \$\begingroup\$ Uh, I knew I should have banned ... \$\endgroup\$ Mar 10, 2017 at 0:35
  • \$\begingroup\$ You can write in terms of / too. It's just rather more verbose than this solution. \$\endgroup\$
    – user62131
    Mar 10, 2017 at 0:39
  • \$\begingroup\$ Yep and one could ;@\ṫ0, the regex is getting long. \$\endgroup\$ Mar 10, 2017 at 0:44
2
\$\begingroup\$

Jelly, length 13, @JonathanAllan

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

Try it online!

How it works

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.
\$\endgroup\$
1
  • \$\begingroup\$ Oh wait, what, I missed m?! \$\endgroup\$ Mar 10, 2017 at 1:49
2
\$\begingroup\$

Jelly, length 14, @JonathanAllan

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

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ That is impressive :D \$\endgroup\$ Mar 10, 2017 at 2:57
  • \$\begingroup\$ Thanks! :) For some reason, I was convinced that my code couldn't contain any newlines, which forced me to discover some chain trickery. \$\endgroup\$
    – Dennis
    Mar 10, 2017 at 3:03
2
\$\begingroup\$

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

Haven't touched Scala in awhile, it was fun to revisit. Unfortunately, this solution misses out on a lot of Scala's cool features.

Try it out here

Regex Confirmation

\$\endgroup\$
2
\$\begingroup\$

QBasic (QB64), @DLosc

Note that since the . does not match \n (U+000A, LF), the newline here is a \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

Verify:

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

The main difficulty is how to insert a word after the ;. Thankfully, QB64 treats CR as a newline while Python's regex doesn't, so we could slip a REM\r here. Out of the five allowed regex flavors,

So this crack is fine as long as we don't mention JavaScript... 🤐

\$\endgroup\$
1
  • \$\begingroup\$ I'll accept this, since it works in QB64. However, I will also say that archive.org's QBasic (which I think is the actual QBasic rather than an emulation) complains about REM immediately following a statement with no statement separator. My original solution did not use comments. I've got another variation that I will be posting shortly. :D \$\endgroup\$
    – DLosc
    Mar 11, 2017 at 23:11
2
\$\begingroup\$

Python 3, kennytm

def S(N,A=1,K=1,E=list,r=range):print(E(r(A,A+N)[::K]))or(A>N*N-N)or(((S(N,A+N,-K))))

Regex verification

\$\endgroup\$
2
\$\begingroup\$

><>, torcado

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

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

The program cannot contain numbers, but we can get numbers via:

  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.
\$\endgroup\$
1
  • \$\begingroup\$ Minor issue, cop version was tab-delimited as opposed to space-justified, but no biggy. \$\endgroup\$
    – user15259
    Mar 9, 2017 at 22:31
1
\$\begingroup\$

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

\$\endgroup\$
1
  • \$\begingroup\$ Ah, I messed that up didn't I \$\endgroup\$
    – Value Ink
    Mar 13, 2017 at 19:08
1
\$\begingroup\$

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.
\$\endgroup\$
1
  • \$\begingroup\$ Good work. (BTW, it's more idiomatic just to do (f 4)--the disp is implied.) \$\endgroup\$
    – DLosc
    Mar 13, 2017 at 5:54
1
\$\begingroup\$

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)
)
?>
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.