0

I was looking over my old code and wanted to make it look more "elegant". Basically overly complicated but looks cooler. I was wondering if anyone could help! Assuming I want to add the 4 neighbours of a given index (x, y) in a 2D array arr, to an new array n, I started with this:

n.add( arr[x][y-1] );
n.add( arr[x][y+1] );
n.add( arr[x-1][y] );
n.add( arr[x+1][y] );

With a bit of googling, this was probably the best answer I managed to find. I tidied it up a little to get this:

for (int i = x-1; i <= x+1; i++) {
    for (int j = y-1; j <= y+1; j++) {
        if(!((i == x) && (j == y))) {
            n.add( arr[i][j] );
        }
    }
}

With a bit of tweaking I ended up with this:

for (int i = -1; i <= 1; i++) {
    for (int j = -1; j <= 1; j++) {
        if(Math.abs(i) == Math.abs(j)) continue;
        n.add( arr[x+i][y+j] );
    }
}

How much further can you go with this? I was thinking there may be a way to simplify the if statement with some math logic but I'm not smart enough to think of anything. Help/thoughts would be appreciated!

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Kentalian
  • 25
  • 3
  • 1
    Welcome to Stack Overflow. If you're never going to want to generalize this operation to handle other cases, like adding the two prior neighbors instead of just the one, then I actually much prefer your first solution. I personally never feel a need to shoot for "elegant". I want "fast" and "easy to understand". Your first version is significantly more efficient than your final version, and it's much easier to understand what the code is doing. All other things being fairly equal, readability is king. The easiest code to understand and maintain is often seen as the "best" code. – CryptoFool Sep 18 '22 at 05:13
  • ..one other comment...I'm guessing that you're leaving bounds checking out of this for reasons of simplicity. Unless you are somehow sure that neither `x` nor `y` are ever going to be out of bounds or on one of the edges of the input array, you're likely going to want to deal with those cases explicitly rather than waiting for an "out of bounds error" to be thrown by a bad array access. – CryptoFool Sep 18 '22 at 05:18
  • You're definitely right on the efficiency! I'm never planning on using this code in a product as it was more of a thought experiment. And yes the `x` and `y` are assumed to be checked before passing into this function for simplicity's sake. – Kentalian Sep 18 '22 at 05:21
  • 1
    Cool. I still don't see the point of your endeavor though. If you'd never write the code any other way than your first example in real life, what's the purpose of the :"though experiment"? Let me make my own slant on this question even clearer. The efficiency of this code probably doesn't matter, right? The main issue I see is that I had to stare REALLY HARD at the more complex version of your code to try to understand what it was doing and confirm that it was producing the same result as your first version. Such situations should be avoided whenever possible. – CryptoFool Sep 18 '22 at 05:22
  • For fun! Also, sometimes in another situation the knowledge I gained from this might help. – Kentalian Sep 18 '22 at 05:26
  • Well, if the goal is to make your code progressively harder to understand, then I get what knowledge you might take away from this exercise. Otherwise.... – CryptoFool Sep 18 '22 at 05:28
  • One bit of knowledge I already got from this is the `Math.abs(i) == Math.abs(j)` statement can find the diagonal neighbours of an index, or orthogonal with its inverse :) – Kentalian Sep 18 '22 at 05:37
  • yeah, totally true. Sorry. I was maybe too critical of your thought experiment. There are definitely things to learn from the kind of thing you're doing, and the great thing about programming is that it can't hurt to try anything and everything. You machine is never going to bite you. – CryptoFool Sep 18 '22 at 06:47

1 Answers1

1

Note that you make 9 iterations, while only 4 are useful.

If this part of code really needs to be changed, it is possible to store shifts in array and use them. Pseudocode:

yxs = {{0,1},{1,0},{0,-1},{-1,0}}

for (int i = 0; i < 4; i++) 
    n.add( arr[x+yxs[i][0]][y+yxs[i][1]]);
MBo
  • 77,366
  • 5
  • 53
  • 86