Day 7
This commit is contained in:
123
AdventOfCode/Problems/AOC2022/Day7/DirectoryNode.cs
Normal file
123
AdventOfCode/Problems/AOC2022/Day7/DirectoryNode.cs
Normal 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}";
|
||||||
|
}
|
||||||
|
}
|
||||||
74
AdventOfCode/Problems/AOC2022/Day7/NoSpace.cs
Normal file
74
AdventOfCode/Problems/AOC2022/Day7/NoSpace.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1089
AdventOfCode/Problems/AOC2022/Day7/input.txt
Normal file
1089
AdventOfCode/Problems/AOC2022/Day7/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
23
AdventOfCode/Problems/AOC2022/Day7/test.txt
Normal file
23
AdventOfCode/Problems/AOC2022/Day7/test.txt
Normal 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
|
||||||
Reference in New Issue
Block a user