Day 7 solution

Cleaned this one up a bit after getting the solve, and did a few things to make Rider quiet.
This commit is contained in:
2022-12-06 23:49:59 -06:00
parent a3b906f94d
commit 8f9b147913
4 changed files with 1150 additions and 1 deletions

View File

@ -39,6 +39,7 @@
<EmbeddedResource Include="inputs\06a.txt" /> <EmbeddedResource Include="inputs\06a.txt" />
<EmbeddedResource Include="inputs\07.txt" /> <EmbeddedResource Include="inputs\07.txt" />
<None Remove="inputs\08.txt" /> <None Remove="inputs\08.txt" />
<EmbeddedResource Include="inputs\07a.txt" />
<EmbeddedResource Include="inputs\08.txt" /> <EmbeddedResource Include="inputs\08.txt" />
<None Remove="inputs\09.txt" /> <None Remove="inputs\09.txt" />
<EmbeddedResource Include="inputs\09.txt" /> <EmbeddedResource Include="inputs\09.txt" />

File diff suppressed because it is too large Load Diff

23
inputs/07a.txt Normal file
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

116
src/07.cs Normal file
View File

@ -0,0 +1,116 @@
namespace aoc2022;
internal class Day07 : Day
{
private class file
{
public long size;
// ReSharper disable once NotAccessedField.Local
public string name = string.Empty;
public override string ToString() => $"{name}, {size:N0}b";
}
private class dir
{
public dir? outer;
public readonly List<dir> dirs = new();
public readonly List<file> files = new();
public string name = string.Empty;
public long size => files.Sum(x => x.size) + dirs.Sum(x => x.size);
public override string ToString() => $"{name}, {size:N0}b, {dirs.Count} dir{(dirs.Count == 1 ? "" : "s")}, {files.Count} file{(files.Count == 1 ? "" : "s")}{(outer != null ? $", parent '{outer.name}'" : "")}";
}
private readonly dir rootDir = new() {name = "/"};
internal override void Parse()
{
dir? curr = null;
foreach (var line in Util.ReadAllLines("07"))
{
if (line.StartsWith("$"))
{
var cmd = line[2..];
string? arg = null;
if (cmd.Contains(' '))
{
arg = cmd[(cmd.IndexOf(' ') + 1)..];
cmd = cmd[..cmd.IndexOf(' ')];
}
if (cmd == "cd")
{
if (arg == "/")
{
curr = rootDir;
}
else if (arg == "..")
{
curr = curr!.outer;
}
else
{
curr = curr!.dirs.First(x => x.name == arg);
}
}
}
else
{
var parts = line.Split(' ');
if (parts[0] == "dir")
{
curr!.dirs.Add(new dir() { name = parts[1], outer = curr });
}
else
{
curr!.files.Add(new file { size = long.Parse(parts[0]), name = parts[1] });
}
}
}
}
private static IEnumerable<dir> GetCandidates(dir root, long? threshold = null)
{
if (threshold == null || root.size <= threshold)
{
yield return root;
}
foreach (var dir in root.dirs)
{
if (threshold == null || dir.size <= threshold)
{
yield return dir;
}
foreach (var d in dir.dirs.SelectMany(d2 => GetCandidates(d2, threshold)))
{
yield return d;
}
}
}
internal override string Part1()
{
List<dir> candidates = new(GetCandidates(rootDir, 100000));
return $"Sum of directories below 100,000 bytes: <+white>{candidates.Sum(x => x.size)}";
}
internal override string Part2()
{
List<dir> flatDirList = new(GetCandidates(rootDir));
var rootSize = rootDir.size;
const int totalSize = 70000000;
var currentFreeSpace = totalSize - rootSize;
const int totalNeededFreeSpace = 30000000;
var neededFreeSpace = totalNeededFreeSpace - currentFreeSpace;
var smallestCandidate = flatDirList.Where(x => x.size >= neededFreeSpace).MinBy(x => x.size);
return $"Smallest directory that can free the required {neededFreeSpace:N0} bytes: <+white>{smallestCandidate!.size}";
}
}