I need help with this problem, I need an array 3x5 and then when the user selects a position the output will show the min value of the adjacents numbers. Like this:
3 5 6 7 8
6 7 8 2 3
0 9 2 1 1
And the user selects the position 1,1. // Diagonals count it too.
Output: The min value around is 0.
This is the code that I have, the problem is I´m asking if there is a better way than spamming if and elses everywhere.
private static int checkAdjacentField(int p1, int p2, int[][] ae) {
int min = Integer.MAX_VALUE;
if (p1 == 0) {
if (p2 == 0) {
if (ae[p1][p2+1] < min) {
min = ae[p1][p2+1];
} else if (ae[p1+1][p2+1] < min) {
min = ae[p1+1][p2+1];
} else if (ae[p1+1][p2] < min) {
min = ae[p1+1][p2];
}
} else if (p2 == 1) {
if (ae[p1][p2+1] < min){
min = ae[p1][p2+1];
} else if (ae[p1+1][p2+1] < min) {
min = ae[p1+1][p2+1];
} else if (ae[p1+1][p2] < min) {
min = ae[p1+1][p2];
} else if (ae[p1+1][p2-1] < min) {
min = ae[p1+1][p2-1];
} else if (ae[p1][p2-1] < min) {
min = ae[p1][p2-1];
}
}
}
return min;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Random r = new Random();
int [][] ar = new int[3][5];
for (int i = 0; i < ar.length; i++) {
System.out.println();
for (int j = 0; j < 5; j++) {
int rand = r.nextInt(9) + 1;
ar[i][j]=rand;
System.out.printf("%3d",ar[i][j]);
}
}
System.out.println();
System.out.println("Select a position [][]: ");
int pos1 = Integer.parseInt(br.readLine());
int pos2 = Integer.parseInt(br.readLine());
System.out.println("The min value around is " + checkAdjacentField(pos1,pos2,ar));
}
}
In the code the 0,0 and 0,1 works and yes, I could spend time doing the spamming method of if else but I want to know if there is a better way so I can improve. Thanks for helping, any idea or answer is welcome.
I think the best way to do that is using the following algo:
this way :
private static int checkAdjacentField(int col, int row, int[][] ae) {
int nbRows = ae.length;
int nbCols = ae[0].length;
// Stream all the 8 positions around your position
Stream<Point> positions = Stream.of(
new Point(col-1, row-1), new Point(col-1, row), new Point(col-1, row+1),
new Point(col, row-1), new Point(col, row+1),
new Point(col+1, row-1), new Point(col+1, row), new Point(col+1, row+1));
return positions
.filter(p -> p.x>=0 && p.y>=0 && p.x<nbCols && p.y<nbRows) // keep those inbound
.mapToInt(p -> ae[p.y][p.x]) // replace positions by their values in the array
.sorted() // sort the values
.findFirst().orElse(-1); // take the first one (smallest)
}
You could even generate the list of points, instead of hard coding them
private static int checkAdjacentField(int col, int row, int[][] ae) {
int nbRows = ae.length;
int nbCols = ae[0].length;
// Stream all the 8 positions around your position
Stream<Point> positions = IntStream.rangeClosed(-1, 1).boxed() // -1, 0, 1
.map(c -> IntStream.rangeClosed(-1, 1).boxed() // -1, 0, 1
.map(r -> new Point(col+c, row+r)))
.flatMap(p -> p) // to a list
.filter(p -> !(p.x == col && p.y==row)); // remove center point
// then same as first example
return positions
.filter(p -> p.x>=0 && p.y>=0 && p.x<nbCols && p.y<nbRows)
.mapToInt(p -> ae[p.y][p.x])
.sorted()
.findFirst().orElse(-1);
}
I prefer hard coding them like in the first example though, it is clearer.
How about this?
private static int checkAdjacentField(int p1, int p2, int[][] ae) {
int[] tmp = new int[8];
int left = (p2-1) % ae[0].length;
int right = (p2+1) % ae[0].length;
int up = (p1-1) % ae.length;
int down = (p1+1) % ae.length;
tmp[0] = ae[up][left];
tmp[1] = ae[up][p2];
tmp[2] = ae[up][right];
tmp[3] = ae[p1][left];
tmp[4] = ae[p1][right];
tmp[5] = ae[down][left];
tmp[6] = ae[down][p2];
tmp[7] = ae[down][right];
List<Integer> tmpList = Arrays.stream(tmp).boxed().collect(Collectors.toList());
return tmpList.stream().mapToInt(i -> i).min().orElse(0);
}
Granted, this doesn't account for edges. If you care about edges, you can use Math.min
or Math.max
to cover these cases:
private static int checkAdjacentField(int p1, int p2, int[][] ae) {
int[] tmp = new int[8];
int left = (Math.max((p2-1),0)) % ae[0].length;
int right = (Math.min((p2+1), ae[0].length-1)) % ae[0].length;
int up = (Math.max((p1-1),0)) % ae.length;
int down = (Math.min((p1+1), ae.length-1)) % ae.length;
tmp[0] = ae[up][left];
tmp[1] = ae[up][p2];
tmp[2] = ae[up][right];
tmp[3] = ae[p1][left];
tmp[4] = ae[p1][right];
tmp[5] = ae[down][left];
tmp[6] = ae[down][p2];
tmp[7] = ae[down][right];
List<Integer> tmpList = Arrays.stream(tmp).boxed().collect(Collectors.toList());
return tmpList.stream().mapToInt(i -> i).min().orElse(0);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With