Initial Commit
This commit is contained in:
205
2022/Day07CSharp/Program.cs
Normal file
205
2022/Day07CSharp/Program.cs
Normal file
@@ -0,0 +1,205 @@
|
||||
// See https://aka.ms/new-console-template for more information
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Xml;
|
||||
|
||||
Console.WriteLine("Hello, World!");
|
||||
|
||||
Directory exampleRoot = LoadData("example-input.txt");
|
||||
Directory puzzleRoot = LoadData("puzzle-input.txt");
|
||||
|
||||
Console.WriteLine(String.Format("Part01: Example({0}), Puzzle({1})", Part01(exampleRoot, 100000), Part01(puzzleRoot, 100000)));
|
||||
|
||||
Console.WriteLine(String.Format("Part02: Example({0}), Puzzle({1})" , Part02(exampleRoot, 70000000 - exampleRoot.Size, 30000000, exampleRoot.Size)
|
||||
, Part02(puzzleRoot, 70000000 - puzzleRoot.Size, 30000000, puzzleRoot.Size)));
|
||||
|
||||
int Part01(Directory root, int maxsize)
|
||||
{
|
||||
int returnSize = 0;
|
||||
int size = 0;
|
||||
|
||||
foreach (var file in root.Files)
|
||||
{
|
||||
size += file.Size;
|
||||
}
|
||||
foreach (var subdir in root.SubDirectories)
|
||||
{
|
||||
size += subdir.Size;
|
||||
}
|
||||
|
||||
if (size < maxsize) returnSize += size;
|
||||
|
||||
foreach (var subdir in root.SubDirectories)
|
||||
{
|
||||
returnSize += Part01(subdir, maxsize);
|
||||
}
|
||||
|
||||
return returnSize;
|
||||
}
|
||||
|
||||
int Part02(Directory root, int unusedSpace, int targetUnusedSpace, int returnSize)
|
||||
{
|
||||
if (unusedSpace + root.Size > targetUnusedSpace)
|
||||
{
|
||||
returnSize = Int32.Min(returnSize, root.Size);
|
||||
}
|
||||
|
||||
|
||||
foreach (var subdir in root.SubDirectories)
|
||||
{
|
||||
returnSize = Int32.Min(returnSize, Part02(subdir, unusedSpace, targetUnusedSpace, returnSize));
|
||||
}
|
||||
|
||||
return returnSize;
|
||||
}
|
||||
|
||||
Directory LoadData(string fileName)
|
||||
{
|
||||
Directory root = new Directory("/", null);
|
||||
Directory currentDir = root;
|
||||
|
||||
using (StreamReader reader = System.IO.File.OpenText(fileName))
|
||||
{
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
string? line = reader.ReadLine();
|
||||
if (line == null) throw new InvalidDataException();
|
||||
if (line.Length == 0) continue;
|
||||
|
||||
// We should be reading commands here
|
||||
if (line.StartsWith('$'))
|
||||
{
|
||||
var split = line.Split(' ');
|
||||
|
||||
if (split[1].StartsWith("cd"))
|
||||
{
|
||||
if (split.Length != 3)
|
||||
{
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
currentDir = HandleChangeDirectory(reader, split[2], currentDir);
|
||||
}
|
||||
else if (split[1].StartsWith("ls"))
|
||||
{
|
||||
currentDir = HandleListDirectory(reader, currentDir);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
Directory HandleListDirectory(StreamReader reader, Directory currentDir)
|
||||
{
|
||||
while (!reader.EndOfStream && reader.Peek() != '$')
|
||||
{
|
||||
string? line = reader.ReadLine();
|
||||
if (line == null) throw new InvalidDataException();
|
||||
|
||||
var split = line.Split(" ");
|
||||
|
||||
int size = 0;
|
||||
|
||||
if (split[0].StartsWith("dir"))
|
||||
{
|
||||
if (currentDir.SubDirectories.Exists(x => x.Name.StartsWith(split[1])))
|
||||
{
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
currentDir.SubDirectories.Add(new Directory(split[1], currentDir));
|
||||
}
|
||||
else if (Int32.TryParse(split[0], out size))
|
||||
{
|
||||
if (currentDir.Files.Exists(x => x.Name == split[1]))
|
||||
{
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
currentDir.Files.Add(new File(split[1], size));
|
||||
}
|
||||
else
|
||||
{ throw new InvalidDataException(); }
|
||||
}
|
||||
|
||||
return currentDir;
|
||||
}
|
||||
|
||||
Directory HandleChangeDirectory(StreamReader reader, string argument, Directory currentDir)
|
||||
{
|
||||
switch (argument)
|
||||
{
|
||||
case "/":
|
||||
while (currentDir != null && !currentDir.Name.StartsWith("/"))
|
||||
{
|
||||
if (currentDir.Parent == null) throw new InvalidDataException();
|
||||
currentDir = currentDir.Parent;
|
||||
}
|
||||
return currentDir;
|
||||
|
||||
case "..":
|
||||
if (currentDir.Parent == null)
|
||||
{
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
|
||||
currentDir = currentDir.Parent;
|
||||
return currentDir;
|
||||
|
||||
default:
|
||||
foreach (var subdir in currentDir.SubDirectories)
|
||||
{
|
||||
if (subdir.Name == argument)
|
||||
{
|
||||
currentDir = subdir;
|
||||
return currentDir;
|
||||
}
|
||||
}
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
}
|
||||
|
||||
class File
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Size { get; set; }
|
||||
|
||||
public File(string name, int size)
|
||||
{
|
||||
Name = name;
|
||||
Size = size;
|
||||
}
|
||||
}
|
||||
class Directory
|
||||
{
|
||||
public List<Directory> SubDirectories { get; set; } = new List<Directory>();
|
||||
public List<File> Files { get; set; } = new List<File>();
|
||||
public Directory? Parent { get; set; } = null;
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public Directory(string name, Directory parent) { Name = name; Parent = parent; }
|
||||
|
||||
public int Size
|
||||
{
|
||||
get
|
||||
{
|
||||
int size = 0;
|
||||
|
||||
foreach (var subdir in SubDirectories)
|
||||
{
|
||||
size += subdir.Size;
|
||||
}
|
||||
foreach (var file in Files)
|
||||
{
|
||||
size += file.Size;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user