Square-Random-Symmetrical
R, 124 118 bytes
function(n,i=(n+1)/2,j=n%/%2,m="[<-"(matrix(-letters,i,i),j-1,j-1,0:9-1))cbind(y<-rbind(m,m[j:1,]),y[,j:1])
`-`=sample
Try it online!
In R, things that look like operators are just functions that get special treatment from the parser.
If you redefine an operator (like -
) to be some other function, it keeps the special treatment from the parser. Since -
is both prefix and infix, and I need to call the sample
function with both one and two arguments, I can use
`-`=sample
to get what I want.
So the code -letters
is translated to sample(letters)
, which randomly shuffles the letters
built-in. But j-1
is translated to sample(j,1)
, which randomly samples 1
item from the vector 1:j
.
(This behaviour of the sample
function depending on the number of parameters and what the first parameter is, is a huge pain in the butt in production code, so I'm happy to find a great use of its perverse nature here!)
Otherwise the code just makes the top left quadrant of the required result, replaces a random element (the j-1
,j-1
bit) with a random digit (the 0:9-1
bit), and folds it out for the required symmetry. The i
and the j
are needed to deal with the even and odd cases.
Python3, 287 bytes
My first try at golfing something here; I'm sure someone can do far better:
import random as rn, math as m
n=int(input())
x,o=m.ceil(n/2),n%2
c=x-1-o
f=lambda l,n: l.extend((l[::-1], l[:-1][::-1])[o])
q=[rn.sample([chr(i) for i in range(97, 123)],x) for y in range(x)]
q[rn.randint(0,c)][rn.randint(0,c)] = rn.randint(0,9)
for r in q:
f(r, n)
f(q, n)
print(q)
Try it Online!
Thanks to HyperNeurtrino, Ourous and Heiteria this shrunk down to 193 bytes (see comments). However, TFeld correctly pointed out that multiple calls to sample
aren't guaranteeing at least N
different characters.
That stuff in mind, try this new version that should guarantee at least N
different characters per run.
Python3, 265 260 bytes, at least N
distinct characters
from random import *
n=int(input())
x=-(-n//2)
o=n%2
c=x+~o
i=randint
u=[chr(j+97)for j in range(26)]
z,q=u[:],[]
for y in [1]*x:
shuffle(z)
q+=[z[:x]]
z=z[x:] if len(z[x:])>=x else u[:]
q[i(0,c)][i(0,c)]=i(0,9)
for r in[q]+q:r.extend(r[~o::-1])
print(q)
Try it online!
Charcoal, 30 bytes
NθE⊘⊕θ⭆⊘⊕θ‽βJ‽⊘θ‽⊘θI‽χ‖OO→↓﹪θ²
Try it online! Link is to verbose version of code. If n
is always even, then for 23 bytes:
NθE⊘θ⭆⊘θ‽βJ‽⊘θ‽⊘θI‽χ‖C¬
Try it online! Link is to verbose version of code. Explanation:
Nθ
Input \$ n \$.
E⊘θ⭆⊘θ‽β
Create an \$ \frac n 2 \$ by \$ \frac n 2 \$ array of random lowercase letters. This prints implicitly as a square.
J‽⊘θ‽⊘θ
Jump to a random position in the square.
I‽χ
Print a random digit.
‖C¬
Reflect horizontally and vertically to complete the matrix.