partial day 14 p2, added empty day 15
This commit is contained in:
parent
eb599df171
commit
a91dd1c661
@ -4,7 +4,7 @@ using AdventOfCode.Core;
|
|||||||
|
|
||||||
InputReader inputReader = new()
|
InputReader inputReader = new()
|
||||||
{
|
{
|
||||||
//IsDebug = true
|
IsDebug = true
|
||||||
};
|
};
|
||||||
|
|
||||||
//inputReader.SetInputByChallange(3);
|
//inputReader.SetInputByChallange(3);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using AdventOfCode.Core.Shared;
|
using AdventOfCode.Core.Shared;
|
||||||
|
using AdventOfCode.Core.Shared.Grid;
|
||||||
|
|
||||||
namespace AdventOfCode.Core
|
namespace AdventOfCode.Core
|
||||||
{
|
{
|
||||||
@ -84,14 +85,14 @@ namespace AdventOfCode.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Grid<T>> ReadToGrid<T>() where T : Node, new()
|
public async Task<Grid<T>> ReadToGrid<T>() where T : Point, new()
|
||||||
{
|
{
|
||||||
Grid<T> result = new();
|
Grid<T> result = new();
|
||||||
int row = 0;
|
int row = 0;
|
||||||
await foreach(string line in ReadAsStringLine())
|
await foreach(string line in ReadAsStringLine())
|
||||||
{
|
{
|
||||||
// create the nodes from the lines
|
// create the nodes from the lines
|
||||||
result.DataGrid.AddRange(line.Select((c, i) => new T { X = i, Y = row, Char = c }));
|
result.DataGrid.AddRange(line.Select((c, i) => new T { X = i, Y = row, Value = c }));
|
||||||
row++;
|
row++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +114,7 @@ namespace AdventOfCode.Core
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// create the nodes from the lines
|
// create the nodes from the lines
|
||||||
result.DataGrid.AddRange(line.Select((c, i) => new T { X = i, Y = row, Char = c }));
|
result.DataGrid.AddRange(line.Select((c, i) => new T { X = i, Y = row, Value = c }));
|
||||||
row++;
|
row++;
|
||||||
}
|
}
|
||||||
yield return result;
|
yield return result;
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
var neighbors = GetNeighbors(current, false);
|
var neighbors = GetNeighbors(current, false);
|
||||||
neighbors = neighbors.Where(n => current.CanMoveTo(n));
|
neighbors = neighbors.Where(n => current.CanMoveTo(current));
|
||||||
|
|
||||||
// calc costs
|
// calc costs
|
||||||
foreach(AStarNode neighbor in neighbors)
|
foreach(AStarNode neighbor in neighbors)
|
||||||
|
|||||||
@ -1,27 +1,29 @@
|
|||||||
namespace AdventOfCode.Core.Shared.A_Star
|
using AdventOfCode.Core.Shared.Grid;
|
||||||
|
|
||||||
|
namespace AdventOfCode.Core.Shared.A_Star
|
||||||
{
|
{
|
||||||
public class AStarNode : Node
|
public class AStarNode : Point
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Distance from start node
|
/// Distance from start node
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int GCost { get; set; } = 0;
|
public long GCost { get; set; } = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Distance from end node
|
/// Distance from end node
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int HCost { get; set; }
|
public long HCost { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Total cost (G + F)
|
/// Total cost (G + F)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int FCost => GCost + HCost;
|
public long FCost => GCost + HCost;
|
||||||
|
|
||||||
public bool? IsClosed { get; private set; } = null;
|
public bool? IsClosed { get; private set; } = null;
|
||||||
|
|
||||||
public AStarNode? ParentNode { get; set; }
|
public AStarNode? ParentNode { get; set; }
|
||||||
|
|
||||||
public AStarNode(Node position) : base(position)
|
public AStarNode(Point position) : base(position)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public AStarNode(int x, int y, char value) : base(x, y, value)
|
public AStarNode(int x, int y, char value) : base(x, y, value)
|
||||||
@ -33,8 +35,10 @@
|
|||||||
|
|
||||||
public bool CanMoveTo(AStarNode target)
|
public bool CanMoveTo(AStarNode target)
|
||||||
{
|
{
|
||||||
int diff = target.Integer - Integer; ;
|
return false;
|
||||||
return diff == 0 || diff == 1;
|
// TODO FIX
|
||||||
|
//int diff = target.Integer - Integer;
|
||||||
|
//return diff == 0 || diff == 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
namespace AdventOfCode.Core.Shared
|
using AdventOfCode.Core.Shared.Grid;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace AdventOfCode.Core.Shared
|
||||||
{
|
{
|
||||||
public class Grid<T> where T : Node
|
public class Grid<T> where T : Point
|
||||||
{
|
{
|
||||||
public List<T> DataGrid { get; set; } = [];
|
public List<T> DataGrid { get; set; } = [];
|
||||||
|
|
||||||
public int Columns => DataGrid.Max(n => n.X) + 1;
|
public long Columns => DataGrid.Max(n => n.X) + 1;
|
||||||
public int Rows => DataGrid.Max(n => n.Y) + 1;
|
public long Rows => DataGrid.Max(n => n.Y) + 1;
|
||||||
|
|
||||||
public Grid() { }
|
public Grid() { }
|
||||||
|
|
||||||
@ -13,12 +16,12 @@
|
|||||||
|
|
||||||
public Grid(IEnumerable<T> data) : this(data.ToArray()) { }
|
public Grid(IEnumerable<T> data) : this(data.ToArray()) { }
|
||||||
|
|
||||||
public IEnumerable<T> GetRow(int rowNumber) => DataGrid.Where(n => n.X == rowNumber);
|
public IEnumerable<T> GetRow(long rowNumber) => DataGrid.Where(n => n.X == rowNumber);
|
||||||
public string GetRowAsString(int columnNumber) => string.Concat(DataGrid.Where(n => n.Y == columnNumber).OrderBy(n => n.X).Select(n => n.Char));
|
public string GetRowAsString(long columnNumber) => string.Concat(DataGrid.Where(n => n.Y == columnNumber).OrderBy(n => n.X).Select(n => n.Value));
|
||||||
public IEnumerable<T> GetColumn(int columnNumber) => DataGrid.Where(n => n.Y == columnNumber);
|
public IEnumerable<T> GetColumn(long columnNumber) => DataGrid.Where(n => n.Y == columnNumber);
|
||||||
public string GetColumnAsString(int rowNumber) => string.Concat(DataGrid.Where(n => n.X == rowNumber).OrderBy(n => n.Y).Select(n => n.Char));
|
public string GetColumnAsString(long rowNumber) => string.Concat(DataGrid.Where(n => n.X == rowNumber).OrderBy(n => n.Y).Select(n => n.Value));
|
||||||
public T GetNode(int x, int y) => DataGrid.First(n => n.X == x && n.Y == y);
|
public T GetNode(long x, long y) => DataGrid.First(n => n.X == x && n.Y == y);
|
||||||
public IEnumerable<T> FindWithValue(char toFind) => DataGrid.Where(n => n.Char == toFind);
|
public IEnumerable<T> FindWithValue(char toFind) => DataGrid.Where(n => n.Value == toFind);
|
||||||
|
|
||||||
public void UpdateNode(T node)
|
public void UpdateNode(T node)
|
||||||
{
|
{
|
||||||
@ -40,7 +43,7 @@
|
|||||||
|| (source.X == target.X && Math.Abs(source.Y - target.Y) <= 1));
|
|| (source.X == target.X && Math.Abs(source.Y - target.Y) <= 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<T> GetSection(int fromX, int fromY, int toX, int toY)
|
public IEnumerable<T> GetSection(long fromX, long fromY, long toX, long toY)
|
||||||
{
|
{
|
||||||
return DataGrid.Where(node => node.X >= fromX && node.X <= toX && node.Y >= fromY && node.Y <= toY);
|
return DataGrid.Where(node => node.X >= fromX && node.X <= toX && node.Y >= fromY && node.Y <= toY);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,22 @@
|
|||||||
using static System.Collections.Specialized.BitVector32;
|
namespace AdventOfCode.Core.Shared.Grid
|
||||||
|
|
||||||
namespace AdventOfCode.Core.Shared.Grid
|
|
||||||
{
|
{
|
||||||
public class Point(long X, long Y)
|
public class Point(long X, long Y) : IEquatable<Point>
|
||||||
{
|
{
|
||||||
public long X { get; set; } = X;
|
public long X { get; set; } = X;
|
||||||
public long Y { get; set; } = Y;
|
public long Y { get; set; } = Y;
|
||||||
|
|
||||||
public string Value { get; set; } = string.Empty;
|
public char Value { get; set; } = ' ';
|
||||||
|
|
||||||
public Point(long X, long Y, string value) : this(X, Y) => Value = value;
|
public Point() : this(-1, -1) { }
|
||||||
|
|
||||||
|
public Point(Point point) : this(point.X, point.Y) { }
|
||||||
|
|
||||||
|
public Point(long X, long Y, char value) : this(X, Y) => Value = value;
|
||||||
|
|
||||||
|
public long DistanceTo(Point other)
|
||||||
|
{
|
||||||
|
return Math.Abs(X - other.X) + Math.Abs(Y - other.Y);
|
||||||
|
}
|
||||||
|
|
||||||
public bool Intersect(Point other)
|
public bool Intersect(Point other)
|
||||||
{
|
{
|
||||||
@ -22,5 +29,23 @@ namespace AdventOfCode.Core.Shared.Grid
|
|||||||
{
|
{
|
||||||
return $"[{Y},{X}] {Value}";
|
return $"[{Y},{X}] {Value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Equals(Point? other)
|
||||||
|
{
|
||||||
|
if (other is null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (this.X != other.X
|
||||||
|
|| this.Y != other.Y
|
||||||
|
|| this.Value != other.Value)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return this.X.GetHashCode() ^ this.Y.GetHashCode() ^ this.Value.GetHashCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,32 +1,15 @@
|
|||||||
namespace AdventOfCode.Core.Shared
|
using AdventOfCode.Core.Shared.Grid;
|
||||||
{
|
|
||||||
public class Node
|
|
||||||
{
|
|
||||||
public int X { get; set; }
|
|
||||||
public int Y { get; set; }
|
|
||||||
public char Char { get; set; }
|
|
||||||
public short Integer => (short)Char;
|
|
||||||
|
|
||||||
public Node() { }
|
namespace AdventOfCode.Core.Shared
|
||||||
|
|
||||||
public Node(int x, int y, char character)
|
|
||||||
{
|
{
|
||||||
X = x;
|
public class Node(long X, long Y, char value) : Point(X, Y, value)
|
||||||
Y = y;
|
|
||||||
Char = character;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Node(Node position) : this(position.X, position.Y, position.Char)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
public int DistanceTo(Node other)
|
|
||||||
{
|
{
|
||||||
return Math.Abs(X - other.X) + Math.Abs(Y - other.Y);
|
public Node() : this(-1, -1, '0') { }
|
||||||
}
|
public Node(long X, long Y) : this(X, Y, ' ') { }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"[{Y},{X}] {Char}";
|
return $"[{Y},{X}] {Value}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@ namespace AdventOfCode.Solutions._2023
|
|||||||
{
|
{
|
||||||
var (Numbers, Symbols) = await GetNumbersAndSymbols();
|
var (Numbers, Symbols) = await GetNumbersAndSymbols();
|
||||||
return Symbols
|
return Symbols
|
||||||
.Where(s => s.Value == "*")
|
.Where(s => s.Value == '*')
|
||||||
.Select(g => Numbers.Where(n => n.Intersect(g)))
|
.Select(g => Numbers.Where(n => n.Intersect(g)))
|
||||||
.Where(n => n.Count() == 2)
|
.Where(n => n.Count() == 2)
|
||||||
.Select(num => int.Parse(num.First().Value) * int.Parse(num.Last().Value))
|
.Select(num => int.Parse(num.First().Value) * int.Parse(num.Last().Value))
|
||||||
@ -57,7 +57,7 @@ namespace AdventOfCode.Solutions._2023
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Rectangle> numbers = parts.Where(p => p.IsDigit()).Select(number => new Rectangle(new Point(number.X - 1, number.Y - 1), new Point(number.X + number.Length, number.Y + 1), number.Section)).ToList();
|
List<Rectangle> numbers = parts.Where(p => p.IsDigit()).Select(number => new Rectangle(new Point(number.X - 1, number.Y - 1), new Point(number.X + number.Length, number.Y + 1), number.Section)).ToList();
|
||||||
List<Point> symbols = parts.Where(p => p.IsPartSymbol()).Select(symbol => new Point(symbol.X, symbol.Y, symbol.Section)).ToList();
|
List<Point> symbols = parts.Where(p => p.IsPartSymbol()).Select(symbol => new Point(symbol.X, symbol.Y, symbol.Section[0])).ToList();
|
||||||
|
|
||||||
return (numbers, symbols);
|
return (numbers, symbols);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -155,7 +155,7 @@ namespace AdventOfCode.Solutions._2023
|
|||||||
|
|
||||||
if (lastId < currentSeedRange.End.X)
|
if (lastId < currentSeedRange.End.X)
|
||||||
{
|
{
|
||||||
Line map = new(new Point(lastId, 0, ""), currentSeedRange.End);
|
Line map = new(new Point(lastId, 0, ' '), currentSeedRange.End);
|
||||||
resultRanges.Add(map);
|
resultRanges.Add(map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using AdventOfCode.Core;
|
using AdventOfCode.Core;
|
||||||
|
using AdventOfCode.Core.Shared.Grid;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
namespace AdventOfCode.Solutions._2023
|
namespace AdventOfCode.Solutions._2023
|
||||||
@ -31,17 +32,17 @@ namespace AdventOfCode.Solutions._2023
|
|||||||
|
|
||||||
if (value.Steps >= 0) // this is in the main loop
|
if (value.Steps >= 0) // this is in the main loop
|
||||||
{
|
{
|
||||||
if (value.Char == '-') // never crosses, also to not update prev
|
if (value.Value == '-') // never crosses, also to not update prev
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((prevSegment == 'L' && value.Char == '7') // this is L7 meaning that there is no crossing
|
if ((prevSegment == 'L' && value.Value == '7') // this is L7 meaning that there is no crossing
|
||||||
|| prevSegment == 'F' && value.Char == 'J') // this is FJ meaning that there is no crossing
|
|| prevSegment == 'F' && value.Value == 'J') // this is FJ meaning that there is no crossing
|
||||||
{
|
{
|
||||||
prevSegment = value.Char;
|
prevSegment = value.Value;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
prevSegment = value.Char;
|
prevSegment = value.Value;
|
||||||
pipesCrossed++;
|
pipesCrossed++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -60,7 +61,7 @@ namespace AdventOfCode.Solutions._2023
|
|||||||
startPipe.Steps = 0;
|
startPipe.Steps = 0;
|
||||||
|
|
||||||
Pipe[] lineToWalk = grid.GetNeighbors(startPipe, false)
|
Pipe[] lineToWalk = grid.GetNeighbors(startPipe, false)
|
||||||
.Where(n => n.Char != '.')
|
.Where(n => n.Value != '.')
|
||||||
.Where(n => n.GetNeighbors().Any(np => np.X == startPipe.X && np.Y == startPipe.Y))
|
.Where(n => n.GetNeighbors().Any(np => np.X == startPipe.X && np.Y == startPipe.Y))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
@ -99,9 +100,9 @@ namespace AdventOfCode.Solutions._2023
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Pipe : Node
|
public class Pipe : Point
|
||||||
{
|
{
|
||||||
public Pipe From { get; set; }
|
public Pipe From { get; set; } = null;
|
||||||
|
|
||||||
public int Steps { get; set; } = -1;
|
public int Steps { get; set; } = -1;
|
||||||
|
|
||||||
@ -115,7 +116,7 @@ namespace AdventOfCode.Solutions._2023
|
|||||||
|
|
||||||
public IEnumerable<Pipe> GetNeighbors()
|
public IEnumerable<Pipe> GetNeighbors()
|
||||||
{
|
{
|
||||||
switch (Char)
|
switch (Value)
|
||||||
{
|
{
|
||||||
case '|':
|
case '|':
|
||||||
yield return GetNorth();
|
yield return GetNorth();
|
||||||
|
|||||||
@ -1,4 +1,9 @@
|
|||||||
using AdventOfCode.Core;
|
using AdventOfCode.Core;
|
||||||
|
using AdventOfCode.Core.Shared.Grid;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.ExceptionServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks.Dataflow;
|
||||||
|
|
||||||
namespace AdventOfCode.Solutions._2023
|
namespace AdventOfCode.Solutions._2023
|
||||||
{
|
{
|
||||||
@ -8,38 +13,154 @@ namespace AdventOfCode.Solutions._2023
|
|||||||
|
|
||||||
public async Task<string> GetSolutionPart1()
|
public async Task<string> GetSolutionPart1()
|
||||||
{
|
{
|
||||||
string[] lines = await _inputReader.ReadAsVerticalArrayString();
|
Grid<Point> grid = await _inputReader.ReadToGrid<Point>();
|
||||||
int totalWeight = 0;
|
HashSet<Point> bolders = grid.FindWithValue('O').Select(p => new Point(p.X, p.Y)).ToHashSet();
|
||||||
for(int lineIndex = 0; lineIndex < lines.Length; lineIndex++)
|
HashSet<Point> cubes = grid.FindWithValue('#').Select(p => new Point(p.X, p.Y)).ToHashSet();
|
||||||
{
|
|
||||||
int weight = lines[lineIndex].Length, lineWeight = 0;
|
|
||||||
for (int charIndex = 0; charIndex < lines[lineIndex].Length; charIndex++)
|
|
||||||
{
|
|
||||||
if (lines[lineIndex][charIndex] is '.')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (lines[lineIndex][charIndex] is '#')
|
bolders = MoveUp(bolders, cubes);
|
||||||
{
|
|
||||||
weight = lines[lineIndex].Length - charIndex - 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lines[lineIndex][charIndex] is 'O')
|
return bolders.Sum(bolder => grid.Rows - bolder.Y).ToString();
|
||||||
{
|
|
||||||
lineWeight += weight;
|
|
||||||
weight--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
totalWeight += lineWeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
return totalWeight.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> GetSolutionPart2()
|
public async Task<string> GetSolutionPart2()
|
||||||
{
|
{
|
||||||
return string.Empty;
|
long maxCycles = 1_000_000_000;
|
||||||
|
Dictionary<string, int> mapStates = [];
|
||||||
|
bool foundLoop = false;
|
||||||
|
|
||||||
|
Grid<Point> grid = await _inputReader.ReadToGrid<Point>();
|
||||||
|
HashSet<Point> bolders = grid.FindWithValue('O').Select(p => new Point(p.X, p.Y)).ToHashSet();
|
||||||
|
HashSet<Point> cubes = grid.FindWithValue('#').Select(p => new Point(p.X, p.Y)).ToHashSet();
|
||||||
|
|
||||||
|
for (int currentCycle = 0; currentCycle < maxCycles; currentCycle++)
|
||||||
|
{
|
||||||
|
mapStates.TryAdd(CreateStringMap(bolders, cubes, grid.Rows, grid.Columns), currentCycle);
|
||||||
|
|
||||||
|
bolders = MoveUp(bolders, cubes);
|
||||||
|
bolders = MoveLeft(bolders, cubes);
|
||||||
|
bolders = MoveDown(bolders, cubes, grid.Rows);
|
||||||
|
bolders = MoveRight(bolders, cubes, grid.Columns);
|
||||||
|
|
||||||
|
if (foundLoop) continue;
|
||||||
|
|
||||||
|
int hash = bolders.GetHashCode();
|
||||||
|
if (mapStates.TryGetValue(CreateStringMap(bolders, cubes, grid.Rows, grid.Columns), out int prevCycle))
|
||||||
|
{
|
||||||
|
// calculate remaining cycles to the first exit point
|
||||||
|
long remainingCycles = (maxCycles - prevCycle) % (currentCycle + 1 - prevCycle) + 1;
|
||||||
|
// set the total the first exit point
|
||||||
|
maxCycles = remainingCycles + currentCycle;
|
||||||
|
foundLoop = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return bolders.Sum(bolder => grid.Rows - bolder.Y).ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashSet<Point> MoveUp(HashSet<Point> bolders, HashSet<Point> cubes)
|
||||||
|
{
|
||||||
|
HashSet<Point> boldersMoved = [];
|
||||||
|
foreach (Point bolder in bolders.OrderBy(bolder => bolder.Y) )
|
||||||
|
{
|
||||||
|
// current location
|
||||||
|
long ySearch = bolder.Y;
|
||||||
|
while (ySearch - 1 >= 0 // ensure in map
|
||||||
|
&& !boldersMoved.Contains(new(bolder.X, ySearch - 1)) // check that the next tile does not have a bolder
|
||||||
|
&& !cubes.Contains(new(bolder.X, ySearch - 1))) // check that the next tile has not cube
|
||||||
|
{
|
||||||
|
ySearch--; // move to next
|
||||||
|
}
|
||||||
|
|
||||||
|
// something found on next location so place bolder here
|
||||||
|
boldersMoved.Add(new(bolder.X, ySearch));
|
||||||
|
}
|
||||||
|
|
||||||
|
return boldersMoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashSet<Point> MoveDown(HashSet<Point> bolders, HashSet<Point> cubes, long ySize)
|
||||||
|
{
|
||||||
|
HashSet<Point> boldersMoved = [];
|
||||||
|
foreach (Point bolder in bolders.OrderBy(bolder => bolder.Y))
|
||||||
|
{
|
||||||
|
// current location
|
||||||
|
long ySearch = bolder.Y;
|
||||||
|
while (ySearch + 1 < ySize // ensure in map
|
||||||
|
&& !boldersMoved.Contains(new(bolder.X, ySearch + 1)) // check that the next tile does not have a bolder
|
||||||
|
&& !cubes.Contains(new(bolder.X, ySearch + 1))) // check that the next tile has not cube
|
||||||
|
{
|
||||||
|
ySearch++; // move to next
|
||||||
|
}
|
||||||
|
|
||||||
|
// something found on next location so place bolder here
|
||||||
|
boldersMoved.Add(new(bolder.X, ySearch));
|
||||||
|
}
|
||||||
|
|
||||||
|
return boldersMoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashSet<Point> MoveLeft(HashSet<Point> bolders, HashSet<Point> cubes)
|
||||||
|
{
|
||||||
|
HashSet<Point> boldersMoved = [];
|
||||||
|
foreach (Point bolder in bolders.OrderBy(bolder => bolder.X))
|
||||||
|
{
|
||||||
|
// current location
|
||||||
|
long xSearch = bolder.X;
|
||||||
|
while (xSearch - 1 >= 0 // ensure in map
|
||||||
|
&& !boldersMoved.Contains(new(xSearch, bolder.Y)) // check that the next tile does not have a bolder
|
||||||
|
&& !cubes.Contains(new(xSearch, bolder.Y))) // check that the next tile has not cube
|
||||||
|
{
|
||||||
|
xSearch--; // move to next
|
||||||
|
}
|
||||||
|
|
||||||
|
// something found on next location so place bolder here
|
||||||
|
boldersMoved.Add(new(xSearch, bolder.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
return boldersMoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashSet<Point> MoveRight(HashSet<Point> bolders, HashSet<Point> cubes, long xSize)
|
||||||
|
{
|
||||||
|
HashSet<Point> boldersMoved = [];
|
||||||
|
foreach (Point bolder in bolders.OrderBy(bolder => bolder.Y))
|
||||||
|
{
|
||||||
|
// current location
|
||||||
|
long xSearch = bolder.Y;
|
||||||
|
while (xSearch + 1 < xSize // ensure in map
|
||||||
|
&& !boldersMoved.Contains(new(xSearch, bolder.Y)) // check that the next tile does not have a bolder
|
||||||
|
&& !cubes.Contains(new(xSearch, bolder.Y))) // check that the next tile has not cube
|
||||||
|
{
|
||||||
|
xSearch++; // move to next
|
||||||
|
}
|
||||||
|
|
||||||
|
// something found on next location so place bolder here
|
||||||
|
boldersMoved.Add(new(xSearch, bolder.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
return boldersMoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string CreateStringMap(HashSet<Point> bolders, HashSet<Point> cubess, long maxX, long maxY)
|
||||||
|
{
|
||||||
|
var stringBuilder = new StringBuilder();
|
||||||
|
for (var y = 0; y < maxY; y++)
|
||||||
|
{
|
||||||
|
for (var x = 0; x < maxX; x++)
|
||||||
|
{
|
||||||
|
if (bolders.Contains(new Point(x, y)))
|
||||||
|
stringBuilder.Append('O');
|
||||||
|
else if (cubess.Contains(new Point(x, y)))
|
||||||
|
stringBuilder.Append('#');
|
||||||
|
else
|
||||||
|
stringBuilder.Append('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
stringBuilder.AppendLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringBuilder.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
19
AdventOfCode.Solutions/2023/Day 15/Day15.cs
Normal file
19
AdventOfCode.Solutions/2023/Day 15/Day15.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using AdventOfCode.Core;
|
||||||
|
|
||||||
|
namespace AdventOfCode.Solutions._2023
|
||||||
|
{
|
||||||
|
public class Day15(InputReader reader) : IChallange
|
||||||
|
{
|
||||||
|
private InputReader _inputReader = reader;
|
||||||
|
|
||||||
|
public async Task<string> GetSolutionPart1()
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> GetSolutionPart2()
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
0
AdventOfCode.Solutions/2023/Day 15/day-15-input.txt
Normal file
0
AdventOfCode.Solutions/2023/Day 15/day-15-input.txt
Normal file
Loading…
Reference in New Issue
Block a user