# Robbers: Crack the regex - Make a snake

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.

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.

# PHP, @Ionut Botizan

Once upon a time I remember that PHP has a goto

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

double assigments are alternatives for example Newline under Mac and Linux

solution with tab

<?="";
$p="M"&";";$cr="M"&"-";
$cr="Z"&"*";$zero=$one=$line=$text="";$zero++;$zero--;$a=$zero;$s="$zero"&"$";
$one=++$one;
$g=$argv{$one};$dir=$one; a:++$a;
$line=$dir?"$line$a":"$a$line";
$line=$a%$g?$dir?"$line$p":"$p$line":"$line$cr";
$dir=$a%$g?$dir:$one-$dir;
$text=$a%$g?$text:"$text$line";
$line=$a%$g?$line:"";
echo$a-$g*$g?"":$text;
$a-$g*$g?:exit; goto a;  First I have tought that I must use dynamic spaces <?="";$cr="M"&"-";
$cr="Z"&"*";$zero=$one=$line=$text="";$zero++;$zero--;$a=$zero;$s="$zero"&"$";
$one=++$one;
$five=$one+$one+$one+$one+$one;
$ten=$five+$five;${"v$zero"}="$s$s$s$s$s$s$s";
${"v$one"}="$s$s$s$s$s$s";
${"v$ten"}="$s$s$s$s$s";$g=$argc-$one;
$g=$argv{$one};$space=$zero;$p=${"v$space"};
$dir=$one;
a:++$a;$a%$ten?:$space++;
$p=${"v$space"}??$p;
$line=$dir?"$line$a":"$a$line";
$line=$a%$g?$dir?"$line$p":"$p$line":"$line$cr";
$dir=$a%$g?$dir:$one-$dir;
$text=$a%$g?$text:"$text$line";
$line=$a%$g?$line:"";
echo$a-$g*$g?"":$text;
$a-$g*g?:exit; goto a;  • My output was aligned with tabs, but StackExchange converted them to spaces. Anyway, a tab character is just as easy to obtain as a newline so it doesn't really matter! :) Mar 13 '17 at 9:01 • @IonutBotizan It works better with tabs. tab="M"&"+"; or $tab="M"&";"; are two ways to create the tab Mar 13 '17 at 12:46 • I know, that's what I used and that's why M was whitelisted! :) Mar 13 '17 at 12:59 # PHP, @Jörg Hülsermann $n=next($argv);$a=array();for($i=0;$i<$n;++$i){$f=$i*$n;$g=$f+++$n;$a{$i}=$i&1?range($g,$f):range($f,$g);}echo(serialize($a));;


In PHP, range(1, 4) gives [1, 2, 3, 4] while range(4, 1) gives [4, 3, 2, 1]. o_O.

# Racket Intermediate Student with Lambda, @Brian McCutchon

