Added day 7,8,9,10 and did some refactoring

pull/1/head
Alexander Sigler 2 years ago
parent b59de0b037
commit a780576402

@ -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();
}
}
}
}

@ -5,7 +5,7 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace AOC2021.Helper
namespace AdventOfCode.Common
{
public class TextPlainInputFormatter : InputFormatter
{

@ -1,4 +1,4 @@
using AOC2021.Helper;
using AdventOfCode.Common;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;

@ -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<CommandType>(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
}
}

@ -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;
}
}
}

@ -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;

@ -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> DirectoryResult { get; set; }
public ConsoleCommand(IEnumerable<string> commands)
{
ParseCommand(commands);
}
private void ParseCommand(IEnumerable<string> commands)
{
var cmd = commands.First(x => x.StartsWith("$"));
if (cmd == "$ ls")
{
DirectoryResult = new List<DirectoryResult>();
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;
}
}
}

@ -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<ConsoleCommand>();
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;
}
}
}

@ -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];
}
}
}

@ -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<ElfFile> _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<ElfFile>();
}
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<ElfFile> 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 + " ");
}
}
}
}
}

@ -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;
}
}
}

@ -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<Direction>(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<Direction>(line.Split(" ")[0]);
var count = int.Parse(line.Split(" ")[1]);
rope.Move(direction, count);
}
_response.Answer = rope.GetUniqueVisitedByTail();
return _response;
}
}
}

@ -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
}
}

@ -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<string> _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<string>();
//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?");
}
}
}
}

@ -1,5 +1,5 @@
using AdventOfCode.Models;
using AOC2021.Helper;
using AdventOfCode.Common;
using System;
using System.Collections.Generic;
using System.Linq;

@ -1,4 +1,4 @@
using AOC2021.Helper;
using AdventOfCode.Common;
using System;
using System.Collections.Generic;
using System.Linq;

Loading…
Cancel
Save