Notice that `' '`(`chr(32)`) becomes `0` after passing `stov()`,we can construct a string with `' '`s and only one `chr(33)` in each half, so
$$\begin{bmatrix}  a_{11}& a_{12} &\dots  & a_{1n}\\  a_{21}& a_{22} &\dots & a_{2n}\\  a_{31}& a_{32} &\dots & a_{3n}\\ \vdots  &  \vdots&  \ddots & \vdots\\  a_{n1}& a_{n2} &\dots & a_{nn}\end{bmatrix}\begin{bmatrix} 0\\ \vdots\\ x_j=1\\ \vdots\\ 0\end{bmatrix}=\begin{bmatrix} a_{1j}\\ a_{2j}\\ a_{3j}\\ \vdots\\ a_{nj}\end{bmatrix}$$
(The latex may be broken here, please refer to the original writeup)
In each query, we can reveal two columns of `A`, so in 10 queries, we can reveal all data in `A`. Then you can just use `A` to encrypt `fakeflag2` and get the flag.
```py#!/usr/local/bin/python3
import numpy as np
n = 20
A = np.matrix([[0 for i in range(n)] for i in range(n)])
def stov(s):    return np.array([ord(c)-32 for c in s])
def vtos(v):    return ''.join([chr(v[0,i]+32) for i in range(n)])
def encrypt(s):    return vtos(np.matmul(A, stov(s))%95)
from pwn import *# context(log_level='debug')
r = remote('lac.tf',31140)# r = process(['python','chall.py'])
r.recvuntil(b'On the hill lies a stone. It reads:\n')r.recvline()r.recvline()r.recvuntil(b'\nA mysterious figure offers you 10 attempts at decoding the stone:')for i in range(10):    r.sendline(b' '*i+b'!'+b' '*(19-i)+b' '*(i+10)+b'!'+b' '*(9-i))    r.recvuntil(b'Incorrect:\n')    r1 = stov(r.recvline().decode().strip('\n'))    r2 = stov(r.recvline().decode().strip('\n'))    for j in range(n):        A[j,i] = r1[j]        A[j,i+10] = r2[j]
r.recvuntil(b"Create a new stone that decodes to the following:\n")fakeflag2 = r.recvline().strip().decode()f3 = encrypt(fakeflag2[:n])f4 = encrypt(fakeflag2[n:])
r.recvuntil(b'Enter the first half: ')r.sendline(f3.encode())r.recvuntil(b'Enter the second half: ')r.sendline(f4.encode())
r.interactive()
# lactf{tHeY_SaiD_l!NaLg_wOuLD_bE_fUN_115}```