Javascript - Verbose DSU + Weighing  & Path Compression solution
Hi, I\'ve tried to keep a solution as verbose as possible to make it easy to read. DSU is implemented as a separate class. Though weighing and path compression 
Hi, I\'ve tried to keep a solution as verbose as possible to make it easy to read. DSU is implemented as a separate class. Though weighing and path compression is not required here and you won\'t get much benefit ( in leetcode benchmark ), but  I think it\'s good to have it :) \n\n```\nconst NORTH = 0;\nconst EAST = 1;\nconst SOUTH = 2;\nconst WEST = 3;\nconst SIDES = 4;\n\n/**\n * @param {string[]} grid\n * @return {number}\n */\nvar regionsBySlashes = function (grid) {\n    const n = grid.length;\n    /* Total size of our grid is [2x2]x4 */\n    const size = n * n * SIDES;\n    const uf = new UF(size);\n\n    /**\n     * Checks if the array index in the correct range\n     * @param index - 1D array index\n     * @returns {boolean|boolean} \n     */\n    const isValid = (index) => index >= 0 && index < size;\n\n    /**\n     * Convert 2D array index into 1D array index.\n     * Please note, that if we have 2x2 grid it will\n     * result to 4x[2x2] = [8x8] grid, because each\n     * 1x1 square contains 4 sides\n     * @param row\n     * @param col\n     * @returns {number} - 1D array index\n     */\n    const toIndex = (row, col) => {\n        if (row >= 0 && row < n && col >= 0 && col < n) {\n            return SIDES * (row * n + col);\n        }\n        return -1;\n    };\n\n    // Loop through our grid\n    for (let row = 0; row < n; row++) {\n        for (let col = 0; col < n; col++) {\n            /* grid[row] is a string, so we can treat it as array of characters */\n            const delimiter = grid[row][col];\n            \n            /* Find the root of current square - NORTH side */\n            const root = toIndex(row, col);\n\n            /* Merge parts of 1x1 square */\n            if (delimiter !== "/") {\n                uf.union(root + NORTH, root + EAST);\n                uf.union(root + WEST, root + SOUTH);\n            }\n            if (delimiter !== "\\\\") {\n                uf.union(root + NORTH, root + WEST);\n                uf.union(root + SOUTH, root + EAST)\n            }\n\n            /* Find the root of a neighbour from each side */\n            const northRoot = toIndex(row - 1, col);\n            const eastRoot = toIndex(row, col + 1);\n            const southRoot = toIndex(row + 1, col);\n            const westRoot = toIndex(row, col - 1);\n\n            // merge north\n            if (isValid(northRoot)) {\n                uf.union(root + NORTH, northRoot + SOUTH);\n            }\n\n            // merge east\n            if (isValid(eastRoot)) {\n                uf.union(root + EAST, eastRoot + WEST)\n            }\n\n            // merge south\n            if (isValid(southRoot)) {\n                uf.union(root + SOUTH, southRoot + NORTH)\n            }\n\n            // merge west\n            if (isValid(westRoot)) {\n                uf.union(root + WEST, westRoot + EAST);\n            }\n        }\n    }\n    return uf.count();\n};\n\n\nclass UF {\n    _sizes = [];\n    _ids = [];\n    _numberOfComponents = 0;\n\n    constructor(N) {\n        for (let i = 0; i < N; i++) {\n            this._ids[i] = i;\n            this._sizes[i] = 0;\n        }\n        this._numberOfComponents = N;\n    }\n\n    union(p, q) {\n        const pRoot = this.find(p);\n        const qRoot = this.find(q);\n        if (pRoot === qRoot) {\n            return;\n        }\n        // weighing Approach\n        if (this._sizes[pRoot] > this._sizes[qRoot]) {\n            this._ids[qRoot] = pRoot;\n            this._sizes[pRoot] += this._sizes[qRoot];\n        } else {\n            this._ids[pRoot] = qRoot;\n            this._sizes[qRoot] += this._sizes[pRoot];\n        }\n        this._numberOfComponents--;\n    }\n\n    find(p) {\n        let root = this._ids[p];\n        while (root !== this._ids[root]) {\n            root = this._ids[root];\n        }\n        // Compress the path\n        while (p !== root) {\n            let next = this._ids[p];\n            this._ids[p] = root;\n            p = this._ids[next];\n        }\n        return root;\n    }\n\n    count() {\n        return this._numberOfComponents;\n    }\n}\n```
[]