Да, «тетрис» был определённо приятней вчерашних «скобочек». И концептуально, и в реализации. Старые-добрые циклы-в-циклах — что может быть лучше!? 🙂
Только циклы, приправленные щепоткой стримов, конечно! Впрочем, попытки решить вторую часть через стрим — не увенчались успехом, увы. Приступ стримоза отступил и циклы вошли в свои права.
Песок и камни, или — камни и песок
static int drawRock(String scanLine, boolean[][] gameField) {
int maxY = 0;
String[] XY = scanLine.split(" -> ");
for (int i = 0; i < XY.length - 1; i++) {
int[] rocks = IntStream.rangeClosed(i, i + 1).mapToObj(idx -> XY[idx].split(","))
.flatMap(Arrays::stream).mapToInt(Integer::parseInt).toArray();
for (int j = Math.min(rocks[0], rocks[2]); j <= Math.max(rocks[0], rocks[2]); j++) {
for (int k = Math.min(rocks[1], rocks[3]); k <= Math.max(rocks[1], rocks[3]); k++) {
gameField[j][k] = true;
}
}
maxY = Math.max(maxY, Math.max(rocks[1], rocks[3]));
}
return maxY;
}
static boolean pourSand(int maxY, boolean[][] gameField) {
if (gameField[500][0]) return false;
int x = 500;
int y = 0;
while (y <= maxY + 3) {
if (!gameField[x][y + 1]) {
y++;
continue;
} else if (!gameField[x - 1][y + 1]) {
x--;
y++;
continue;
} else if (!gameField[x + 1][y + 1]) {
x++;
y++;
continue;
}
return gameField[x][y] = true;
}
return false;
}
Обратная засыпка по самое горлышко
static void day14(String puzzleInputUri) throws IOException, InterruptedException {
boolean[][] gameField = new boolean[1000][1000];
var maxY = client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines())
.body()
.mapToInt(scanLine -> drawRock(scanLine, gameField))
.max().orElse(0);
int answer = 0;
drawRock( "0," + (maxY + 2) + " -> " + (gameField[0].length - 1) + "," + (maxY + 2), gameField);
while (pourSand(maxY, gameField)) {
answer++;
}
System.out.println(answer);
}
Читать далее Advent of Code 2022: Day 14