Iterierung über ein zweidimensionales Array

sserio

Bekanntes Mitglied
Also die Aufgabe war es über ein zweidimensionales Array zu iterieren und die größte diagonale Summer heraus zu finden (die länge der diagonalen ist 4). Ich habe mir gedacht das ich immer durch die Reihen gehe und den Spaltenindex verschiebe. Ich muss nur bis zur Reihe 16 gehen, weil es ja sowieso in die Diagonale 4 runter geht. Damit ich alle Felder erreiche iteriere ich ein Mal von Rechts und ein Mal von Links. Jedoch auf der Spaltenebene nur 17 Mal, weil es ja in die Diagonale nach 4 geht.
[CODE lang="java" title="ProjectEuler11"]package ProjectEuler11;

import java.math.BigInteger;
import java.util.BitSet;

public class Main {
public static void main(String... args) {
System.out.println(findBiggestDiagonalSum(array()));
}

public static BigInteger findBiggestDiagonalSum(int[][] array) { //the code isn't universal because it has to be [20][20] in this example
var sum = BigInteger.ZERO;
var value = BigInteger.ONE;
for (var i = 0; i < array.length - 4; i++) {
for (var j = 0; j < array.length - 3; j++) {
var first = Integer.valueOf(array[j]);
var second = Integer.valueOf(array[i + 1][j + 1]);
var third = Integer.valueOf(array[i + 2][j + 2]);
var fourth = Integer.valueOf(array[i + 3][j + 3]);
value = value.max(BigInteger.valueOf((long) first * second * third * fourth));

}
for (var k = array.length-1; k > array.length - 15; k--) {
var first = Integer.valueOf(array[k]);
var second = Integer.valueOf(array[i + 1][k - 1]);
var third = Integer.valueOf(array[i + 2][k - 2]);
var fourth = Integer.valueOf(array[i + 3][k - 3]);
value = value.max(BigInteger.valueOf((long) first * second * third * fourth));
}
sum = sum.add(value);
}
return sum;
}

public static int[][] array() {
var value = "08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48";
int[][] arr = new int[20][20];
var splitValue = value.split(" ");
var index = 0;
for (int row = 0; row < arr.length; row++) {
for (int column = 0; column < arr[row].length; column++) {
arr[row][column] = Integer.parseInt(splitValue[index++]);
}
}
return arr;
}

public static void printArray(int[][] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
System.out.printf("%02d ", array[j]);

}
System.out.println();
}

}

}[/CODE]
Ich habe das Problem, dass statt 52167216 , 769074616 rauskommt. Wenn ich die Verschiebungen in den for schleifen vergrößere oder (nach links) verkleinere nichts wirklich passiert. Falls ihr Tipps habt gerne schreiben.
Array:
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
 

Anhänge

  • Screenshot 2022-02-18 224418.png
    Screenshot 2022-02-18 224418.png
    64,7 KB · Aufrufe: 2
ich weis nicht genau das problem aber ich kann dir was in die hand drücken "clean code" ... dh code umschreiben dass es besser lesbar ist
Java:
for (int row = 0; row < arr.length; row++) {
    var rowArray[] = arr[row];
     for (int column = 0; column < arr[row].length; column++) {
          var columnArray = rowArray[column];
          // .... alles was hier steht kannst du in methoden auslagern
         // aber vllt spielst du erstmal hier so rum :)
    }
}

ich werfs dir so hin.. wenn du fragen hast kannst du sie ja stellen


und in methoden auslagern... und in allen methoden das durchziehen.. dann lösen sich probleme von selber
 
