#include <iostream>
#include "vision.h"
using namespace std;

void shift(vector <int>& v) {
    v.push_back(v.front());
    v.erase(v.begin());
}

vector <int> operator<<(vector <int> v, int b) {
    while (b--) {
        shift(v);
    }
    
    return v;
}

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

int getMove1d(std::vector<int> v) {
    int vision = (int) v.size() / 2;

    if (v[vision] == 1) {
        if (v[vision - 1] != 1) return vision - 1;
        return vision + 1;
    }

    if (v[vision] == 2) {
        int mx = 0;
    
        for (int i = 0; i < v.size(); i++) {
            if (i == vision) continue;
            mx = max(mx, v[i]);
        }
    
        for (int i = 0; i < v.size(); i++) {
            if (i == vision) continue;
            if (mx == v[i]) return i;
        }
    }

    if (v[vision + 2] == 2) return vision - 3;
    return vision + 3;
}

std::vector<std::vector<int>> getVisionPattern2d() {
    vector <vector <int>> v(24, vector <int> (24, 1));

    for (int i = 0; i < 24; i += 3) {
        v[i][(i + 24 - 0) % 24] = 3;
        v[i][(i + 24 - 3) % 24] = 3;
        v[i][(i + 24 - 6) % 24] = 3;
        v[i][(i + 24 - 9) % 24] = 6;
        v[i][(i + 24 - 12) % 24] = 3;
        v[i][(i + 24 - 15) % 24] = 6;
        v[i][(i + 24 - 18) % 24] = 3;
        v[i][(i + 24 - 21) % 24] = 9;
    }

    return v;
}

int get_x(std::vector<std::vector<int>> v) {
    int vision = (int) v.size() / 2;

    if (v[vision][vision] == 3) {
        if (v[vision - 3][vision] != 3) return vision - 3;
        return vision + 3;
    }

    if (v[vision][vision] == 6) {
        int mx = 0;
    
        for (int i = 0; i < v.size(); i += 3) {
            if (i == vision) continue;
            mx = max(mx, v[i][vision]);
        }
    
        for (int i = 0; i < v.size(); i += 3) {
            if (i == vision) continue;
            if (mx == v[i][vision]) return i;
        }
    }

    if (v[vision + 6][vision] == 6) return vision - 9;
    return vision + 9;
}

int get_y(std::vector<std::vector<int>> v) {
    int vision = (int) v.size() / 2;

    if (v[vision][vision] == 3) {
        if (v[vision][vision - 3] != 3) return vision - 3;
        return vision + 3;
    }

    if (v[vision][vision] == 6) {
        int mx = 0;
    
        for (int i = 0; i < v.size(); i += 3) {
            if (i == vision) continue;
            mx = max(mx, v[vision][i]);
        }
    
        for (int i = 0; i < v.size(); i += 3) {
            if (i == vision) continue;
            if (mx == v[vision][i]) return i;
        }
    }

    if (v[vision][vision + 6] == 6) return vision - 9;
    return vision + 9;
}

std::pair<int, int> getMove2d(std::vector<std::vector<int>> v) {
    int vision = (int) v.size() / 2;

    if (v[vision][vision] == 1) {
        if (v[vision - 1][vision] != 1) return {vision - 1, vision};
        if (v[vision + 1][vision] != 1) return {vision + 1, vision};
        if (v[vision][vision - 1] != 1) return {vision, vision - 1};
        return {vision, vision + 1};
    }

    return {get_x(v), get_y(v)};
}