This commit is contained in:
2022-12-07 09:16:17 -05:00
parent 9eaeb9bc08
commit e60775239c
4 changed files with 1309 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
using System.Collections;
namespace AdventOfCode.Problems.AOC2022.Day7;
internal class DirectoryNode
{
public DirectoryNode Parent { get; set; }
public string Name { get; set; }
public string FullPath => GetFullPath();
public List<DirectoryNode> Children { get; set; }
public List<(string name, int size)> Files { get; set; }
public int Size => Files.Sum(f => f.size) + Children.Sum(c => c.Size);
public int LocalSize => Files.Sum(f => f.size);
public DirectoryNode(string name)
{
Name = name;
Files = new();
Children = new();
Parent = this;
}
public DirectoryNode(string name, DirectoryNode parent)
{
Name = name;
Files = new();
Children = new();
Parent = parent;
}
public DirectoryNode(string name, List<(string name, int size)> files)
{
Name = name;
Files = files;
Children = new();
Parent = this;
}
public DirectoryNode AddDirectory(string path)
{
if (path == "/")
return this;
if(string.IsNullOrWhiteSpace(path))
return this;
var segments = path.Split("/").Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
if (segments.Length == 0)
throw new Exception("Invalid Path?");
return AddDirectory(segments);
}
private DirectoryNode AddDirectory(string[] segments)
{
var curSegment = segments[0];
var child = Children.FirstOrDefault(c => c.Name == curSegment);
if (child == null)
{
var node = new DirectoryNode(curSegment, this);
Children.Add(node);
if (segments.Length == 1)
return node;
else
return node.AddDirectory(segments[1..]);
}
else
{
if (segments.Length == 1)
return child;
return child.AddDirectory(segments[1..]);
}
}
public void AddFile(string name, int size)
{
Files.Add((name, size));
}
public DirectoryNode? GetDirectory(string path)
{
if (path == "/")
return this;
var segments = path.Split("/").Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
if (segments.Length == 0)
throw new Exception("Invalid Path?");
return GetDirectory(segments);
}
private DirectoryNode? GetDirectory(string[] segments)
{
if (Children.Count == 0)
return null;
var child = Children.FirstOrDefault(c => c.Name == segments[0]);
if(child == null)
return null;
else
if(segments.Length == 1)
return child;
else
return child.GetDirectory(segments[1..]);
}
public List<DirectoryNode> Where(Func<DirectoryNode, bool> filter)
{
var result = new List<DirectoryNode>();
if(filter(this))
result.Add(this);
result.AddRange(Children.SelectMany(c => c.Where(filter)));
return result;
}
public string GetFullPath()
{
if (Parent == this)
return "";
return $"{Parent.GetFullPath()}/{Name}";
}
public override string ToString()
{
return $"{Name} - {Children.Count}";
}
}

View File

@@ -0,0 +1,74 @@
using AdventOfCode.Runner.Attributes;
namespace AdventOfCode.Problems.AOC2022.Day7;
[ProblemInfo(2022, 7, "No Space Left On Device")]
internal class NoSpace : Problem<int,int>
{
private DirectoryNode _dirTree = new DirectoryNode("/");
public override void CalculatePart1()
{
var dirs = _dirTree.Where(d => d.Size <= 100000);
Part1 = dirs.Sum(d => d.Size);
}
public override void CalculatePart2()
{
var neededPace = 30000000;
var totalSize = 70000000;
var unusedSpace = totalSize - _dirTree.Size;
var targetSize = neededPace - unusedSpace;
var bigEnough = _dirTree.Where(d => d.Size >= targetSize);
Part2 = bigEnough.MinBy(d => d.Size)?.Size ?? 0;
}
public override void LoadInput()
{
var lines = ReadInputLines("input.txt");
var curDir = new Stack<string>();
var dir = "/";
foreach (var line in lines)
{
if (line[0] == '$')
{
ParseCommand(line[2..], ref curDir);
dir = $"/{string.Join("/", curDir.Reverse())}";
_dirTree.AddDirectory(dir);
}else
ReadDirectory(line, _dirTree.GetDirectory(dir)!);
}
}
private static void ReadDirectory(string line, DirectoryNode curDir)
{
if (line.StartsWith("dir"))
return;
var split = line.Split(' ');
var name = split[1];
var size = int.Parse(split[0]);
curDir.AddFile(name, size);
}
private static void ParseCommand(string command, ref Stack<string> curDir)
{
var split = command.Split(' ');
var keyword = split.First();
var param = split.Last();
switch (keyword)
{
case "cd":
if (param == "..")
curDir.Pop();
else if (param == "/")
curDir.Clear();
else
curDir.Push(param);
break;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
$ 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