Java:
public static BigInteger findBiggestDiagonalSum(int[][] array) { //the code isn't universal because it has to be [20][20] in this example
    var sum = BigInteger.ZERO;
    var value = BigInteger.ONE;
    for (var row = 0; row < array.length - 4; row++) {
        for (var columnRight = 0; columnRight < array[row].length - 3; columnRight++) {
            var first = Integer.valueOf(array[row][columnRight]);
            var second = Integer.valueOf(array[row + 1][columnRight + 1]);
            var third = Integer.valueOf(array[row + 2][columnRight + 2]);
            var fourth = Integer.valueOf(array[row + 3][columnRight + 3]);
            if (first * second * third * fourth <= (int) Math.pow(99, 4)) {
                value = value.max(BigInteger.valueOf((long) first * second * third * fourth));
            }else continue;
        }
        for (var columnLeft = array[row].length - 1; columnLeft > array[row].length - 15; columnLeft--) {
            var first = Integer.valueOf(array[row][columnLeft]);
            var second = Integer.valueOf(array[row + 1][columnLeft - 1]);
            var third = Integer.valueOf(array[row + 2][columnLeft - 2]);
            var fourth = Integer.valueOf(array[row + 3][columnLeft - 3]);
            if (first * second * third * fourth <= (int) Math.pow(99, 4)) {
                value = value.max(BigInteger.valueOf((long) first * second * third * fourth));
            }else continue;

        }
        sum = sum.add(value);
    }
    return sum;
}
    }
Habe das jetzt versucht mit einer if schleife abzuschachteln, ich glaube es liegt an diesem .max bei dem BigInteger. Weil das ergebnis trotz der 99 x 99 x 99 x 99 immernoch das gleiche ist
 
Wozu verwendest du hier BigInteger . Deine maximale Zahl passt in einen normalen Integer.
Ja, wollte aber konstanten mal ausprobieren. Also ich habe solche noch nie benutzt (dieses mal zum ersten Mal).
Java:
package ProjectEuler11;

import java.math.BigInteger;

public class Main {
    public static void main(String... args) {
        double startTime = System.currentTimeMillis();
        printArray(array());
        System.out.println(findBiggestDiagonalSum(array()));
        double endTime = System.currentTimeMillis();
        System.out.printf("%.3f %s",  (endTime - startTime) / 1000,  "seconds");
    }

    public static BigInteger findBiggestDiagonalSum(int[][] array) { //the code isn't universal because it has to be [20][20] in this example
        var value = BigInteger.ZERO;
        // 4 to right
        for (var row = 0; row < array.length; row++) {
            for (var column = 0; column < array[row].length - 3; column++) {
                value = value.max(BigInteger.valueOf((long) (int) array[row][column] * array[row][column + 1] * array[row][column + 2] * array[row][column + 3]));
            }
        }
        // 4 to the bottom
        for (var row = 0; row < array().length - 3; row++) {
            for (var column = 0; column < array[row].length; column++) {
                value = value.max(BigInteger.valueOf((long) (int) array[row][column] * array[row + 1][column] * array[row + 2][column] * array[row + 3][column]));
            }
        }
        // 4 diagonal right
        for (var row = 0; row < array().length - 3; row++) {
            for (var column = 0; column < array[row].length - 3; column++) {
                value = value.max(BigInteger.valueOf((long) (int) array[row][column] * array[row + 1][column + 1] * array[row + 2][column + 2] * array[row + 3][column + 3]));
            }
        }
        // 4 diagonal left
        for (var row = 0; row < array().length - 3; row++) {
            for (var column = array.length - 1; column < array[row].length - 3; column--) {
                value = value.max(BigInteger.valueOf((long) (int) array[row][column] * array[row + 1][column - 1] * array[row + 2][column - 2] * array[row + 3][column - 3]));
            }
        }
        return value;
    }

    public static int[][] array() {
        var value = "08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48";
        int[][] arr = new int[20][20];
        var splitValue = value.split(" ");
        var index = 0;
        for (int row = 0; row < arr.length; row++) {
            for (int column = 0; column < arr[row].length; column++) {
                arr[row][column] = Integer.parseInt(splitValue[index++]);
            }
        }
        return arr;
    }

    public static void printArray(int[][] array) {
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.printf("%02d ", array[i][j]);

            }
            System.out.println();
        }

    }
}
und es hat auch funktioniert, weil ich diese .ZERO .ONE sachen gecheckt habe
 
Ja, wollte aber konstanten mal ausprobieren. Also ich habe solche noch nie benutzt (dieses mal zum ersten Mal).
Java:
package ProjectEuler11;

import java.math.BigInteger;