(λ(n)(foldr(λ(p q)(cons((λ(x)(if(even? p)(range(+ x 1)(+ x n 1)1)(range(+ x n)x -1)))(* p n))q))'()(range 0 n 1)))


(λ can be replaced by lambda, both are allowed in the regex.)

Since I can't get TIO to restrict to htdp-intermediate-lambda and I don't want to download a new language, I will just assume it is fine as long as I only use functions given on that page:
λ foldr cons if even? range + *.

Since TIO does not include the words "list" in the output (it just produces '((1 2 3 4) (8 7 6 5)…), if the above crack is rejected, consider this quick fix:

(λ(n)(cons 'list(foldr(λ(p q)(cons(cons 'list((λ(x)(if(even? p)(range(+ x 1)(+ x n 1)1)(range(+ x n)x -1)))(* p n)))q))'()(range 0 n 1))))

• Nice, this is exactly what I had in mind, and your code works fine. The reason there is no list in your output is because standard Racket doesn't include it; it gives the right output in ISL. Now check out my new one, which should be much harder. Mar 13 '17 at 21:08
• Oh, and I just found out that you can run ISL with lambda in TIO by putting #lang hdtp/isl+ at the top or in the header. (Of course, you can run it from Dr. Racket without the header, so that shouldn't count as part of the program.) Mar 16 '17 at 0:39

# Mathematica, @Martin Ender (non-competing)

((#//Range)+i#-#)~SortBy~(-(-#)^i&)~Table~{i,#} &


# QBasic, @DLosc

DEFSTR S:CLS:INPUT N:ONE=N\N:TWO=ONE+ONE:FOUR=TWO+TWO:SELECT CASE N:CASE IS<FOUR:FW=ONE:CASE IS<FOUR*TWO+TWO:FW=TWO:CASE ELSE:FW=ONE+TWO:END SELECT:READ S:FOR I=ONE TO N:FOR J=ONE TO N:COL=J*FW+J-FW:LOCATE I+ONE,COL:G=I MOD TWO:F=J*TWO-ONE-N:V=I*N-J+ONE+G*F:PRINT V:LOCATE I+ONE,COL:PRINT S:NEXT:LOCATE I+ONE,N*FW+N+ONE:PRINT S:NEXT:DATA|


Prettified (s/:/\n/g):

DEFSTR S
CLS
INPUT N
ONE = N\N
TWO = ONE+ONE
FOUR = TWO+TWO
SELECT CASE N
CASE IS < FOUR: FW = ONE
CASE IS < FOUR*TWO+TWO: FW = TWO
CASE ELSE: FW = ONE+TWO
END SELECT
FOR I=ONE TO N
FOR J=ONE TO N
COL = J*FW+J-FW
LOCATE I+ONE, COL
G = I MOD TWO
F = J*TWO-ONE-N
V = I*N-J+ONE+G*F
PRINT V
LOCATE I+ONE, COL
PRINT S
NEXT
LOCATE I+ONE, N*FW+N+ONE
PRINT S
NEXT
DATA|


Use LOCATE to force the output position. Use DATA/READ to obtain "|" without using functions.

• Yup--pretty similar to my original code. Mar 14 '17 at 20:04

# Racket Intermediate Student with Lambda, @Brian McCutchon

(λ (n)(((λ (f) (f f))(λ(s)(λ (i a b) (cond [(= i(* n n))'()] [#t(cons(a 1 i)((s s) (+ n i)b a))]))))0((λ (g) (g g))(λ(u)(λ (j i) (cond [(> j n)'()][#t(cons(+ j i)((u u) (+ 1 j)i))]))))((λ(g) (g g))(λ(d) (λ(j i) (cond [(> j n)'()][#t(cons(+(- n j)1 i)((d d) (+ 1 j)i))]))))))


Uses this trick to perform recursion without define/letrec/let*, otherwise a pretty standard algorithm. Some spaces cannot be eliminated due to the regex restriction.

• Hah, interesting! I used the Y combinator, which comes out to basically the same thing. Mar 18 '17 at 14:24

s@²UJḤ$¦Ȯṛ“” Ç²s  Try it online! • This doesn't match the regex. You're missing the œ?. – user62131 Mar 10 '17 at 2:33 • The ? quantifier makes œ optional. Mar 10 '17 at 2:35 • Oh, duh. I need to go fix the regex, then. It's a pity that cops-and-robbers tends to end up littered with broken questions like this. – user62131 Mar 10 '17 at 2:38 • Come to think of it, is the original question even valid? I didn't have a submission that matched the regex (and wasn't aware of it because I missed that ? was a metacharacter). – user62131 Mar 10 '17 at 2:41 • As long as it's actually solvable, there is a solution, so it's valid. You couldn't win with your submission unless you crack it yourself though. Mar 10 '17 at 2:42 # Jelly, 16 bytes, @ais523 s@²UJḤ$¦Ȯṛ“”
Çœ?²s


Try it online!

# 05AB1E, mbomb007

Unlikely to be the intended solution :)

Crack

UXF**XLNNVX*F>}YFR}ˆ


Explanation

U                      # store input in X
XF                    # X times do:
**                  # multiply nothing twice
XL                # range [1 ... input]
N               # push current iteration number
NV             # store current iteration number in Y
X*           # multiply current iteration by input
F>}        # increment the range that many times
YFR}    # iteration number times, reverse the range
ˆ   # add it to global array
# implicitly print global array after program end


# Go, @Kristoffer Sall-Storgaard

package main

import . "fmt"

const (
zero = iota
one
two
)

func inc(p int) int {
var bit = one
for {
if (p & bit) == zero {
return p | bit
}
p ^= bit
bit *= two
}
}

func dec(p int) int {
var bit = one
for {
if (p & bit) == bit {
return p ^ bit
}
p |= bit
bit *= two
}
}

func main() {
var n int
var i int
var row = one
var col = zero
Scan(&n)
print("[")
for n*n > i {
i = inc(i)
if col == zero {
print("[")
}
if row%two == one {
print(i)
} else {
var m = row * n
var c = col
for c > zero {
m = dec(m)
c = dec(c)
}
print(m)
}
col = inc(col)
if col == n {
print("]")
col = zero
row = inc(row)
}
if i != n*n {
print(" ")
}
}
print("]")
}


The regex means we only use one character from + to <, i.e.

+,-./:;<0123456789

The "." is needed for fmt.Scanf anyway. Although the character set is restricted, with unlimited length we could still write very complex programs.

• The lack of numbers is trivial to workaround, just use iota to define constants.
• The lack of < is also simple, just use > instead.
• The lack of + and - are trickier. Here I reimplemented inc(x) == x+1 and dec(x) == x-1 using bit operations. Perhaps there is an easier way but this isn't a 😆
• The lack of , means we cannot use functions with two or more arguments, so make() and append() are out. There might be other ways to construct an array, but I find printing the output as if it is an array is simpler.
• You're right about the arrays, I didn't use them :) I also avoided decrement entirely by using defer instead, my inc function was actually just func inc(i *int) { *i = ^*i * -1 } having gotten the -1 by using ^0 Mar 11 '17 at 9:11
• @KristofferSall-Storgaard Ah thanks. Forgot the old x+1 == -~x and x-1 == ~-x trick :D. Mar 11 '17 at 11:16

# C#, @Eklipz

static int[,]F(int n){var a=new int[n,n];for(int r=n-n,z=r;r<n;++r)for(var c=z;c<n;++c)a[r,c]=n*r+((r&-~z)!=z?n-c:c-~z);;;;;;;;;;;;;;;;;;;;;;;return a;}


Uses standard tricks like z := n - n == 0 and -~z == 1 to produce the missing numbers.