<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 {
private:
    pair<int, int> checkObs(set<vector<int>>& obsSet, int x, int y, int dist, int dir) {
        /*
            dir:
            up = 1
            down = 3
            left = 4
            right = 2
        */
        
        // For dir = 1 (Up)
        if (dir == 1) {
            int newY = y + dist;
            for (int i=y+1; i<=y+dist; ++i) {
                if (obsSet.find({x, i}) != obsSet.end()) {
                    newY = i-1;
                    break;
                }
            }
            return {x, newY};
        }

        // For dir = 3 (Down)
        else if (dir == 3) {
            int newY = y - dist;
            for (int i=y-1; i>=y-dist; --i) {
                if (obsSet.find({x, i}) != obsSet.end()) {
                    newY = i+1;
                    break;
                }
            }
            return {x, newY};
        }

        // For dir = 4 (Left)
        else if (dir == 4) {
            int newX = x - dist;
            for (int i=x-1; i>=x-dist; --i) {
                if (obsSet.find({i, y}) != obsSet.end()) {
                    newX = i+1;
                    break;
                }
            }
            return {newX, y};
        }

        // For dir = 2 (Right)
        else {
            int newX = x + dist;
            for (int i=x+1; i<=x+dist; ++i) {
                if (obsSet.find({i, y}) != obsSet.end()) {
                    newX = i-1;
                    break;
                }
            }
            return {newX, y};
        }


    }

public:
    // Solution(){
    //     ios::sync_with_stdio(0);
    //     cin.tie(NULL);
    // }

    int robotSim(vector<int>& commands, vector<vector<int>>& obstacles) {
        int x = 0, y = 0, curr_dir = 1;
        set<vector<int>> obsSet;
        for (const auto v: obstacles) {
            obsSet.insert(v);
        }

        unordered_map<int, pair<int, int>> directions;
        directions[1] = {2, 4};
        directions[2] = {3, 1};
        directions[3] = {4, 2};
        directions[4] = {1, 3};

        int maxDist = 0;

        /*
            1 - NORTH
            2 - EAST
            3 - SOUTH
            4 - WEST
        */
        for (int i=0; i<commands.size(); ++i) {
            int command = commands[i];
            if (command == -1) {
                curr_dir = directions[curr_dir].first;
            }
            else if (command == -2) {
                curr_dir = directions[curr_dir].second;
            }
            else {
                pair<int, int> resCoord;
                // up
                if (curr_dir == 1) {
                    resCoord = checkObs(obsSet, x, y, command, 1);
                }

                // right
                else if (curr_dir == 2) {
                    resCoord = checkObs(obsSet, x, y, command, 2);
                }

                // down
                else if (curr_dir == 3) {
                    resCoord = checkObs(obsSet, x, y, command, 3);
                }

                // left
                else {
                    resCoord = checkObs(obsSet, x, y, command, 4);
                }

                x = resCoord.first;
                y = resCoord.second;
            }

            maxDist = max(maxDist, x*x + y*y);
            // cout << "curr: " << x << " " << y << endl;
        }


        return maxDist;
    }
};

/*


 CURR > (INT_MAX - DIGIT)/10 


 1 2 3

 '3' - '0' = 3
 '2' => 20 + 3 23

    - 1 of the four cases ==> dir
    - my point ==> x, y
    - list of points ==> obs
    - dist

*/
53273