namespace AdventOfCodeLibrary._2022.Day_07 { public class Directory { public Directory? ParentDirectory { get; set; } public string Name { get; set; } = string.Empty; public List Directories { get; set; } = new(); public List Files { get; set; } = new(); public int GetSizeOfAllFiles() => Files.Sum(f => f.Size) + Directories.Sum(d => d.GetSizeOfAllFiles()); } public struct File { public string Name { get; set; } public int Size { get; set; } } internal class DirectoryManager { readonly Directory RootDirectory; Directory CurrentDirectory; internal DirectoryManager() { RootDirectory = new Directory { Name = "/", ParentDirectory = null }; CurrentDirectory = RootDirectory; } internal void ParseTerminalOutput(string[] lines) { for (int lineIndex = 0; lineIndex < lines.Length; lineIndex++) { string[] parts = lines[lineIndex].Split(' '); // it is a command if (parts[0] == "$") { // move to other folder if (parts[1] == "cd") { switch (parts[2]) { // go to root case "/": CurrentDirectory = RootDirectory; continue; // go to parent case "..": CurrentDirectory = CurrentDirectory.ParentDirectory; continue; // go to sub default: CurrentDirectory = CurrentDirectory.Directories.Single(dir => dir.Name == parts[2]); break; } } // if none of the about, just skip continue; } // if not a command it is the output from the ls command if (parts[0] == "dir") { CurrentDirectory.Directories.Add(new Directory { Name = parts[1], ParentDirectory = CurrentDirectory }); continue; } // it should be a number indicating the size of a file CurrentDirectory.Files.Add(new File { Name = parts[1], Size = Convert.ToInt32(parts[0]) }); } } internal string GetDirectoriesWithMaxFilesSize(int maxSize) { return GetDirectories(RootDirectory).Where(d => d.GetSizeOfAllFiles() <= maxSize).Sum(d => d.GetSizeOfAllFiles()).ToString(); } internal string GetDirectoriesClosestTo(int totalSize, int sizeNeeded) { sizeNeeded -= totalSize - RootDirectory.GetSizeOfAllFiles(); return GetDirectories(RootDirectory).Where(d => d.GetSizeOfAllFiles() >= sizeNeeded).Min(d => d.GetSizeOfAllFiles()).ToString(); } private IEnumerable GetDirectories(Directory source) { yield return source; foreach (Directory dir in source.Directories.SelectMany(GetDirectories)) { yield return dir; } } } }