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 long GetSizeOfAllFiles() => Files.Sum(f => f.Size) + Directories.Sum(d => d.GetSizeOfAllFiles()); } public struct File { public string Name { get; set; } public long Size { get; set; } } internal class DirectoryManager { 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") { // go to root if (parts[2] == "/") { CurrentDirectory = RootDirectory; continue; } if (parts[2] == "..") { CurrentDirectory = CurrentDirectory.ParentDirectory; continue; } CurrentDirectory = CurrentDirectory.Directories.Single(dir => dir.Name == parts[2]); continue; } // 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.ToInt64(parts[0]) }); } } internal string GetDirectoriesWithMaxFilesSize(int maxSize) { return GetDirectories(RootDirectory).Where(d => d.GetSizeOfAllFiles() <= maxSize).Sum(d => d.GetSizeOfAllFiles()).ToString(); } private IEnumerable GetDirectories(Directory root) { yield return root; foreach (Directory dir in root.Directories) yield return dir; } } }