#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#include "vision.h"

#define debug(x) #x << " = " << x << '\n'
using ll = long long;

const int dx[4] = {-1, 0, +1, 0};
const int dy[4] = {0, -1, 0, +1};

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

int getMove1d(std::vector<int> v)
{
    int len = (int) v.size();
    int mid = len / 2;
    int me = v[len / 2];
    // 1 1 2 1 3 1 1 1 2 1 3 1 1 1 2 1 3 1 1 1 2 1 3 1 
    if (me == 1) {  
        // I. 2 si 3 => ma duc in 3
        // II. 1 si 2 => ma duc in 2
        // III. 1 si 3 => ma duc in 1
        // IV. 1 si 1 => ma duc in 1

        int mini = std::min(v[mid - 1], v[mid + 1]);
        int maxi = std::max(v[mid - 1], v[mid + 1]);
        if (mini == 1 && maxi == 3) {
            if (v[mid - 1] == 1) {
                return mid - 1;
            } else {
                return mid + 1;
            }
        }
        if (mini == 2 && maxi == 3) {
            if (v[mid - 1] == 3) {
                return mid - 1;
            } else {
                return mid + 1;
            }
        }
        if (mini == 1 && maxi == 2) {
            if (v[mid - 1] == 2) {
                return mid - 1;
            } else {
                return mid + 1;
            }
        }
        if (mini == 1 && maxi == 1) {
            return mid - 1;
        }
        assert(false);
    }
    if (me == 2) {
        // daca sunt 2 => ma duc in 3
        for (int i = 0; i < len; i++) {
            if (v[i] == 3) {
                return i;
            }
        }
        assert(false);
    }
    if (me == 3) {
        // ma duc in 1 le din directia in care nu am 1
        if (v[1] == 2) {
            return len - 1;
        } else {
            assert(v[len - 2] == 2);
            return 0;
        }
    }

    assert(false);
}

std::vector<std::vector<int>> getVisionPattern2d()
{

    return {{1, 1, 1, 1, 1, 1},
            {1, 3, 2, 1, 3, 1},
            {1, 1, 1, 1, 2, 1},
            {1, 1, 1, 1, 1, 1},
            {1, 3, 1, 1, 3, 2},
            {1, 2, 1, 1, 1, 1}};
}

std::pair<int, int> getMove2d(std::vector<std::vector<int>> v)
{
    int len = (int) v.size();
    for (int i = 0; i < len; i++) {
        assert((int) v[i].size() == len);
    }
    int me = v[len / 2][len / 2];
    if (me == 1) {
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < len; j++) {
                if (v[i][j] > 1) {
                    return {i, j};
                }
            }
        }
        assert(false);
    } 
    if (me == 2) {
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < len; j++) {
                if (v[i][j] == 3) {
                    return {i, j};
                }
            }
        }
        assert(false);
    } 

    // acum am me == 3 si me == 4
    int direction = -1;
    for (int dir = 0; dir < 4; dir++) {
        int x = len / 2 + dx[dir], y = len / 2 + dy[dir];
        if (v[x][y] == 2) {
            direction = dir;
            break;
        }  
    }

    assert(direction != -1);

    int x = len / 2 + 3 * dx[direction], y = len / 2 + 3 * dy[direction];
    assert(0 <= x && x < len && 0 <= y && y < len);
    assert(v[x][y] == 3);
    return {x, y};
}
