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\$
2
  • 1
    \$\begingroup\$ Welcome to CR! Good job with your first post! Could that be part of something like a minesweeper game? \$\endgroup\$ Commented Mar 24, 2016 at 4:19
  • \$\begingroup\$ @Mat'sMug It's part of a cave generation algorithm from Nethack 4. \$\endgroup\$
    – Tilded
    Commented Mar 24, 2016 at 4:36

1 Answer 1

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 and acknowledge you have read our privacy policy.

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