<p>A robot on an infinite XY-plane starts at point <code>(0, 0)</code> facing north. The robot receives an array of integers <code>commands</code>, which represents a sequence of moves that it needs to execute. There are only three possible types of instructions the robot can receive:</p>

<ul>
	<li><code>-2</code>: Turn left <code>90</code> degrees.</li>
	<li><code>-1</code>: Turn right <code>90</code> degrees.</li>
	<li><code>1 &lt;= k &lt;= 9</code>: Move forward <code>k</code> units, one unit at a time.</li>
</ul>

<p>Some of the grid squares are <code>obstacles</code>. The <code>i<sup>th</sup></code> obstacle is at grid point <code>obstacles[i] = (x<sub>i</sub>, y<sub>i</sub>)</code>. If the robot runs into an obstacle, it will stay in its current location (on the block adjacent to the obstacle) and move onto the next command.</p>

<p>Return the <strong>maximum squared Euclidean distance</strong> that the robot reaches at any point in its path (i.e. if the distance is <code>5</code>, return <code>25</code>).</p>

<p><strong>Note:</strong></p>

<ul>
	<li>There can be an obstacle at <code>(0, 0)</code>. If this happens, the robot will ignore the obstacle until it has moved off the origin. However, it will be unable to return to <code>(0, 0)</code> due to the obstacle.</li>
	<li>North means +Y direction.</li>
	<li>East means +X direction.</li>
	<li>South means -Y direction.</li>
	<li>West means -X direction.</li>
</ul>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">commands = [4,-1,3], obstacles = []</span></p>

<p><strong>Output:</strong> <span class="example-io">25</span></p>

<p><strong>Explanation: </strong></p>

<p>The robot starts at <code>(0, 0)</code>:</p>

<ol>
	<li>Move north 4 units to <code>(0, 4)</code>.</li>
	<li>Turn right.</li>
	<li>Move east 3 units to <code>(3, 4)</code>.</li>
</ol>

<p>The furthest point the robot ever gets from the origin is <code>(3, 4)</code>, which squared is <code>3<sup>2</sup> + 4<sup>2 </sup>= 25</code> units away.</p>
</div>

<p><strong class="example">Example 2:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">commands = [4,-1,4,-2,4], obstacles = [[2,4]]</span></p>

<p><strong>Output:</strong> <span class="example-io">65</span></p>

<p><strong>Explanation:</strong></p>

<p>The robot starts at <code>(0, 0)</code>:</p>

<ol>
	<li>Move north 4 units to <code>(0, 4)</code>.</li>
	<li>Turn right.</li>
	<li>Move east 1 unit and get blocked by the obstacle at <code>(2, 4)</code>, robot is at <code>(1, 4)</code>.</li>
	<li>Turn left.</li>
	<li>Move north 4 units to <code>(1, 8)</code>.</li>
</ol>

<p>The furthest point the robot ever gets from the origin is <code>(1, 8)</code>, which squared is <code>1<sup>2</sup> + 8<sup>2</sup> = 65</code> units away.</p>
</div>

<p><strong class="example">Example 3:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">commands = [6,-1,-1,6], obstacles = [[0,0]]</span></p>

<p><strong>Output:</strong> <span class="example-io">36</span></p>

<p><strong>Explanation:</strong></p>

<p>The robot starts at <code>(0, 0)</code>:</p>

<ol>
	<li>Move north 6 units to <code>(0, 6)</code>.</li>
	<li>Turn right.</li>
	<li>Turn right.</li>
	<li>Move south 5 units and get blocked by the obstacle at <code>(0,0)</code>, robot is at <code>(0, 1)</code>.</li>
</ol>

<p>The furthest point the robot ever gets from the origin is <code>(0, 6)</code>, which squared is <code>6<sup>2</sup> = 36</code> units away.</p>
</div>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= commands.length &lt;= 10<sup>4</sup></code></li>
	<li><code>commands[i]</code> is either <code>-2</code>, <code>-1</code>, or an integer in the range <code>[1, 9]</code>.</li>
	<li><code>0 &lt;= obstacles.length &lt;= 10<sup>4</sup></code></li>
	<li><code>-3 * 10<sup>4</sup> &lt;= x<sub>i</sub>, y<sub>i</sub> &lt;= 3 * 10<sup>4</sup></code></li>
	<li>The answer is guaranteed to be less than <code>2<sup>31</sup></code>.</li>
</ul>

class Solution {
public:

    void help_dir(vector<int> &dir, int var){
        
        if(var == -1){

            if(dir[0] == 0 && dir[1] == 1){
                dir = {1, 0};
            }
            else if(dir[0] == 0 && dir[1] == -1){
                dir = {-1, 0};
            }
            else if(dir[0] == 1 && dir[1] == 0){
                dir = {0, -1};
            }
            else if(dir[0] == -1 && dir[1] == 0){
                dir = {0, 1};
            }
            
        }

        else if(var == -2){

            if(dir[0] == 0 && dir[1] == 1){
                dir = {-1, 0};
            }
            else if(dir[0] == 0 && dir[1] == -1){
                dir = {1, 0};
            }
            else if(dir[0] == 1 && dir[1] == 0){
                dir = {0, 1};
            }
            else if(dir[0] == -1 && dir[1] == 0){
                dir = {0, -1};
            }
        }
    }

    // void help_obs(vector<int> &pred_pos, vector<int> &pos, map<int, set<int>> &mp_x, map<int, set<int>> &mp_y){

    //     if(pos[0] == pred_pos[0]){

    //         if(mp_x.find(pos[0]) != mp_x.end()){

    //             for(auto elem : mp_x[pos[0]]){

    //                 if(elem > pos[1] && elem < pred_pos[1]){
    //                     pos[1] = elem - 1;
    //                 }
    //             }
    //         }
    //         else{

    //             pos[1] = pred_pos[1];
    //         }
    //     }

    //     else if(pos[1] == pred_pos[1]){

    //         if(mp_y.find(pos[1]) != mp_y.end()){

    //             for(auto elem : mp_y[pos[1]]){

    //                 if(elem > pos[0] && elem < pred_pos[0]){
    //                     pos[0] = elem - 1;
    //                 }
    //             }
    //         }else{

    //             pos[0] = pred_pos[0];
    //         }
    //     }
    // }
    void help_obs(vector<int> &pred_pos, vector<int> &pos, map<int, set<int>> &mp_x, map<int, set<int>> &mp_y, vector<int> &dir){

    if(pos[0] == pred_pos[0]){ // Moving vertically

        if(mp_x.find(pos[0]) != mp_x.end()){ // If there are obstacles on this x-coordinate

            for(auto elem : mp_x[pos[0]]){

                // Obstacle in the direction of movement (upwards)
                if(dir[1] == 1 && elem > pos[1] && elem <= pred_pos[1]){
                    pos[1] = elem - 1;
                    return; // Stop moving as obstacle blocks the path
                }

                // Obstacle in the direction of movement (downwards)
                if(dir[1] == -1 && elem < pos[1] && elem >= pred_pos[1]){
                    pos[1] = elem + 1;
                    return; // Stop moving as obstacle blocks the path
                }
            }

            // No blocking obstacle in the path
            pos[1] = pred_pos[1];
        } else {
            pos[1] = pred_pos[1];
        }
    }

    else if(pos[1] == pred_pos[1]){ // Moving horizontally

        if(mp_y.find(pos[1]) != mp_y.end()){ // If there are obstacles on this y-coordinate

            for(auto elem : mp_y[pos[1]]){

                // Obstacle in the direction of movement (right)
                if(dir[0] == 1 && elem > pos[0] && elem <= pred_pos[0]){
                    pos[0] = elem - 1;
                    return; // Stop moving as obstacle blocks the path
                }

                // Obstacle in the direction of movement (left)
                if(dir[0] == -1 && elem < pos[0] && elem >= pred_pos[0]){
                    pos[0] = elem + 1;
                    return; // Stop moving as obstacle blocks the path
                }
            }

            // No blocking obstacle in the path
            pos[0] = pred_pos[0];
        } else {
            pos[0] = pred_pos[0];
        }
    }
}

    int robotSim(vector<int>& commands, vector<vector<int>>& obstacles) {

        map<int, set<int>>mp_x, mp_y;

        for(int i = 0; i < obstacles.size(); i++){
            mp_x[obstacles[i][0]].insert(obstacles[i][1]);
            mp_y[obstacles[i][1]].insert(obstacles[i][0]);
        }

        vector<int>pos = {0,0};
        vector<int>dir = {0, 1};

        int maxx = INT_MIN;

        for(int i = 0; i < commands.size(); i++){

            if(commands[i] == -1 || commands[i] == -2){
                help_dir(dir, commands[i]);
                continue;
            }
            else{

                vector<int>pred_pos;
                if(dir[0] == 0 && dir[1] == 1){
                    pred_pos = {pos[0], pos[1] + commands[i]};
                   
                }
                else if(dir[0] == 0 && dir[1] == -1){
                    pred_pos = {pos[0], pos[1] - commands[i]};
                }
                else if(dir[0] == 1 && dir[1] == 0){
                   pred_pos = {pos[0] + commands[i], pos[1]};
                }
                else if(dir[0] == -1 && dir[1] == 0){
                   pred_pos = {pos[0] - commands[i], pos[1]};
                }
                help_obs(pred_pos, pos, mp_x, mp_y, dir);
               maxx = max(maxx, pos[0] * pos[0] + pos[1] * pos[1]);
            }
        }

        return maxx;

    }
};
59691