public class Main {
    public static void main(String... args) {
        double startTime = System.currentTimeMillis();
        printArray(array());
        System.out.println(findBiggestDiagonalSum(array()));
        double endTime = System.currentTimeMillis();
        System.out.printf("%.3f %s",  (endTime - startTime) / 1000,  "seconds");
    }

    public static BigInteger findBiggestDiagonalSum(int[][] array) { //the code isn't universal because it has to be [20][20] in this example
        var value = BigInteger.ZERO;
        // 4 to right
        for (var row = 0; row < array.length; row++) {
            for (var column = 0; column < array[row].length - 3; column++) {
                value = value.max(BigInteger.valueOf((long) (int) array[row][column] * array[row][column + 1] * array[row][column + 2] * array[row][column + 3]));
            }
        }
        // 4 to the bottom
        for (var row = 0; row < array().length - 3; row++) {
            for (var column = 0; column < array[row].length; column++) {
                value = value.max(BigInteger.valueOf((long) (int) array[row][column] * array[row + 1][column] * array[row + 2][column] * array[row + 3][column]));
            }
        }
        // 4 diagonal right
        for (var row = 0; row < array().length - 3; row++) {
            for (var column = 0; column < array[row].length - 3; column++) {
                value = value.max(BigInteger.valueOf((long) (int) array[row][column] * array[row + 1][column + 1] * array[row + 2][column + 2] * array[row + 3][column + 3]));
            }
        }
        // 4 diagonal left
        for (var row = 0; row < array().length - 3; row++) {
            for (var column = array.length - 1; column < array[row].length - 3; column--) {
                value = value.max(BigInteger.valueOf((long) (int) array[row][column] * array[row + 1][column - 1] * array[row + 2][column - 2] * array[row + 3][column - 3]));
            }
        }
        return value;
    }

    public static int[][] array() {
        var value = "08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48";
        int[][] arr = new int[20][20];
        var splitValue = value.split(" ");
        var index = 0;
        for (int row = 0; row < arr.length; row++) {
            for (int column = 0; column < arr[row].length; column++) {
                arr[row][column] = Integer.parseInt(splitValue[index++]);
            }
        }
        return arr;
    }

    public static void printArray(int[][] array) {
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.printf("%02d ", array[i][j]);

            }
            System.out.println();
        }

    }
}
und es hat auch funktioniert, weil ich diese .ZERO .ONE sachen gecheckt habe
grundsätzlich hätte ich es ja auch mit long oder etwas anderem machen können
 
