[Question]
  [
## Challenge
Write a program or a function that returns or prints a square-random-symmetrical matrix.
---
## Input
**N**: The size of the matrix i.e `6 x 6`
---
## Output
The matrix. You can either print it, return it as string (with the newlines) or as a list/array of lists/arrays.
---
## Rules
1. You need to use at least `N` different characters, where `N` is the size of the square matrix (input). Since we 're using only letter [a, z][A, Z] and digits [0, 9] (and only 1 digit at the time) you can assume that `N < 27` and `N > 2`, that is because at `N <= 2` you can't have both letters and digits. Last but not least, every letter/digit must have non-zero probability of occurring (uniform distribution is not a necessity). However, the result must have at least `N` different letter/digits.
2. The matrix has to be both horizontally and vertically symmetrical.
3. Exactly 2 rows and 2 columns must contain strictly one single-digit number (it's position should be random as well). The rest of rows/cols will contain only letters. Consider letters as [a, z] and [A, Z] and of course single-digit numbers as [0, 9].
4. Just to be easier, you can assume that the case of the letters doesn't matter, as long as the cases are symmetrical which means: `a=A, b=B, etc`.
5. Every possible output must have a non-zero probability of occurring. The random distribution doesn't need to be uniform.
---
## Example
**Input**: 8
**Output**:
```
c r p s s p r c
r k o z z o k r
u t 2 a a 2 t u
y n q z z q n y
y n q z z q n y
u t 2 a a 2 t u
r k o z z o k r
c r p s s p r c
```
  
[Answer]
# [R](https://www.r-project.org/), ~~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!](https://tio.run/##HcbRCoIwFIDhe58iBOEcOgebFJFsTzIEzTbYcCvmgnz6VV78P18q9iC52Hecs3tGiOQUxKPAtiOvYtM2HQVVa8k1hCkn9wFeTM4mreTIIXkWe6f@xgJxvrv4gE1y2hEoaN8LGpA2TT8NWI08qnUKr8UUC2esLFz@u2L5Ag "R – 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.
[Answer]
# 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!](https://tio.run/##ZU7LasMwELzrK/ZS0ILs1g6lxKAvMTqotlwLpNUjCihf71rNoZTuZV7LMPFR9kCX47A@hlwga1qDB32DTAK8LnvjnpG0VLileC8ckVURpO8XYx2n1xEFvYxskbUbusA26bT/XDU4QRO43tRiaOXczdPUDUrASU58KpyDQpbknKm/aR@d4fOyZ24RtpDBgqW26cvw64eAYbygEvWZPX6zioqlVtHmt6FvYkH1zwAJf6wrslaUW1GaGJy38SyATp@nH4y5vSY8jvdv)
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!](https://tio.run/##NY/BasMwEETv@xW6FLSx3TRuaYlg8yNCh@LItYIjWYoMig75dUcK9PQYZneGWe5xcvZz28bgriz82nOBuS4uRLYDS8ZGbuyyRo4IiTre2f2@R3Bk33oYKDUPB4bqYzmFleQwBX5pjj84usAuzNia@qd5/40KcutplUK1UkH179WXB7VLAhi7Tes4zppnLMI3JLMUSakiMmWZhGJmZLO2/CXwRInp@aZZTQQvDf9oB1T/pMojvnpC6ZFeNV6Ed52itmce5MMJ0R0UwhLqTI/b9vUE)
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 30 bytes
```
ＮθＥ⊘⊕θ⭆⊘⊕θ‽βＪ‽⊘θ‽⊘θＩ‽χ‖ＯＯ→↓﹪θ²
```
[Try it online!](https://tio.run/##fY3LCsIwEEX3/YosJxBB3QjtUhdWqEr1B6ZpbAt5NSb182OQ@lg5mxnunMPlPTpuUMZYahv8MahGOBhpkZ3doD1UaGGPchItlJo7oYT26R4pZeTiE9L9I2rUrVHQ0DRFdgjKXg3M4ez8ct/o07/Fu38bq@XrUYubFNyfJuEk2nlBXg9d7xnJd@ahGalMG6SBkZF1cmLcxMUknw "Charcoal – Try It Online") Link is to verbose version of code. If `n` is always even, then for 23 bytes:
```
ＮθＥ⊘θ⭆⊘θ‽βＪ‽⊘θ‽⊘θＩ‽χ‖Ｃ¬
```
[Try it online!](https://tio.run/##S85ILErOT8z5/98zr6C0xK80Nym1SKNQ05oroCgzr0TDN7FAwyMxpyw1BSiooxBcAhRNRxMMSsxLyc/VSNIEAmsur9LcgpB8DaggXBlCHUIIbotzYnEJTIehAVgiKDUtJzW5xDm/oFLD6tAaTev//y3@65blAAA "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
Ｎθ
```
Input \$ n \$.
```
Ｅ⊘θ⭆⊘θ‽β
```
Create an \$ \frac n 2 \$ by \$ \frac n 2 \$ array of random lowercase letters. This prints implicitly as a square.
```
Ｊ‽⊘θ‽⊘θ
```
Jump to a random position in the square.
```
Ｉ‽χ
```
Print a random digit.
```
‖Ｃ¬
```
Reflect horizontally and vertically to complete the matrix.
[Answer]
# [APL (Dyalog Classic)](https://www.dyalog.com/), ~~45~~ ~~44~~ ~~43~~ 40 bytes
thanks @Adám for -1 byte
```
26{(⎕a,⍺⍴⎕d)[⌈∘⊖⍨⌈∘⌽⍨⍺+@(?⊂⌊⍵÷2)?⍵⍴⍺]},⍨
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT9dNzkksLs5M/v@ob2pm/qO2CQb/04CkkVm1BlAkUedR765HvVuAzBTN6Ec9HY86ZjzqmvaodwWU3bMXxO7dpe2gYf@oq@lRT9ej3q2Htxtp2gNpkMbeXbG1QENW/P@fpmABAA "APL (Dyalog Classic) – Try It Online")
uses `⌈` (max) of the matrix with its reflections to make it symmetric, so it's biased towards the latter part of the alphabet
the digit is chosen uniformly from 0...25 mod 10, so it has a small bias to lower values
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 31 bytes (Fixed digit position)
```
;
/2 c
VÆVÆBö}ÃgT0@Mq9Ã®êUvÃêUv
```
[Try it online!](https://tio.run/##y0osKPn/35pL30ghmSvscBsQOR3eVnu4OT3EwMG30PJw86F1h1eFlh1uBpH//1so6AYBAA "Japt – Try It Online")
---
# [Japt](https://github.com/ETHproductions/japt), 41 bytes (Random digit position)
```
;
/2 c
VÆVÆBö}ÃgMq´VÉ ,MqVÉ @Mq9Ã®êUvÃêUv
```
[Try it online!](https://tio.run/##y0osKPn/35pL30ghmSvscBsQOR3eVnu4Od238NCWsMOdCjq@hSDKwbfQ8nDzoXWHV4WWHW4Gkf//WyjoBgEA "Japt – Try It Online")
---
**Explanation**
```
;                               Change to new vars
/2 c                            set implicit var V equal to implicit var U / 2 rounded up
VÆVÆBö}ÃgT0@Mq9Ã®êUvÃêUv        Main function
VÆ                              Range from 0 to V and map
  VÆ                            Range from 0 to V and map
    Bö}Ã                        return random char from alphabet
        gT0@                    map upper-left corner
            Mq9Ã                return random number
                ®êUv            horizontal mirror
                    êUv         vertical mirror
```
[Answer]
# [Python 2](https://docs.python.org/2/), 259 bytes
```
from random import*
n=input();c=choice;r=range
w,W=n/2,-~n/2
o=n%2
A=map(chr,r(97,123))
l=[c(r(10))]+sample(A,n)+[c(A)for _ in' '*w*w]
l,e=l[:w*w],l[w*w:W*W]
shuffle(l)
l=[l[w*i:w*-~i]+e[i:i+1]for i in range(w)]+[e[-W:]]
for r in l+l[~o::-1]:print r+r[~o::-1]
```
[Try it online!](https://tio.run/##NU4xbsQgEOx5BU10YLASO8XpOFH4FS4QiiyC45UwoD2frDT@ugMnpdlZzczObP7dlhT785wxrRSn@F0A1pxwa0jUEPNzY/zutFsSOH9HXTw/nuxy1PG9l@1RJkk6vvVk0OuUmVtQIrtdZdd/ck6CNo4h6z44t@IxrTl4NsjIRaEHPiekXxTihV6avdktCdLrYFTdZTAF1NiMljyW5zyXy/AKrAIUT3uAFd6AAtHZGgUlir4eZHupM960o7KWVA2rFkQwR1Kq7azKCHGjKPCfOc/rHw "Python 2 – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~29~~ ~~40~~ 38 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Commands)
```
A.rs;ò©n∍9ÝΩ®DnαLʒ®%Ā}<Ωǝ®ô»¹Éi.º.∊ëº∊
```
+11 bytes to fix the digit being at a random position while still keeping rule 3 in mind for odd inputs..  
-2 bytes thanks to *@MagicOctopusUrn*, changing `îï` to `ò` and changing the position of the `»`.
[Try it online](https://tio.run/##AUoAtf9vc2FiaWX//0EucnM7w7LCqW7iiI05w53OqcKuRG7OsUzKksKuJcSAfTzOqcedwq7DtMK7wrnDiWkuwrou4oiKw6vCuuKIiv//Nw) of [verify some more test cases](https://tio.run/##AVsApP9vc2FiaWX/MjVMw4x2eSc6wqssef9BLnJzO8Oywqlu4oiNOcOdzqnCrkRuzrFMypLCriXEgH08zqnHncKuw7TCu3nDiWkuwrou4oiKw6vCuuKIiv99LMK2P/83).
Old (**~~29~~ 27 bytes**) answer where the digit positions where always in the corners:
```
A.rs;ò©n∍¦9ÝΩì®ô»¹Éi.º.∊ëº∊
```
[Try it online](https://tio.run/##AToAxf9vc2FiaWX//0EucnM7w7LCqW7iiI3CpjnDnc6pw6zCrsO0wrvCucOJaS7Cui7iiIrDq8K64oiK//83) or [verify some more test cases](https://tio.run/##AUoAtf9vc2FiaWX/MjVMw4x2eSc6wqssef9BLnJzO8Oywqlu4oiNwqY5w53OqcOswq7DtMK7ecOJaS7Cui7iiIrDq8K64oiK/30swrY//w).
**Explanation:**
```
A           # Take the lowercase alphabet
 .r         # Randomly shuffle it
            #  i.e. "abcdefghijklmnopqrstuvwxyz" → "uovqxrcijfgyzlbpmhatnkwsed"
s           # Swap so the (implicit) input is at the top of the stack
 ;          # Halve the input
            #  i.e. 7 → 3.5
  ò         # Bankers rounding to the nearest integer
            #  i.e. 3.5 → 4
   ©        # And save this number in the register
    n       # Take its square
            #  i.e. 4 → 16
     ∍      # Shorten the shuffled alphabet to that length
            #  i.e. "uovqxrcijfgyzlbpmhatnkwsed" and 16 → "uovqxrcijfgyzlbp"
9ÝΩ         # Take a random digit in the range [0,9]
            #  i.e. 3
   ®Dnα     # Take the difference between the saved number and its square:
            #  i.e. 4 and 16 → 12
       L    # Create a list in the range [1,n]
            #  i.e. 12 → [1,2,3,4,5,6,7,8,9,10,11,12]
ʒ   }       # Filter this list by:
 ®%Ā        #  Remove any number that's divisible by the number we've saved
            #   i.e. [1,2,3,4,5,6,7,8,9,10,11,12] and 4 → [1,2,3,5,6,7,9,10,11]
     <      # Decrease each by 1 (to make it 0-indexed)
            #  i.e. [1,2,3,5,6,7,9,10,11] → [0,1,2,3,5,6,7,9,10]
      Ω     # Take a random item from this list
            #  i.e. [0,1,2,3,5,6,7,9,10] → 6
       ǝ    # Replace the character at this (0-indexed) position with the digit
            #  i.e. "uovqxrcijfgyzlbp" and 3 and 6 → "uovqxr3ijfgyzlbp"
®ô          # Split the string into parts of length equal to the number we've saved
            #  i.e. "uovqxr3ijfgyzlbp" and 4 → ["uovq","xr3i","jfgy","zlbp"]
  »         # Join them by new-lines (this is done implicitly in the legacy version)
            #  i.e. ["uovq","xr3i","jfgy","zlbp"] → "uovq\nxr3i\njfgy\nzlbp"
   ¹Éi      # If the input is odd:
            #  i.e. 7 → 1 (truthy)
      .º    # Intersect mirror the individual items
            #  i.e. "uovq\nxr3i\njfgy\nzlbp"
            #   → "uovqvou\nxr3i3rx\njfgygfj\nzlbpblz"
        .∊  # And intersect vertically mirror the whole thing
            #  i.e. "uovqvou\nxr3i3rx\njfgygfj\nzlbpblz"
            #   → "uovqvou\nxr3i3rx\njfgygfj\nzlbpblz\njfgygfj\nxr3i3rx\nuovqvou"
  ë         # Else (input was even):
   º∊       #  Do the same, but with non-intersecting mirrors
```
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~198~~ ~~197~~ 196 bytes
Saved 2 bytes thanks to ceilingcat.
```
#define A(x)(x<n/2?x:n-1-x)
#define R rand()
S(n,x,y){int s[x=n*n];for(srand(s),y=R;x;)s[x]=97+(--x*31+y)%71%26;y=n/2;for(s[R%y+n*(R%y)]=48+R%10;x<n*n;++x%n||puts(""))putchar(s[A(x%n)+A(x/n)*n]);}
```
[Try it online!](https://tio.run/##NU7LCsIwELz3K0olsNs01FbxFYP4C@1Reijx1YOr2Aob1G@vqeJpZpgZZqw6Wdv3o/3h2NAh3AIj8JrSfMMrUpliDP5eEd5r2gMGJVDCicNnQ13Y7thQTJU@Xu/QfhMtJs4UmjV6szLLuQSlOJ5k0qGYZyKfaWf8xK@yK4STFIMHrMx0IQuRjbX/EJOWkgW9XrdH10IUIXpiz/VQ8kcFofSQEvp51O/@UjcE@Cwhnw3yAw "C (gcc) – Try It Online")
Explanation:
```
// Coordinate conversion for symmetry
#define A (x) (x < n / 2 ? x : n - 1 - x)
// Get a random and seed
#define R rand()
S (n, x, y)
{
   // the array to store matrix values (x is the array size)
   // Note that we do not need the whole array, only its first quarter
   int s[x = n * n];
   // iterate n*n-1 times until x is zero
   for (srand(s), y = R; x;)
       // and fill the array with pseudo-random sequence of letters
       s[x] = 97 + (--x * 31 + y) % 71 % 26;
   // this is the max. coordinate of the matrix element where a digit may occur
   y = n / 2;
   // drop a random digit there
   s[R % y + n * (R % y)] = 48 + R % 10;
   // Now we output the result. Note that x is zero here
   for (; 
       x < n * n; // iterate n*n times
       ++x % n || puts ("") // on each step increase x and output newline if needed
       )
       // output the character from the array
       putchar (s[A (x % n) + A (x / n) * n]);
}
```
[Answer]
# JavaScript (ES6), ~~213~~ ~~209~~ 206 bytes
```
n=>(a=[],F=(x=y=d=c=0,R=k=>Math.random()*k|0,g=y=>(r=a[y]=a[y]||[])[x]=r[n+~x]=v.toString(36))=>y<n/2?F(g(y,R[v=R(m=~-n/2)<!d&x<m&y<m?R(d=10):R(26)+10]=R[v]||++c,g(n+~y))&&++x<n/2?x:+!++y,R):!d|c<n?F():a)()
```
[Try it online!](https://tio.run/##LYxPb4JAEEfvforxAjMdpKiJB8rgzVt7oEfKYQNC/cOuWYmBlPrV6Wp6mffL5OUd1U1dS3u4dAttqv1Uy6QlRSV5EewEexmkklKiIJOTpO@q@w6t0pVpkV5OYxQ0TkjRisqH4nnGMS8o7wuxuea74y3szGdnD7rB9YZI0iHRr6vtDhscgiy/SYat3BfuR8m88vqk9Yak3WZYyTKiOMPVhngZFeJcV2cugwZdeiDyPOb@WetjnjO7HsXzaiwT7foUK0KaamNRg8D6DTQksIwcmQl@ZgCl0Vdz3odn06D/4SQf2FkMfvylH7tGTWGrLmhBUrDh0Rw0@uAT/U@n0cN/cPY7/QE "JavaScript (Node.js) – Try It Online")
### Commented
```
n => (                             // n = input
  a = [],                          // a[][] = output matrix
  F = (                            // F = main recursive function taking:
    x = y =                        //   (x, y) = current coordinates
    d = c = 0,                     //   d = digit flag; c = distinct character counter
    R = k =>                       //   R() = helper function to get a random value in [0,k[
      Math.random() * k | 0,       //         also used to store characters
    g = y =>                       //   g() = helper function to update the matrix
      (r = a[y] = a[y] || [])[x]   //         with horizontal symmetry
      = r[n + ~x] = v.toString(36) //         using the base-36 representation of v
  ) =>                             //
    y < n / 2 ?                    // if we haven't reached the middle row(s) of the matrix:
      F(                           //   do a recursive call to F():
        g(                         //     invoke g() ...
          y,                       //       ... on the current row
          R[v =                    //       compute v = next value to be inserted
            R(m = ~-n/2) < !d &    //       we may insert a digit if no digit has been
            x < m &                //       inserted so far and the current coordinates are
            y < m ?                //       compatible: 2 distinct rows / 2 distinct columns
              R(d = 10)            //         if so, pick v in [0, 9] and update d
            :                      //       else:
              R(26) + 10           //         pick v in [10, 35] for a letter
          ] = R[v] || ++c,         //       set this character as used; update c accordingly
          g(n + ~y)                //       invoke g() on the mirror row
        ) &&                       //     end of outer call to g()
        ++x < n / 2 ?              //     if we haven't reached the middle column(s):
          x                        //       use x + 1
        :                          //     else
          +!++y,                   //       increment y and reset x to 0
        R                          //     explicitly pass R, as it is used for storage
      )                            //   end of recursive call to F()
    :                              // else:
      !d | c < n ? F() : a         //   either return the matrix or try again if it's invalid
)()                                // initial call to F()
```
[Answer]
# [Clean](https://github.com/Ourous/curated-clean-linux), ~~346~~ 312 bytes
*will golf more tomorrow*
```
import StdEnv,Data.List,Math.Random,System.Time,System._Unsafe
$n#q=twice(transpose o\q=zipWith((++)o reverse o drop(n-n/2*2))q q)[[(['a'..'z']++['0'..'9'])!!(c rem 36)\\c<-genRandInt(toInt(accUnsafe(time)))]%(i*n/2,i*n/2+(n-1)/2)\\i<-[1..(n+1)/2]]
|length(nub(flatten q))>=n&&sum[1\\c<-q|any isDigit c]==2=q= $n
```
[Try it online!](https://tio.run/##PY7RT8IwEMbf@StKQNYyNmRGExPqEz6QYGJE48NYTCndaLJe2XpgIPztzg6iL5fv7rvv7idLJaAxdrMvFTFCQ6PNztZIlrh5hsNoJlDEC@1w9CJwG78J2FgzWh4dKhO/a6P@9NcHOJGrTh96FcdvLRXFWoDbWaeIXVX8pHefGreUhiGzpFYHVbcO2dR2RyGCcTJMGKtIxdKUpoEI4jg4BVkYpsFtqx@DjHW7VPqoIXcPbLWS06hQ0CLNASnatgopryAUPRxjLLuheuiPjy419J8mbJz4tJ5G6SSOKYTtIMs651JB4QFhv6Z5KRAVeBj2xGEwcHuTTi4fq7OAI9FupguNRGacJ7zipA/NEkWNnR5x@qQIJ/de5nuQqC34tt/hpL1aalCO0H@n3WbNj/Re4ZpovmhmRxBGy2vz6iO5rU0TrX8B "Clean – Try It Online")
[Answer]
# [Python 3](https://docs.python.org/3/), 197 bytes
**As mentioned by @Emigna, doesn't work for odd values of `N` (I didn't understand the question properly)**
```
from random import*
def m(N):M=N//2;E=reversed;R=range;B=[randint(48,57),*(sample(R(97,123),N)*N)][:M*M];shuffle(B);r=R(M);m=[k+[*E(k)]for k in[[chr(B.pop())for i in r]for j in r]];m+=E(m);return m
```
[Try it online!](https://tio.run/##XU9Nb4MgGL7zK94jWLKuH1s7CRcTj3rwSjw0EydVkIAu2a93FG2WjAvwfOV57M/Ujea0LK0bNbibacKltB3dlKBGtqBxSdKCl/v9keXcyW/pvGxYxYP2S7KMi4dJmQmfr/TtQmiC/U3bQeIKf1zo4XgitCRJSWqRFklRM9/NbRvojDDHK1wQprnodyLJcU/qdnTQgzJCfHYOZy92tJiQB6oCCi4K7uuzZnrHc6xDkJxmZ0AvCMUd1rrQaNux/QL1TDlTeKdwpXB4TRGE46Sfhwl4WKtIRG7ey2AdpMErSYBzUJH7qxCZNeKf6b7pI7cWeAYhtPwC "Python 3 – Try It Online")
I do think the calls to `randint()` + `sample()` + `shuffle()` are too much, and getting rid of in-place shuffling would be great :)
I'm pretty sure this part (that selects the letters & digit) could be golfed a bit more.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~275~~ 266 bytes
```
from random import*
def f(n):
 R=range;C=choice;A=map(chr,R(97,123));b=N=n-n/2;c=`C(R(10))`;s=[c]+sample(A,n-1)+[C(A)for i in R(N*N-n)]
 while b:shuffle(s);i=s.index(c);b=n%2>(i<N*N-N>N-1>i%N)
 a=[r+r[~(n%2)::-1]for r in[s[i::N]for i in R(N)]];return a+a[~(n%2)::-1]
```
[Try it online!](https://tio.run/##TZDBboMwEETP5St8ifAGkxbSKqpdI0W5@8DVtRRCTHEVFmSI2l766xSrrZTTjjRvdqQZvqa2x3yeG993xFd4Xo7rht5P6@hsG9JQBB6RUi7emxUHWbe9q63Yy64aaN16VtLnHcvyLYA4SSUxxftc1PJ4oCXNHgCOYpS6NslYdcPF0j3DNINEH@gemt4TRxySkqq1ShFMRD5ad7HkxMf22jQLP4Jwctw4PNtPWocOXOUFdS8hoQqVZoVbKYhIJbVPvP6miw@cp5kJ75cC1KN2nCtzWwfGCG@nq0dSJdVtag4YBkxv2SN7YvnO8Ohu8A4ngv8ifsV48947pGGH@FezsBbAHzPPPw "Python 2 – Try It Online")
Returns the array as a list of lists of characters. To satisfy Rule 1, we set up a pool of characters:
```
s = [c]                        # the unique digit...
     + sample(A,n-1)           # then sample without replacement `n-1` chars in a-z, 
                               # so we have `n` distinct chars
     + [C(A)for i in R(N*N-n)] # and fill out the rest with any in a-z
```
The next tricky bit is rule 3: there must be *exactly 2* columns and rows having a digit; this means for `n` odd, that the chosen digit may not appear in the middle column or middle row. Since we construct the array using a twice reflected square sub array `s`, that is accomplished here by using:
```
while b:            # to save a couple bytes, `b` is initialized 
                    # to `N`, which is greater than 0.
    shuffle(s)      # shuffle at least once...
    i = s.index(c)  # c is the unique digit used
    b = n%2 
             >      # if n is even, 0>(any boolean) will be false,
                    # so exit the loop; otherwise n odd, and we are
                    # evaluating '1 > some boolean', which is equivalent 
                    # to 'not (some boolean)'
         (i<N*N-N   # i is not the last column of s...
             >      # shortcut for ' and ', since N*N-N is always > N-1
          N-1>i%N)  # is not the last row of s
```
i.e., shuffle at least once; and then, if `n` is odd, keep looping if the digit is in the last column or the last row of `s`.
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 48 bytes
```
L+b_<b/Q2JmO/Q2 2jy.eyXWqhJkbeJOT<csm.SGQK.EcQ2K
```
Try it out online [here](https://pyth.herokuapp.com/?code=L%2Bb_%3Cb%2FQ2JmO%2FQ2%202jy.eyXWqhJkbeJOT%3Ccsm.SGQK.EcQ2K&input=8&debug=0).
The program is in 3 parts - definition of palindromisation function, choosing location of numeric, and main function.
```
Implicit: Q=eval(input()), T=10, G=lower case alphabet
L+b_<b/Q2   Palindromisation function
L           Define a function, y(b)
      /Q2   Half input number, rounding down
    <b      Take that many elements from the start of the sequence
   _        Reverse them
 +b         Prepend the unaltered sequence
JmO/Q2 2   Choose numeric location
  O/Q2     Choose a random number between 0 and half input number
 m     2   Do the above twice, wrap in array
J          Assign to variable J
jy.eyXWqhJkbeJOT<csm.SGQK.EcQ2K   Main function
                           cQ2    Divide input number by 2
                         .E       Round up
                        K         Assign the above to K
                    .SG           Shuffle the alphabet
                  sm   Q          Do the above Q times, concatenate
                 c      K         Chop the above into segments of length K
                <             K   Take the first K of the above
  .e                              Map (element, index) as (b,k) using:
       qhJk                         Does k equal first element of J?
      W                             If so...
     X     b                          Replace in b...
            eJ                        ...at position <last element of J>...
              OT                      ...a random int less than 10
                                    Otherwise, b without replacement
    y                               Apply palindromisation to the result of the above
 y                                Palindromise the set of lines
j                                 Join on newlines, implicit print
```
Using several shuffled alphabets should ensure that the number of unique characters is always more then the input number.
[Answer]
# **Python 2/Python 3, 227 bytes**
```
from random import*
def m(N):n=N-N//2;r=range;C=choice;c=n*[chr(i+97)for i in r(26)];shuffle(c);c[C([i for i in r(n*(N-n))if(i+1)%n+1-N%2])]=`C(r(10))`;R=[c[i*n:i*n+n]+c[i*n:i*n+n-N%2][::-1]for i in r(n)];return R+R[::-1][N%2:]
```
ungolfing a bit:
```
from random import * # get 'choice' and 'shuffle'
def matrix(N):
    n = ceil(N/2) # get the size of the base block
    # get a shuffleable lowercase alphabet
    c = [chr(i+97)for i in range(26)]
    c = n*c # make it large enough to fill the base-block
    shuffle(c) # randomize it
    digit = choice('1234567890') # get random digit string
    ## this is only needed as to prevent uneven side-length matrices
    #  from having centerline digits.
    allowed_indices = [i for i in range( # get all allowed indices
        n*(N-n)) # skip those, that are in an unmirrored center-line
        if(i+1)%n  # only use those that are not in the center column
                 +1-N%2] # exept if there is no center column
    index = choice(allowed_indices) # get random index
    c[index]=digit # replace one field at random with a random digit
    ## 
    R=[]
    for i in range(n):
        r = c[i*n:i*n+n] # chop to chunks sized fit for the base block
        R.append(r+r[::-1][N%2:]) # mirror skipping the center line
    return R+R[::-1][N%2:] # mirror skipping the center line and return
```
Older, *almost* correct versions below:
**Python2, Python3, 161 bytes**
```
from random import *
N=26
n=N-N//2
c=[chr(i+97)for i in range(26)]
R=[ r+r[::-1][N%2:]for r in[(shuffle(c),c[:n])[1]for i in range(n)]]
R+=R[::-1][N%2:]
print(R)
```
It seems N differing elements is only *almost* guarranteed.
**Python 2/Python 3, 170 bytes**
```
from random import*
def m(N):n=N-N//2;r=range;c=n*[chr(i+97)for i in r(26)][:n*n];shuffle(c);R=[_+_[::-1][N%2:]for _ in[c[i*n:i*n+n]for i in r(n)]];return R+R[::-1][N%2:]
```
It seems I forgot rule 3. Also somehow the [:n\*n] slipped in.
]