Найти тему
2 подписчика

Advent of Code 2022: Day 7


Мои взаимоотношения с этой загадкой можно описать примерно такой фразой (по мотивам анекдотов):
— Дерево — подумал Штирлиц
— Дерево — поняло дерево
Всё началось с того, что мне совершенно не хотелось строить это дерево (забегая вперёд — всё же пришлось).

После пары неудачных попыток — решил хранить эту псевдо-ФС в избыточном виде — получились этакие «мангровые заросли».
Директории, помимо вложенности в свои родительские каталоги, дублируются на корневом уровне. Таким образом получается без лишних усилий посчитать результат по условиям загадки.

record File(String name, long size, List<File> files) {}
static Map<String, File> flattenFs = new HashMap<>();

static void day7(String puzzleInputUri) throws IOException, InterruptedException {
List<String[]> commands = client.send(
request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines()
).body()
.skip(1)
.filter(line -> !line.equals("$ ls"))
.map(line -> line.replace("$ ", ""))
.map(line -> line.split(" "))
.toList();

String currentDirKey = "/";
flattenFs.put(currentDirKey, new File("/", 0L, new ArrayList<>()));
for (var commandLine : commands) {
String command = commandLine[0];
String arg = commandLine[1];
if ("dir".equals(command)) {
String newDirKey = currentDirKey + "/" + arg;
flattenFs.putIfAbsent(newDirKey, new File(newDirKey, 0L, new ArrayList<>()));
flattenFs.get(currentDirKey).files().add(flattenFs.get(newDirKey));
} else if ("cd".equals(command)) {
if ("..".equals(arg)) {
String parentDir = currentDirKey.substring(0, currentDirKey.lastIndexOf("/"));
currentDirKey = flattenFs.keySet().stream()
.filter(dir -> dir.equals(parentDir))
.findAny().orElseThrow();
} else {
currentDirKey += "/" + arg;
}
} else {
flattenFs.get(currentDirKey).files().add(new File(arg, Long.parseLong(command), new ArrayList<>()));
}
}

long resultPartOne = flattenFs.values().stream()
.mapToLong(dir -> getTotalSize(dir, 0L))
.filter(size -> size <= 100_000L)
.sum();
System.out.println(resultPartOne);

long usedSpace = getTotalSize(flattenFs.get("/"), 0L);
long freeSpace = 70_000_000L - usedSpace;
long needForUpdateSpace = 30_000_000L - freeSpace;
long resultPartTwo = flattenFs.values().stream()
.mapToLong(dir -> getTotalSize(dir, 0L))
.filter(size -> size >= needForUpdateSpace)
.min()
.orElseThrow();
System.out.println(resultPartTwo);
}

static long getTotalSize(File dir, long totalSize) {
List<File> files = dir.files();
for (File file : files) {
totalSize += file.size() > 0L
? file.size()
: getTotalSize(flattenFs.get(file.name()), 0L);
}
return totalSize;
}

#adventofcode #adventofcode_2022 #программинг

--- Ссылка на запись ---
2 минуты