#include "vision.h"
#include <bits/stdc++.h>

using namespace std;

vector<int> getVisionPattern1d()
{
    return {2, 1, 2, 2, 1, 1};
}

int getMove1d(vector<int> v)
{
    int k = v.size() / 2;
    if (k == 1)
    {
        if (v[k + 1] == 2)
            return k + 1;
        else
            return k - 1;
    }
    else if (k == 2)
    {
        vector<int> f1 = {1, 2, 2, 1, 1}, f2 = {1, 1, 2, 2, 1}, f3 = {2, 1, 2, 2, 1}, f4 = {1, 2, 2, 1, 2}, f5 = {1, 1, 2, 1, 2}, f6 = {2, 1, 2, 1, 1};
        if (v == f1)
            return 4;
        else if (v == f2)
            return 0;
        else if (v == f3)
            return 3;
        else if (v == f4)
            return 1;
        else if (v == f5)
            return 4;
        else if (v == f6)
            return 0;
    }
}

struct M///lucrez doar in patratice!!!
{
    vector<vector<int>> mat;

    void sz(int n)
    {
        mat.resize(n);
        for (int i = 0; i < n; i++)
            mat[i].resize(n);
    }
};

bool eq(M m1, M m2)
{
    if (m1.mat.size() != m2.mat.size())
        return false;
    int n = m1.mat.size();
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            if (m1.mat[i][j] != m2.mat[i][j])
                return false;
    return true;
}

M Xflip(M mt)
{
    M doi;
    int n = mt.mat.size();
    doi.sz(n);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            doi.mat[n - 1 - i][j] = mt.mat[i][j];
        }
    }
    return doi;
}

M Yflip(M mt)
{
    M doi;
    int n = mt.mat.size();
    doi.sz(n);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            doi.mat[i][n - 1 - j] = mt.mat[i][j];
        }
    }
    return doi;
}

M XYflip(M mt)
{
    return Xflip(Yflip(mt));
}

int cnt;
map<vector<vector<int>>, pair<int, int>> mp;

vector<vector<int>> nrm(M mt)
{
    vector<vector<int>> ce;
    int n = mt.mat.size();
    ce.resize(n);
    for (int i = 0; i < n; i++)
        ce[i].resize(n);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            ce[i][j] = mt.mat[i][j];
    return ce;
}

void afis(M mt)
{
    /*cout << endl;
    cout << cnt << endl;
    for (int i = 0; i < mt.mat.size(); i++)
    {
        for (int j = 0; j < mt.mat.size(); j++)
        {
            cout << mt.mat[i][j] << ' ';
        }
        cout << endl;
    }
    cout << endl;*/
    vector<vector<int>> kv = nrm(mt);
    if (cnt == 1 or cnt == 5 or cnt == 9)
        mp[kv] = {0, 3};
    else if (cnt == 2 or cnt == 6 or cnt == 10)
        mp[kv] = {4, 3};
    else if (cnt == 3 or cnt == 7 or cnt == 11)
        mp[kv] = {0, 1};
    else if (cnt == 4 or cnt == 8 or cnt == 12)
        mp[kv] = {4, 1};
}

vector<vector<int>> getVisionPattern2d()
{
    vector<int> simple = {2, 1, 2, 2, 1, 1};
    vector<vector<int>> mat;
    mat.resize(12);
    for (int i = 0; i < 12; i++)
    {
        mat[i].resize(12);
        if (i % 2 == 1)
        {
            for (int j = 0; j < 12; j++)
                mat[i][j] = 1;
        }
        else
        {
            int rt = i / 2;
            for (int j = 0; j < 12; j++)
            {
                int x = (rt + j) % 6;
                mat[i][j] = simple[x];
            }
        }
    }
    int linie = 4;
    cnt = 0;
    for (int i = 4; i < 10; i++)
    {
        if (mat[linie][i] == 2)
        {
            vector<vector<int>> hmm(5);
            for (int x = 0; x < 5; x++)
                hmm[x].resize(5);
            for (int x = 0; x < 5; x++)
            {
                for (int y = 0; y < 5; y++)
                {
                    hmm[x][y] = mat[linie - 2 + x][i - 2 + y];
                }
            }
            M mt;
            mt.sz(5);
            for (int x = 0; x < 5; x++)
                for (int y = 0; y < 5; y++)
                    mt.mat[x][y] = hmm[x][y];
            cnt++;
            afis(mt);

            cnt++;
            afis(Xflip(mt));

            cnt++;
            afis(Yflip(mt));

            cnt++;
            afis(XYflip(mt));
        }
    }
    return mat;
}

pair<int, int> getMove2d(vector<vector<int>> v)
{
    int k = v.size() / 2;
    if (k == 1)
    {
        for (int i = 0; i < v.size(); i++)
        {
            for (int j = 0; j < v[i].size(); j++)
            {
                if (v[i][j] == 2)
                    return {i, j};
            }
        }
        return {0, 0};
    }
    else
    {
        return mp[v];
    }
}
