5
\$\begingroup\$

Consider a 3x3 square surrounding a cell (marked @) on a grid:

0 1 1
1 @ 0
1 1 1

I need to find the number of groups of open cells (ones) surrounding the center cell. In the above example, there are two groups of open cells. All cells have the value 0, closed, or 1, open.
Here's what I have:

{
    // x and y coordinates for offsets corresponding
    // to the eight neighboring cells
    const xDir = [0, 1, 1, 1, 0,-1,-1,-1];
    const yDir = [1, 1, 0,-1,-1,-1, 0, 1];

    // generate a randomly open (1) or closed (0) 3 by 3 square of cells
    const generateSquare = _ => {
        const square = [];
        for (let x = 0; x < 3; x++) {
            square[x] = [];
            for (let y = 0; y < 3; y++) {
                square[x][y] = Number(Math.random() < 0.5);
            }
        }
        return square;
    };

    // count the number of contiguous groups of open (1) cells
    const countGroups = square => {
        let groups = 0;
        // loop clockwise through neighbors and count transitions from 0 to 1
        let prev = square[0][2];
        for (let i = 0; i < 8; i++) {
            let curr = square[1 + xDir[i]][1 + yDir[i]];
            groups += Number(!prev && curr);
            prev = curr;
        }
        // if there aren't any transitions, check if all neighbors are 1
        return !groups && prev ? 1 : groups;
    };

    const square = generateSquare();
    console.table(square);
    console.log(countGroups(square));
}

Is there anything I can improve?

\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to CR! Good job with your first post! Could that be part of something like a minesweeper game? \$\endgroup\$ – Mathieu Guindon Mar 24 '16 at 4:19
  • \$\begingroup\$ @Mat'sMug It's part of a cave generation algorithm from Nethack 4. \$\endgroup\$ – Tilded Mar 24 '16 at 4:36
1
\$\begingroup\$

You could try using ramdajs. I solved it as follows but it could be way better

// indexes of the order to iterate in array square
const cord = [6, 7, 8, 5, 2, 1, 0, 3, 6];
const binaryRand = ()=>  Number(Math.random() < 0.5);

//const square = [1, 1, 1, 1, 0, 1, 0, 1, 0];
const square = R.times(binaryRand,9) 

const zeroToOne = (acc,curr,index)=>{
  if(index === 0) return 0;
  return acc+= Number(!square[index-1] && square[curr])
}

const countGroups = (square)=>
  ((R.sum(square) - cord[4]) < 8)?
     cord.reduce(zeroToOne,0) : 1;

countGroups(square);

here is the Ramdajs repel of the code.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.