Ich habe das Problem, dass statt 52167216 , 769074616 rauskommt
Das Maximum befindet sich in Zeile 13 Spalte 7 und ist eine Linksdiagonale.
89*94*97*87 = 70600674
[CODE lang="java" title="StartFindMax" highlight="59-64.68-73,16-23"]import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class StartFindMax {
final static int DIAGONAL_SIZE = 4;

public static void main(String[] args) {
int[][] arr = load("./array.txt"); // lade array aus Datei
System.out.println(findMaxDiagonalProduct(arr));
}

private static long findMaxDiagonalProduct(int[][] arr) {
long max = 0;
for (int y = 0; y < arr.length; y++) {
for (int x = 0; x < arr[y].length; x++) {
max = updateMaxLeftDiagonal(arr, x, y, max);
max = updateMaxRightDiagonal(arr, x, y, max);
}
}
return max;
}

private static int[][] load(String name) {
ArrayList<String[]> tmp = new ArrayList<>();
try {
BufferedReader br = new BufferedReader(new FileReader(new File(name)));
String line = null;
int maxRow = 0;
while ((line = br.readLine()) != null) {
String[] row = line.split(" ");
if (row.length > maxRow)
maxRow = row.length;
tmp.add(row);
}
br.close();
return toIntArray(tmp, maxRow);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

private static int[][] toIntArray(ArrayList<String[]> str, int colMax) {
int rowMax = str.size();
int[][] array = new int[rowMax][colMax];
for (int row = 0; row < rowMax; row++) {
String[] tmp = str.get(row);
for (int col = 0; col < colMax; col++) {
array[row][col] = Integer.parseInt(tmp[col]);
}
}
return array;
}

private static long updateMaxLeftDiagonal(int[][] arr, int x, int y, long max) {
if (x < DIAGONAL_SIZE - 1 || y > arr.length - DIAGONAL_SIZE)
return max;
long product = 1;
for (int i = 0; i < DIAGONAL_SIZE; i++)
product *= arr[y + i][x - i];
return product > max ? product : max;
}

private static long updateMaxRightDiagonal(int[][] arr, int x, int y, long max) {
if (x > arr[y].length - DIAGONAL_SIZE || y > arr.length - DIAGONAL_SIZE)
return max;
long product = 1;
for (int i = 0; i < DIAGONAL_SIZE; i++)
product *= arr[y + i][x + i];
return product > max ? product : max;
}

}[/CODE]
 
Das Maximum befindet sich in Zeile 13 Spalte 7 und ist eine Linksdiagonale.
89*94*97*87 = 70600674
[CODE lang="java" title="StartFindMax" highlight="59-64.68-73,16-23"]import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class StartFindMax {
final static int DIAGONAL_SIZE = 4;

public static void main(String[] args) {
int[][] arr = load("./array.txt"); // lade array aus Datei
System.out.println(findMaxDiagonalProduct(arr));
}

private static long findMaxDiagonalProduct(int[][] arr) {
long max = 0;
for (int y = 0; y < arr.length; y++) {
for (int x = 0; x < arr[y].length; x++) {
max = updateMaxLeftDiagonal(arr, x, y, max);
max = updateMaxRightDiagonal(arr, x, y, max);
}
}
return max;
}

private static int[][] load(String name) {
ArrayList<String[]> tmp = new ArrayList<>();
try {
BufferedReader br = new BufferedReader(new FileReader(new File(name)));
String line = null;
int maxRow = 0;
while ((line = br.readLine()) != null) {
String[] row = line.split(" ");
if (row.length > maxRow)
maxRow = row.length;
tmp.add(row);
}
br.close();
return toIntArray(tmp, maxRow);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

private static int[][] toIntArray(ArrayList<String[]> str, int colMax) {
int rowMax = str.size();
int[][] array = new int[rowMax][colMax];
for (int row = 0; row < rowMax; row++) {
String[] tmp = str.get(row);
for (int col = 0; col < colMax; col++) {
array[row][col] = Integer.parseInt(tmp[col]);
}
}
return array;
}

private static long updateMaxLeftDiagonal(int[][] arr, int x, int y, long max) {
if (x < DIAGONAL_SIZE - 1 || y > arr.length - DIAGONAL_SIZE)
return max;
long product = 1;
for (int i = 0; i < DIAGONAL_SIZE; i++)
product *= arr[y + i][x - i];
return product > max ? product : max;
}

private static long updateMaxRightDiagonal(int[][] arr, int x, int y, long max) {
if (x > arr[y].length - DIAGONAL_SIZE || y > arr.length - DIAGONAL_SIZE)
return max;
long product = 1;
for (int i = 0; i < DIAGONAL_SIZE; i++)
product *= arr[y + i][x + i];
return product > max ? product : max;
}

}[/CODE]
Ist natürlich mehr advanced von den ganzen Sachen die du eingebaut hast, dennoch haben wir das gleiche ergebnis. Aber ich hätte mir theoretisch auch die Koordinaten ausgeben können.
 
Frage zur Aufgabe:
Können deine Zahlen dann von einer Seite zur Anderen "loopen"?
Also bspw. die nahc links unten gehen roten diagonallinien, wenn die links die wand treffen, gehen die rechts weiter?
oder ist ende wenn die wand kommt? 🙂

Weil je nachdem müsste man da dann mit modulo arbeiten um die indizes im zulässigen Rahmen zu halten 🙂


Am Rande angemerkt:
Es kann nur so viele Doigonalen geben wie 2 mal die Anzahl an Zahlen in der ersten Zeile.
Weil halt von jeder der Zahlen eine Diagonale nahc links unten und eine nahc rechts unten gehen kann.
just saying.
 

Zurück
Oben