JS minheap bfs
\n/**\ncreate minheap consisting of all borders\n\nwhile heap not empty\n  take min\n  search each direction\n  if not visited\n    if depth lower than waterlin
```\n/**\ncreate minheap consisting of all borders\n\nwhile heap not empty\n  take min\n  search each direction\n  if not visited\n    if depth lower than waterline\n      add diff to total\n    add to visited\n    add to heap\nreturn total\n */\n\nconst trapRainWater = map => {\n    const heap = createMinHeap()\n    const visited = new Set()\n    let total = 0\n    let waterline = 0\n    \n    // add borders\n    const endj = map[0].length - 1\n    const endi = map.length - 1\n    for ( let i = 1; i < endi; i++ ) {\n        visited.add( i )\n        visited.add( i + .1 / endj)\n        heap.add([ i, 0, map[i][0] ])\n        heap.add([ i, endj, map[i][endj] ])\n    }\n    for ( let j = 1; j < endj; j++ ) {\n        visited.add( .1 / j )\n        visited.add( endi + .1 / j)\n        heap.add([ 0, j, map[0][j] ])\n        heap.add([ endi, j, map[endi][j] ])\n    }\n    \n    // by working at the min border and moving in\n    // its known that any depth below waterline will pool\n    while ( heap.size() ) {\n        const [ i, j, d ] = heap.takeMin()\n        waterline = Math.max( waterline, d )\n        \n        dirs( i, j ).forEach( ([ di, dj ]) => {\n            const key = di + .1 / dj\n            if ( visited.has( key ) || di <= 0 || dj <= 0 || di >= endi || dj >= endj ) return\n            visited.add( key )\n            var newd = map[ di ][ dj ]\n            \n            if ( newd < waterline ) {\n                total += waterline - newd\n            }\n            \n            heap.add([ di, dj, newd ])\n        })\n    }\n    \n    return total\n}\n\nconst createMinHeap = () => {\n    const heap = [null]\n    const leftChild = x => x * 2\n    const rightChild = x => x * 2 + 1\n    const parent = x => Math.floor( x / 2 )\n\n    return {\n        heap,\n        size: () => heap.length - 1,\n        takeMin: () => {\n            if ( heap.length === 2 ) return heap.pop()\n            const min = heap[1]\n            const last = heap.length - 1\n            let l, r, c, index = 1\n            \n            // swap w/ last in arr && pop\n            heap[1] = heap.pop()\n\n            // percolate down\n            while ( index < last ) {\n                l = leftChild( index )\n                r = rightChild( index )\n                c = heap[r] && heap[r][2] < heap[l][2] ? r : l\n\n                if ( heap[c] && heap[c][2] < heap[index][2] ) {\n                    let hold = heap[c]\n                    heap[c] = heap[index]\n                    heap[index] = hold\n                    index = c\n                } else {\n                    break\n                }\n            }\n            \n            while ( ! heap[ heap.length - 1 ] ) heap.pop()\n            return min\n        },\n        add: tile => {\n            // push to end\n            let pi, index = heap.length\n            \n            // percolate up until parent <= tile\n            while ( 1 < index ) {\n                pi = parent( index )\n                \n                if ( heap[ pi ] && heap[ pi ][2] <= tile[2] ) break\n\n                heap[ index ] = heap[ pi ]\n                index = pi\n            }\n            heap[ index ] = tile\n            \n            while ( ! heap[ heap.length - 1 ] ) heap.pop()\n        }\n    }\n}\n\nconst dirs = ( i, j ) => [ [ i + 1, j ], [ i - 1, j ], [ i, j + 1 ], [ i, j - 1 ] ]\n```
['JavaScript']