/// G. Hagopian generating a random latin square

#include<iostream>
#include<cstdlib>
#include<ctime>
#include<iomanip>

using namespace std;

class LatinSquare {
    int sz;
    int* Ls = new int[sz*sz];
public:
    LatinSquare(int s) : sz(s) {
        for(int i = 0; i < sz; ++i)
            for(int j = 0; j < sz; ++j)
                Ls[i*sz+j]=((i*sz+j)%sz+i)%sz+1;
    }
    void print() {
        for(int i = 0; i < sz*sz; ++i) {
            cout << setw(3) << Ls[i];
            if((i+1)%sz == 0) cout << endl;
        }
    }
    void shuffleRows() {
        /** Use fisher-yates
        -- To shuffle an array a of n elements (indices 0..n-1):
        for i from n−1 downto 1 do
            j ← random integer such that 0 ≤ j ≤ i
        exchange a[j] and a[i]*/
        int j{0}, temp{0};
        for(int i = sz-1; i > 0; --i) {
            j = rand()%i;
            for(int col = 0; col < sz; col++) {
                /// swap ith row with kth row col by col
                temp = Ls[sz*i+col];
                Ls[sz*i+col] = Ls[sz*j+col];
                Ls[sz*j+col] = temp;
                ///swap(Ls[sz*i+col], Ls[sz*k+col]);
            }
        }
    }
     void shuffleCols() {
        /** Use fisher-yates
        -- To shuffle an array a of n elements (indices 0..n-1):
        for i from n−1 downto 1 do
            j ← random integer such that 0 ≤ j ≤ i
        exchange a[j] and a[i]*/
        int col{0};
        for(int j = sz-1; j > 0; --j) {
            col = rand()%j;
            for(int row = 0; row < sz; row++)
                /// swap ith col with kth col row by row
                swap(Ls[row*sz+col], Ls[]);///figure this out
        }
    }

};

int main() {
    srand(time(0));
    LatinSquare latsq(4);
    latsq.print();
    latsq.shuffleRows();
    latsq.print();
    return 0;
}
