From a780576402bd0d835495a1d0cd8a04293d423092 Mon Sep 17 00:00:00 2001 From: Alexander Sigler Date: Thu, 22 Dec 2022 14:41:35 -0800 Subject: [PATCH] Added day 7,8,9,10 and did some refactoring --- AdventOfCode/Common/AOCExtensions.cs | 14 +- .../Common/TextPlainInputFormatter.cs | 2 +- AdventOfCode/Startup.cs | 2 +- AdventOfCode/_2022/Day10/CommunicationCPU.cs | 81 +++++++++ AdventOfCode/_2022/Day10/Day10.cs | 37 ++++ AdventOfCode/_2022/Day3.cs | 2 +- AdventOfCode/_2022/Day7/ConsoleCommand.cs | 38 +++++ AdventOfCode/_2022/Day7/Day7.cs | 91 ++++++++++ AdventOfCode/_2022/Day7/DirectoryResult.cs | 27 +++ AdventOfCode/_2022/Day7/ElfFile.cs | 74 ++++++++ AdventOfCode/_2022/Day8/Day8.cs | 137 +++++++++++++++ AdventOfCode/_2022/Day9/Day9.cs | 38 +++++ AdventOfCode/_2022/Day9/Direction.cs | 12 ++ AdventOfCode/_2022/Day9/Rope.cs | 159 ++++++++++++++++++ AdventOfCode/_2022/Models/CargoCrateBoard.cs | 2 +- AdventOfCode/_2022/Models/CleaningSection.cs | 2 +- 16 files changed, 712 insertions(+), 6 deletions(-) create mode 100644 AdventOfCode/_2022/Day10/CommunicationCPU.cs create mode 100644 AdventOfCode/_2022/Day10/Day10.cs create mode 100644 AdventOfCode/_2022/Day7/ConsoleCommand.cs create mode 100644 AdventOfCode/_2022/Day7/Day7.cs create mode 100644 AdventOfCode/_2022/Day7/DirectoryResult.cs create mode 100644 AdventOfCode/_2022/Day7/ElfFile.cs create mode 100644 AdventOfCode/_2022/Day8/Day8.cs create mode 100644 AdventOfCode/_2022/Day9/Day9.cs create mode 100644 AdventOfCode/_2022/Day9/Direction.cs create mode 100644 AdventOfCode/_2022/Day9/Rope.cs diff --git a/AdventOfCode/Common/AOCExtensions.cs b/AdventOfCode/Common/AOCExtensions.cs index 526074c..22b02b9 100644 --- a/AdventOfCode/Common/AOCExtensions.cs +++ b/AdventOfCode/Common/AOCExtensions.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; -namespace AOC2021.Helper +namespace AdventOfCode.Common { public static class AOCExtensions { @@ -19,5 +19,17 @@ namespace AOC2021.Helper source = source.Skip(chunksize); } } + + public static void PrintSquareArray(this int[,] arr) + { + for (int x = 0; x < arr.GetLength(0); x++) + { + for (int y = 0; y < arr.GetLength(1); y++) + { + Console.Write(arr[x,y] + " "); + } + Console.WriteLine(); + } + } } } diff --git a/AdventOfCode/Common/TextPlainInputFormatter.cs b/AdventOfCode/Common/TextPlainInputFormatter.cs index 4250c20..07e64ca 100644 --- a/AdventOfCode/Common/TextPlainInputFormatter.cs +++ b/AdventOfCode/Common/TextPlainInputFormatter.cs @@ -5,7 +5,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; -namespace AOC2021.Helper +namespace AdventOfCode.Common { public class TextPlainInputFormatter : InputFormatter { diff --git a/AdventOfCode/Startup.cs b/AdventOfCode/Startup.cs index 3e92133..e0345f2 100644 --- a/AdventOfCode/Startup.cs +++ b/AdventOfCode/Startup.cs @@ -1,4 +1,4 @@ -using AOC2021.Helper; +using AdventOfCode.Common; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; diff --git a/AdventOfCode/_2022/Day10/CommunicationCPU.cs b/AdventOfCode/_2022/Day10/CommunicationCPU.cs new file mode 100644 index 0000000..d37e049 --- /dev/null +++ b/AdventOfCode/_2022/Day10/CommunicationCPU.cs @@ -0,0 +1,81 @@ +using AdventOfCode.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AdventOfCode._2022.Day10 +{ + public class CommunicationCPU + { + private static readonly int[] CHECK_CYCLES = new int[]{20, 60, 100, 140, 180, 220}; + private int _registerX; + private int _cycle; + private int _sumOfStregnth; + private char[] _crtScreen; + private AOCVersion _version; + public CommunicationCPU(AOCVersion version) + { + _version = version; + _registerX = 1; + _cycle = 0; + _sumOfStregnth = 0; + _crtScreen = Enumerable.Repeat(' ', 240).ToArray(); + } + public string PrintCRTScreen() + { + var sb = new StringBuilder(); + for (int i = 1; i <= _crtScreen.Length; i++) + { + sb.Append(_crtScreen[i - 1] + " "); + if (i % 40 == 0) + sb.AppendLine(); + } + sb.AppendLine(); + return sb.ToString(); + } + public int GetCycle() { return _cycle; } + public int GetRegisterValue() { return _registerX; } + public int GetSignalStrength() + { + return _sumOfStregnth; + } + + public void ExecuteInstruction(string instruction) + { + var command = Enum.Parse(instruction.Split(" ")[0].ToUpper()); + if (command == CommandType.NOOP) + { + CheckCycle(); + }else if (command == CommandType.ADDX) + { + var amount = int.Parse(instruction.Split(" ")[1]); + CheckCycle(); + CheckCycle(); + _registerX += amount; + } + } + + private void CheckCycle() + { + if (_version == AOCVersion.B) + { + _crtScreen[_cycle] = Math.Abs((_cycle%40) - _registerX) <= 1 ? '#' : '.'; + } + _cycle++; //Increase it after we draw CRT screen but before we do the cycle check for part A + if (_version == AOCVersion.A && CHECK_CYCLES.Any(x => x == _cycle)) + { + Console.WriteLine($"Cycle {_cycle} has register value of {_registerX} and a strength of {_cycle * _registerX}"); + _sumOfStregnth += _cycle * _registerX; + } + } + + } + + enum CommandType + { + NOOP, + ADDX + } +} diff --git a/AdventOfCode/_2022/Day10/Day10.cs b/AdventOfCode/_2022/Day10/Day10.cs new file mode 100644 index 0000000..a0e80a8 --- /dev/null +++ b/AdventOfCode/_2022/Day10/Day10.cs @@ -0,0 +1,37 @@ +using AdventOfCode._2022.Models; +using AdventOfCode.Common; +using AdventOfCode.Models; +using System; +using System.Linq; + +namespace AdventOfCode._2022.Day10 +{ + [AOC(year: 2022, day: 10)] + public class Day10 : AOCDay + { + protected override AOCResponse ExecutePartA() + { + var cpu = CallCPU(); + _response.Answer = cpu.GetSignalStrength(); + return _response; + } + + protected override AOCResponse ExecutePartB() + { + var cpu = CallCPU(); + _response.Answer = cpu.PrintCRTScreen().Trim().Split("\r\n"); + return _response; + } + + private CommunicationCPU CallCPU() + { + var cpu = new CommunicationCPU(_request.Version); + foreach (var instruction in GetSplitInput()) + { + cpu.ExecuteInstruction(instruction); + Log($"After {instruction}, Cycle:{cpu.GetCycle()} Register: {cpu.GetRegisterValue()}"); + } + return cpu; + } + } +} diff --git a/AdventOfCode/_2022/Day3.cs b/AdventOfCode/_2022/Day3.cs index 7b823e7..b27c8ee 100644 --- a/AdventOfCode/_2022/Day3.cs +++ b/AdventOfCode/_2022/Day3.cs @@ -1,6 +1,6 @@ using AdventOfCode.Common; using AdventOfCode.Models; -using AOC2021.Helper; +using AdventOfCode.Common; using System; using System.Collections.Generic; using System.Linq; diff --git a/AdventOfCode/_2022/Day7/ConsoleCommand.cs b/AdventOfCode/_2022/Day7/ConsoleCommand.cs new file mode 100644 index 0000000..e502b7b --- /dev/null +++ b/AdventOfCode/_2022/Day7/ConsoleCommand.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace AdventOfCode._2022.Day7 +{ + public class ConsoleCommand + { + public string DirectoryTarget { get; set; } + public List DirectoryResult { get; set; } + public ConsoleCommand(IEnumerable commands) + { + ParseCommand(commands); + } + + private void ParseCommand(IEnumerable commands) + { + var cmd = commands.First(x => x.StartsWith("$")); + if (cmd == "$ ls") + { + DirectoryResult = new List(); + foreach (var dirResult in commands.Where(x => !x.StartsWith("$"))) + { + DirectoryResult.Add(new _2022.Day7.DirectoryResult(dirResult)); + } + }else if (cmd.Contains("cd ")) + { + DirectoryTarget = cmd.Split(" ")[2]; + } + } + + public bool IsList() + { + return DirectoryResult != null; + } + } +} diff --git a/AdventOfCode/_2022/Day7/Day7.cs b/AdventOfCode/_2022/Day7/Day7.cs new file mode 100644 index 0000000..a470a19 --- /dev/null +++ b/AdventOfCode/_2022/Day7/Day7.cs @@ -0,0 +1,91 @@ +using AdventOfCode._2022.Models; +using AdventOfCode.Common; +using AdventOfCode.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace AdventOfCode._2022.Day7 +{ + [AOC(year: 2022, day: 7)] + public class Day7 : AOCDay + { + protected override AOCResponse ExecutePartA() + { + var root = GenerateDirectory(); + + root.Print(""); + + var allDirectories = root.GetAllDirectories().ToList(); + _response.Answer = allDirectories.Where(x => x.GetSize() <= 100000).Sum(x => x.GetSize()); + return _response; + } + + protected override AOCResponse ExecutePartB() + { + var root = GenerateDirectory(); + + var takenSpace = root.GetSize(); + var freeSpace = 70000000 - takenSpace; + var neededSpace = 30000000 - freeSpace; + + var allDirectories = root.GetAllDirectories().ToList(); + var directoriesLargeEnough = allDirectories.Where(x => x.GetSize() >= neededSpace); + var smallest = directoriesLargeEnough.OrderBy(x => x.GetSize()).First(); + _response.Answer = smallest.GetSize(); + return _response; + } + + private ElfFile GenerateDirectory() + { + var consoleCommands = new List(); + var input = GetSplitInput(); + + //Create our console commands + int index = 0; + while (index < input.Count()) + { + int take = 1; + while ((index + take) < input.Count() && !input[index + take].StartsWith("$")) + { + take++; + } + consoleCommands.Add(new ConsoleCommand(input.Skip(index).Take(take))); + index += take; + } + + ElfFile root = null; + ElfFile cwd = root; + //Create our file structure + foreach (var cmd in consoleCommands) + { + if (cmd.IsList()) + { + foreach (var file in cmd.DirectoryResult) + { + cwd.AddChild(new ElfFile((file.Size == -1), cwd, file.FileName, file.Size)); + } + } + else + { + if (cmd.DirectoryTarget == "/") + { + root = new ElfFile(true, null, "root"); + root.AddChild(new ElfFile(true, null, "/")); + cwd = root.GetChild("/"); + } + else if (cmd.DirectoryTarget == "..") + { + cwd = cwd.Parent; + } + else + { + cwd = cwd.GetChild(cmd.DirectoryTarget); + } + } + } + return root; + } + } +} diff --git a/AdventOfCode/_2022/Day7/DirectoryResult.cs b/AdventOfCode/_2022/Day7/DirectoryResult.cs new file mode 100644 index 0000000..3fc3a70 --- /dev/null +++ b/AdventOfCode/_2022/Day7/DirectoryResult.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace AdventOfCode._2022.Day7 +{ + public class DirectoryResult + { + public long Size { get; private set; } + public string FileName { get; private set; } + public DirectoryResult(string result) + { + var split = result.Split(" "); + long fileSize; + if (long.TryParse(split[0], out fileSize)) + { + Size = fileSize; + } + else + { + Size = -1; + } + FileName = split[1]; + } + } +} diff --git a/AdventOfCode/_2022/Day7/ElfFile.cs b/AdventOfCode/_2022/Day7/ElfFile.cs new file mode 100644 index 0000000..9a7ee4c --- /dev/null +++ b/AdventOfCode/_2022/Day7/ElfFile.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace AdventOfCode._2022.Day7 +{ + public class ElfFile + { + private long _size; + private string _fileName; + private List _files; + private ElfFile _parentDir; + public ElfFile(bool isDirectory, ElfFile parentDir, string fileName, long fileSize = -1) + { + _parentDir = parentDir; + _size = fileSize; + _fileName = fileName; + if (isDirectory) _files = new List(); + } + + public ElfFile Parent { get { return _parentDir; } } + public string FileName { get { return _fileName; } } + + public bool IsDirectory() + { + return _files != null; + } + + public long GetSize() + { + if (IsDirectory()) + { + var directorySize = _files.Sum(x => x.GetSize()); + return directorySize; + } + return _size; + } + + public void AddChild(ElfFile file) + { + _files.Add(file); + } + public ElfFile GetChild(string childName) + { + try + { + return _files.First(x => x.FileName == childName); + }catch(Exception e) + { + return null; + } + + } + + public IEnumerable GetAllDirectories() + { + var directories = _files.Where(x => x.IsDirectory()); + return directories.Concat(directories.SelectMany(x => x.GetAllDirectories())); + } + + public void Print(string spacing) + { + foreach (var file in _files) + { + Console.WriteLine(spacing + " - " + file.FileName + "(" + file.GetSize() + ")"); + if (file.IsDirectory()) + { + file.Print(spacing + " "); + } + } + } + } +} diff --git a/AdventOfCode/_2022/Day8/Day8.cs b/AdventOfCode/_2022/Day8/Day8.cs new file mode 100644 index 0000000..2ff1fd5 --- /dev/null +++ b/AdventOfCode/_2022/Day8/Day8.cs @@ -0,0 +1,137 @@ +using AdventOfCode._2022.Models; +using AdventOfCode.Common; +using AdventOfCode.Models; +using System; +using System.Linq; + +namespace AdventOfCode._2022.Day8 +{ + [AOC(year: 2022, day: 8)] + public class Day8 : AOCDay + { + protected override AOCResponse ExecutePartA() + { + var board = CreateBoard(); + var maxIndex = board.GetLength(0) - 1; + int visibleTrees = 0; + for (int x = 0; x < board.GetLength(0); x++) + { + for (int y = 0; y < board.GetLength(1); y++) + { + var tree = board[x, y]; + int left = Math.Abs(0 - y), right = maxIndex - y, up = Math.Abs(0 - x), down = maxIndex - x; + if (left == 0 || right == 0 || up == 0 || down == 0) + { + visibleTrees++; + continue; + } + + bool isHiddenLeft = false, isHiddenRight = false, isHiddenUp = false, isHiddenDown = false; + //left + for (int i = 0; i < left; i++) + { + if (board[x, y - (i + 1)] >= tree) isHiddenLeft = true; + } + + //right + for (int i = 0; i < right; i++) + { + if (board[x, y + (i + 1)] >= tree) isHiddenRight = true; + } + + //up + for (int i = 0; i < up; i++) + { + if (board[x - (i + 1), y] >= tree) isHiddenUp = true; + } + + //down + for (int i = 0; i < down; i++) + { + if (board[x + (i + 1), y] >= tree) isHiddenDown = true; + } + + if (!isHiddenLeft || !isHiddenRight || !isHiddenUp || !isHiddenDown) + { + visibleTrees++; + } + } + } + _response.Answer = visibleTrees; + return _response; + } + + protected override AOCResponse ExecutePartB() + { + var board = CreateBoard(); + var maxIndex = board.GetLength(0) - 1; + _response.Answer = 0; + for (int x = 0; x < board.GetLength(0); x++) + { + for (int y = 0; y < board.GetLength(1); y++) + { + var tree = board[x, y]; + int left = Math.Abs(0 - y), right = maxIndex - y, up = Math.Abs(0 - x), down = maxIndex - x; + if (left == 0 || right == 0 || up == 0 || down == 0) + { + continue; //The tree is on the edge so viewing is 0 on one side + } + + int leftTree = 0; + //left + for (int i = 0; i < left; i++) + { + leftTree++; + if (board[x, y - (i + 1)] >= tree) break; + } + + int rightTree = 0; + //right + for (int i = 0; i < right; i++) + { + rightTree++; + if (board[x, y + (i + 1)] >= tree) break; + } + + int upTree = 0; + //up + for (int i = 0; i < up; i++) + { + upTree++; + if (board[x - (i + 1), y] >= tree) break; + } + + int downTree = 0; + //right + for (int i = 0; i < down; i++) + { + downTree++; + if (board[x + (i + 1), y] >= tree) break; + } + + var viewingScore = leftTree * rightTree * upTree * downTree; + Log($"({x},{y}) - {tree} - ({leftTree},{rightTree},{upTree},{downTree}) - ({viewingScore})"); + _response.Answer = Math.Max(viewingScore, (int) _response.Answer); + } + } + return _response; + } + + private int[,] CreateBoard() + { + var splitInput = GetSplitInput(); + var board = new int[splitInput.Length,splitInput.Length]; + + for (int x = 0; x < splitInput.Length; x++) + { + for (int y = 0; y < splitInput[x].Length; y++) + { + board[x,y] = int.Parse(splitInput[x][y].ToString()); + } + } + if (!_request.IgnoreLogMessages) + board.PrintSquareArray(); + return board; + } + } +} diff --git a/AdventOfCode/_2022/Day9/Day9.cs b/AdventOfCode/_2022/Day9/Day9.cs new file mode 100644 index 0000000..5137a89 --- /dev/null +++ b/AdventOfCode/_2022/Day9/Day9.cs @@ -0,0 +1,38 @@ +using AdventOfCode._2022.Models; +using AdventOfCode.Common; +using AdventOfCode.Models; +using System; +using System.Linq; + +namespace AdventOfCode._2022.Day9 +{ + [AOC(year: 2022, day: 9)] + public class Day9 : AOCDay + { + protected override AOCResponse ExecutePartA() + { + var rope = new Rope(1); + foreach (var line in GetSplitInput()) + { + var direction = Enum.Parse(line.Split(" ")[0]); + var count = int.Parse(line.Split(" ")[1]); + rope.Move(direction, count); + } + _response.Answer = rope.GetUniqueVisitedByTail(); + return _response; + } + + protected override AOCResponse ExecutePartB() + { + var rope = new Rope(9); + foreach (var line in GetSplitInput()) + { + var direction = Enum.Parse(line.Split(" ")[0]); + var count = int.Parse(line.Split(" ")[1]); + rope.Move(direction, count); + } + _response.Answer = rope.GetUniqueVisitedByTail(); + return _response; + } + } +} diff --git a/AdventOfCode/_2022/Day9/Direction.cs b/AdventOfCode/_2022/Day9/Direction.cs new file mode 100644 index 0000000..66b25ed --- /dev/null +++ b/AdventOfCode/_2022/Day9/Direction.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace AdventOfCode._2022.Day9 +{ + public enum Direction + { + U,D,L,R + } +} diff --git a/AdventOfCode/_2022/Day9/Rope.cs b/AdventOfCode/_2022/Day9/Rope.cs new file mode 100644 index 0000000..cb91f55 --- /dev/null +++ b/AdventOfCode/_2022/Day9/Rope.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace AdventOfCode._2022.Day9 +{ + public class Rope + { + private RopeEnd[] _rope; + private HashSet _lastTailVisit; + public Rope(int numberOfTails) + { + _rope = new RopeEnd[numberOfTails+1]; + for (int i = 0; i < numberOfTails+1; i++) + _rope[i] = new RopeEnd(); + _lastTailVisit = new HashSet(); + //Print(); + } + + public int GetUniqueVisitedByTail() + { + return _lastTailVisit.Count(); + } + + public void Move(Direction dir, int units) + { + for (int i = 0; i < units; i++) + { + _rope.First().Move(dir); + for (int j = 1; j < _rope.Length; j++) + { + _rope[j].Follow(_rope[j - 1]); + } + _lastTailVisit.Add($"{_rope.Last().X},{_rope.Last().Y}"); + //Print(); + } + } + + //DEBUG + private void Print() + { + var head = _rope.First(); + int size = 14; + for (int x = -size; x < size; x++) + { + for (int y = -size; y < size; y++) + { + if (head.X == y && -head.Y == x) + Console.Write("H "); + else if (_rope.Any(r => r.X == y && -r.Y == x)) + { + var tail = _rope.Select((r, i) => new { Pos = i, Rope = r }) + .First(r => r.Rope.X == y && -r.Rope.Y == x); + Console.Write(tail.Pos + " "); + } + else + { + Console.Write(". "); + } + + } + Console.WriteLine(""); + } + //for (int x = size; x > -size; x--) + //{ + // for (int y = size; y > -size; y--) + // { + // if (_head.X == y && _head.Y == x) + // Console.Write("H "); + // else if (_tail.X == y && _tail.Y == x) + // Console.Write("T "); + // else + // Console.Write(". "); + // } + // Console.WriteLine(""); + //} + Console.WriteLine(); + } + } + + class RopeEnd + { + public int X { get; set; } + public int Y { get; set; } + + public RopeEnd() + { + X = 0; + Y = 0; + } + + public void Move(Direction dir) + { + switch (dir) + { + case Direction.U: + Y++; + break; + case Direction.D: + Y--; + break; + case Direction.L: + X--; + break; + case Direction.R: + X++; + break; + default: + break; + } + } + + public void Follow(RopeEnd head) + { + var distance = Math.Floor(Math.Sqrt((Math.Pow(head.X - X, 2) + Math.Pow(head.Y - Y, 2)))); + if (distance <= 1) return; + //Diagonal Move + if (head.X != X && head.Y != Y) + { + if (head.X > X && head.Y > Y) + { + X++; Y++; + } + else if (head.X > X && head.Y < Y) + { + X++; Y--; + } + else if (head.X < X && head.Y > Y) + { + X--; Y++; + } + else if (head.X < X && head.Y < Y) + { + X--; Y--; + } + else + { + Console.WriteLine("Diag shouldn't happen"); + } + } + else if (head.X == X && head.Y != Y) + { + if (head.Y > Y) Y++; //Head is above + else Y--; //Head below + } + else if (head.Y == Y && head.X != X) + { + if (head.X > X) X++; //Head is to the right of tail + else X--; //Head is to the left + } + else + { + Console.WriteLine("This shouldn't happen?"); + } + + } + } +} diff --git a/AdventOfCode/_2022/Models/CargoCrateBoard.cs b/AdventOfCode/_2022/Models/CargoCrateBoard.cs index 562a08f..ac04390 100644 --- a/AdventOfCode/_2022/Models/CargoCrateBoard.cs +++ b/AdventOfCode/_2022/Models/CargoCrateBoard.cs @@ -1,5 +1,5 @@ using AdventOfCode.Models; -using AOC2021.Helper; +using AdventOfCode.Common; using System; using System.Collections.Generic; using System.Linq; diff --git a/AdventOfCode/_2022/Models/CleaningSection.cs b/AdventOfCode/_2022/Models/CleaningSection.cs index ded7331..19e5923 100644 --- a/AdventOfCode/_2022/Models/CleaningSection.cs +++ b/AdventOfCode/_2022/Models/CleaningSection.cs @@ -1,4 +1,4 @@ -using AOC2021.Helper; +using AdventOfCode.Common; using System; using System.Collections.Generic; using System.Linq;