Skip to content
Snippets Groups Projects
Commit fac478b8 authored by Christopher Bohn's avatar Christopher Bohn :thinking:
Browse files

Completed Year 2022 Day 7 part 1

parent a086d134
No related branches found
No related tags found
No related merge requests found
...@@ -183,5 +183,30 @@ This is straight-forward -- I just need to parameterize the helper method that l ...@@ -183,5 +183,30 @@ This is straight-forward -- I just need to parameterize the helper method that l
## Day 7 ## Day 7
- [The problem](https://adventofcode.com/2022/day/7)
- [The solution](src/main/java/edu/unl/cse/bohn/year2022/Day7.java)
### Part 1
The subproblems are
- Parse the input
- Based on the responses to commands, determine the size of each directory
- The size of a "leaf" directory that has no subdirectories is the sum of the sizes of its files
- The size of a non-leaf is the sum of the sizes of its files and the sizes of its directories
- Determine which directories' size is at most 100000
It is very tempting to create a model of the directory structure, but the concern of course is the memory usage.
Many of these problems can be mapped to a simpler problem.
I think the reason I'm so tempted to create a model of the directory structure is because the description of the
structure is coming in BFS, but determining the directory sizes would best be done DFS.
It looks like the puzzle input has fewer than 200 directories. YOLO. So, add to the subproblems:
- Build a model of the directory tree
### Part 2
...
## Day 8
(coming soon) (coming soon)
package edu.unl.cse.bohn.year2022;
import edu.unl.cse.bohn.Puzzle;
import java.util.*;
@SuppressWarnings("unused")
public class Day7 extends Puzzle {
public Day7(boolean isProductionReady) {
super(isProductionReady);
sampleData = """
$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k""";
}
Directory rootDirectory = null;
public static final long THRESHOLD_DIRECTORY_SIZE = 100000;
@Override
public long computePart1(List<String> data) {
if (rootDirectory == null) {
rootDirectory = buildDirectoryTree(data);
}
Set<Directory> directoriesBelowThreshold = getSmallDirectories(rootDirectory);
return directoriesBelowThreshold.stream().mapToLong(Directory::getSize).sum();
}
@Override
public long computePart2(List<String> data) {
if (rootDirectory == null) {
rootDirectory = buildDirectoryTree(data);
}
return 0;
}
private Directory buildDirectoryTree(List<String> data) {
Directory root = null;
Directory workingDirectory = null;
for (String datum : data) {
if (datum.equals("$ cd /")) {
root = new Directory("/", null);
workingDirectory = root;
} else if (datum.equals("$ cd ..")) {
assert workingDirectory != null;
workingDirectory = workingDirectory.getParentDirectory();
} else if (datum.startsWith("$ cd ")) {
assert workingDirectory != null;
workingDirectory = workingDirectory.getSubdirectory(datum.substring(5));
} else if (datum.equals("$ ls")) {
System.out.print(""); // a convenient nop, since there's nothing to do
} else if (datum.startsWith("dir ")) {
assert workingDirectory != null;
workingDirectory.addDirectory(datum.substring(4));
} else if (Character.isDigit(datum.charAt(0))) {
String[] tokens = datum.strip().split(" ");
long fileSize = Long.parseLong(tokens[0]);
String fileName = tokens[1];
assert workingDirectory != null;
workingDirectory.addFile(fileName, fileSize);
} else {
throw new IllegalArgumentException("Unrecognized line in the data: " + datum);
}
}
return root;
}
private Set<Directory> getSmallDirectories(Directory rootOfSubtree) {
Set<Directory> smallDirectories = new HashSet<>();
if (rootOfSubtree.getSize() <= THRESHOLD_DIRECTORY_SIZE) {
smallDirectories.add(rootOfSubtree);
}
for (Directory subdirectory : rootOfSubtree.getSubdirectories()) {
smallDirectories.addAll(getSmallDirectories(subdirectory));
}
return smallDirectories;
}
private static class Directory {
String name;
Directory parentDirectory;
Map<String, Directory> subdirectories;
Map<String, Long> files;
Long cachedSize; // we're going to cache the directory size to avoid repeatedly diving into subdirectories
public Directory(String name, Directory parentDirectory) {
this.name = name;
this.parentDirectory = parentDirectory;
subdirectories = new HashMap<>();
files = new HashMap<>();
cachedSize = null;
}
public void addDirectory(String name) {
subdirectories.put(name, new Directory(name, this));
cachedSize = null; // any existing cached size is now invalid
}
public void addFile(String name, long size) {
files.put(name, size);
cachedSize = null; // any existing cached size is now invalid
}
public String getName() {
return name;
}
public Directory getParentDirectory() {
return parentDirectory;
}
public Directory getSubdirectory(String name) {
return subdirectories.get(name);
}
public Collection<Directory> getSubdirectories() {
return subdirectories.values();
}
public long getSize() {
if (cachedSize == null) {
long size = subdirectories.keySet().stream()
.mapToLong(directoryName -> subdirectories.get(directoryName).getSize())
.sum();
size += files.keySet().stream().mapToLong(fileName -> files.get(fileName)).sum();
cachedSize = size;
}
return cachedSize;
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment