Skip to content

Commit

Permalink
day 6 part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
KaterynaKateryna committed Dec 7, 2024
1 parent dec16c1 commit e9a2eff
Showing 1 changed file with 131 additions and 17 deletions.
148 changes: 131 additions & 17 deletions AdventOfCode/Day06.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,32 @@ public Day06()

public override ValueTask<string> Solve_1()
{
HashSet<Point> visitedLocations = new HashSet<Point>();
return new(GetOriginalRoute().Count.ToString());
}

public override ValueTask<string> Solve_2()
{
int loops = 0;

Point currentGuardPoint = GetGuard();
Direction currentGuardDirection = Direction.Up;
visitedLocations.Add(currentGuardPoint);

while (true)
HashSet<Point> originalLocationsVisited = GetOriginalRoute();
originalLocationsVisited.Remove(currentGuardPoint);

List<Point> obstacles = GetObstacles();

foreach (var originalLocation in originalLocationsVisited)
{
try
obstacles.Add(originalLocation);
if (CanCreateALoop(currentGuardPoint, currentGuardDirection, obstacles))
{
(currentGuardPoint, currentGuardDirection) = GetNextMove(currentGuardPoint, currentGuardDirection);
visitedLocations.Add(currentGuardPoint);
}
catch (IndexOutOfRangeException)
{
break;
loops++;
}
obstacles.Remove(originalLocation);
}


return new(visitedLocations.Count.ToString());
}

public override ValueTask<string> Solve_2()
{
return new("");
return new(loops.ToString());
}

private Point GetGuard()
Expand All @@ -53,6 +54,45 @@ private Point GetGuard()
throw new Exception("Guard not found.");
}

private List<Point> GetObstacles()
{
List<Point> obstacles = new List<Point>();
for (int i = 0; i < _map.Length; ++i)
{
for (int j = 0; j < _map[0].Length; ++j)
{
if (_map[i][j] == '#')
{
obstacles.Add(new Point(i, j));
}
}
}
return obstacles;
}

private HashSet<Point> GetOriginalRoute()
{
HashSet<Point> visitedLocations = new HashSet<Point>();
Point currentGuardPoint = GetGuard();
Direction currentGuardDirection = Direction.Up;
visitedLocations.Add(currentGuardPoint);

while (true)
{
try
{
(currentGuardPoint, currentGuardDirection) = GetNextMove(currentGuardPoint, currentGuardDirection);
visitedLocations.Add(currentGuardPoint);
}
catch (IndexOutOfRangeException)
{
break;
}
}

return visitedLocations;
}

private (Point point, Direction direction) GetNextMove(Point point, Direction direction)
{
switch (direction)
Expand Down Expand Up @@ -98,8 +138,82 @@ private Point GetGuard()
throw new NotImplementedException();
}

private PointWithDirection? GetNextMove2(
PointWithDirection point,
Dictionary<int, List<int>> obstaclesByI,
Dictionary<int, List<int>> obstaclesByJ
)
{
switch (point.Direction)
{
case Direction.Up:
if(obstaclesByJ.TryGetValue(point.J, out List<int>? rows) && rows.Any(x => x < point.I))
{
int row = rows.Last(x => x < point.I);
return new PointWithDirection(row + 1, point.J, Direction.Right);
}
return null;
case Direction.Right:
if (obstaclesByI.TryGetValue(point.I, out List<int>? columns) && columns.Any(x => x > point.J))
{
int column = columns.First(x => x > point.J);
return new PointWithDirection(point.I, column - 1, Direction.Down);
}
return null;
case Direction.Down:
if (obstaclesByJ.TryGetValue(point.J, out List<int>? rows2) && rows2.Any(x => x > point.I))
{
int row = rows2.First(x => x > point.I);
return new PointWithDirection(row - 1, point.J, Direction.Left);
}
return null;
case Direction.Left:
if (obstaclesByI.TryGetValue(point.I, out List<int>? columns2) && columns2.Any(x => x < point.J))
{
int column = columns2.Last(x => x < point.J);
return new PointWithDirection(point.I, column + 1, Direction.Up);
}
return null;
}

throw new NotImplementedException();
}

private bool CanCreateALoop(Point startingPoint, Direction startingDirection, List<Point> obstacles)
{
HashSet<PointWithDirection> visited = new HashSet<PointWithDirection>();
PointWithDirection? currentPointWithDirection = new PointWithDirection(startingPoint.I, startingPoint.J, startingDirection);
visited.Add(currentPointWithDirection);

Dictionary<int, List<int>> obstaclesByI = obstacles
.GroupBy(x => x.I)
.ToDictionary(x => x.Key, x => x.Select(y => y.J).OrderBy(y => y).ToList());

Dictionary<int, List<int>> obstaclesByJ = obstacles
.GroupBy(x => x.J)
.ToDictionary(x => x.Key, x => x.Select(y => y.I).OrderBy(y => y).ToList());


while (true)
{
currentPointWithDirection = GetNextMove2(currentPointWithDirection, obstaclesByI, obstaclesByJ);
if (currentPointWithDirection == null)
{
return false;
}
if (!visited.Add(currentPointWithDirection))
{
return true;
}
}

throw new Exception("Unreachable code");
}

private record Point(int I, int J);

private record PointWithDirection(int I, int J, Direction Direction);

private enum Direction
{
Up,
Expand Down

0 comments on commit e9a2eff

Please sign in to comment.