Skip to content

Commit

Permalink
Day 15 part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
jongeorge1 committed Feb 21, 2019
1 parent 78bf6cc commit 62505c2
Show file tree
Hide file tree
Showing 18 changed files with 650 additions and 1 deletion.
3 changes: 3 additions & 0 deletions AoC2018.Runner/AoC2018.Runner.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
<None Update="Input\day04.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Input\day15.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Input\day14.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
32 changes: 32 additions & 0 deletions AoC2018.Runner/Input/day15.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
################################
######..#######.################
######...######..#.#############
######...#####.....#############
#####....###G......#############
#####.#G..#..GG..##########..#.#
#######G..G.G.....##..###......#
######....G...........#.....####
#######.G......G........##..####
######..#..G.......E...........#
######..G................E..E..#
####.............E..........#..#
#####.........#####........##..#
########.....#######.......#####
########..G.#########......#####
#######.....#########....#######
#######G....#########..G...##.##
#.#.....GG..#########E##...#..##
#.#....G....#########.##...#...#
#....##......#######..###..##E.#
####G.........#####...####....##
####..G...............######..##
####....#.....##############.###
#..#..###......#################
#..#..###......#################
#.....#####....#################
###########.E.E.################
###########.E...################
###########.E..#################
#############.##################
#############.##################
################################
50 changes: 50 additions & 0 deletions AoC2018.Runner/Input/day18.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
||.|..#|.|.....|..|........|..#..|#...|.........#.
...#....|#..|......#.|||...#...|...#....|.......#.
##.#|.#..|.#|....||.|#.#....#.#.###.|..|...|#.#|..
..||.#|#|#..#.#|...|....||.|...##.....|.....#...#|
#|..#...#.##|.|.##||..|...|...#||.|...#.##.###|.|.
#.#||#...#.|#.....|#.......|#.||..|..|#..#.##...#.
|.||.|.|........|.|.#.|...##.|.||..#....#..|.|#..#
....#...|#...#....|#.|.|||#.||#....||.......|.#|..
|#..#..#.|.|#.||#...|.|...|#.||...#...##....|....|
..#...|......#.#...|#...#|.|......#.|||#.|#.|#.#.|
..##.#|#|...||....##|.|||.|##|#.....#|...#...###||
...||......#...|....#.....#|#......#......#..|.|#.
..........#|.|#..|..#.##.#...#|...#..#...|...#|.||
|.#..#|###..||...|#|....|...........|...#|#.#..#|.
|.#..##.........#||.....|#|.###.#.|.....#.|..|.##.
....#||..#|...|.#...#.|.#.|..#............#.|.....
...|#...##.#.#.|.||.......#...|.....###.||...##..|
..|...|#.|.#..|..#|..||.#.....#||.|..#..|..|.||.#.
#.##||#.#.....||.|.#.......#.|.##|##|#..#|.....|#.
...#..#.#..#.|.....|.#...|.....###||||..#..##...#.
...|...|.|.##|..#.#|#....#.#.|#||||....#...|||.#.#
..|...##..|#||..||#|#..|..|##.|..##...#...#|.##.#|
|#...#.#.......|...||...##.|.||#.....#.||.......#|
..#.....#|.#...#...|.#|.#.#|.....#.##.#|.....#....
......#|..|||.#.#..||..|.|..|...##.....#..#.###...
....##..#..|..||..##.||#.|..|.#...#..||#...#..|...
.||......||#.#|#.##.||.#..|..#..#..#.|..|#|..||...
|...#|...|....|.|.|.....||.|.|..|#.#.#..|.#..##..#
..|..#..#.|.##.....|#..|..#|.|..#.#.|..|..#|..|...
....|...#..|#...#.###.|..####..||#..|.|.|......||.
.....||.#.|##|.....|##.||.##..#.#.|...#.#...||.#..
.|#..#.|...||#..|.#..#....###.#...#.....||......##
||...#||..#...##.|..|...|#.|#|.|##|#|##....#..#|..
.|..#.##..|......#|.....||..|||||||#.#.|#..|.|.|..
|#.##.|............##||##.#...#.#........|..#.....
.||....|.#||#|.#..|..........#....##.#.|...#.||..|
......|...#.......##.#.#|#......#||##...#..#||.|#.
..||.#..#.#.......|.|.##.#.|...#...###..|...|..|..
.#....|..||##.|.|..#.|.#|..#|......#....#.#.|..||.
.........|....|.#..|...|.|#....#..|.....#...|#|#.|
.|.||..|#.|...##.|.#...#..|.||||..##.##|#.##.|##.#
.|#.#.....#||#.#....||.|..##......|.#.|..#...##||.
|.#........|..|........#..#.#....|.|#.......#.|...
#..##.|.#......#...#..#.|.....#|.|.|#.##..#|...|..
..#....####....|..||...||..||.|.|...##.#..|||.||.|
...|..#.|||.||.||.#|...|..#.##..|#..........#.##|.
..|..||.#|.|.#..|.###|#.|....|.||.....|.........#.
#.|#.....#.|.#|#.|.#.#||...|.....||..|..|.##|#.|#|
..|...||#.|.#...|#.#....#.|##.#.|.....##..#..|.#..
..|.#...|.|...##|..#.#|.#|..|..#.|#.#...#|#.#||#..
2 changes: 1 addition & 1 deletion AoC2018.Runner/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"profiles": {
"AoC2018.Runner": {
"commandName": "Project",
"commandLineArgs": "14 2"
"commandLineArgs": "15 1"
}
}
}
12 changes: 12 additions & 0 deletions AoC2018.Solutions/Day15/Elf.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace AoC2018.Solutions.Day15
{
using System;

public class Elf : Unit
{
public override string ToString()
{
return "E";
}
}
}
12 changes: 12 additions & 0 deletions AoC2018.Solutions/Day15/Goblin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace AoC2018.Solutions.Day15
{
using System;

public class Goblin : Unit
{
public override string ToString()
{
return "G";
}
}
}
18 changes: 18 additions & 0 deletions AoC2018.Solutions/Day15/LocationHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace AoC2018.Solutions.Day15
{
using System.Collections.Generic;
using System.Linq;

public static class LocationHelper
{
public static (int X, int Y) GetCoordinates(int location, int yOffset)
{
return (location % yOffset, location / yOffset);
}

public static int GetLocation(int x, int y, int yOffset)
{
return x + (y * yOffset);
}
}
}
41 changes: 41 additions & 0 deletions AoC2018.Solutions/Day15/MapSpace.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace AoC2018.Solutions.Day15
{
using System;

public class MapSpace
{
public int Location { get; set; }

public Unit Unit { get; set; }

public static MapSpace Parse(char input, int location)
{
var result = new MapSpace();

switch (input)
{
case '#':
return null;

case '.':
break;

case 'E':
result.Unit = new Elf { CurrentLocation = result };
break;

case 'G':
result.Unit = new Goblin { CurrentLocation = result };
break;
}

result.Location = location;
return result;
}

public override string ToString()
{
return this.Unit?.ToString() ?? ".";
}
}
}
10 changes: 10 additions & 0 deletions AoC2018.Solutions/Day15/MapSpaceExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace AoC2018.Solutions.Day15
{
public static class MapSpaceExtensions
{
public static bool IsEmpty(this MapSpace space)
{
return space.Unit == null;
}
}
}
40 changes: 40 additions & 0 deletions AoC2018.Solutions/Day15/Part01.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
namespace AoC2018.Solutions.Day15
{
using System;

public class Part01 : ISolution
{
public string Solve(string input)
{
var currentState = State.Parse(input);
int rounds = 0;

////Console.WriteLine(currentState.ToString());

while (true)
{
bool roundCompleted = currentState.Round();

if (roundCompleted)
{
rounds++;
}

if (currentState.IsCombatEnded())
{
break;
}

////Console.WriteLine();
////Console.WriteLine($"Round {rounds}");
////Console.WriteLine(currentState.ToString());
}

////Console.WriteLine();
////Console.WriteLine($"Combat ended during round {rounds + 1}");
////Console.WriteLine(currentState.ToString());

return (rounds * currentState.TotalRemainingHitPoints()).ToString();
}
}
}
32 changes: 32 additions & 0 deletions AoC2018.Solutions/Day15/State.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace AoC2018.Solutions.Day15
{
using System;
using System.Collections.Generic;
using System.Linq;

public class State
{
public int YOffset { get; set; }

public MapSpace[] Map { get; set; }

public int MaxY { get; set; }

public static State Parse(string input)
{
string[] inputRows = input.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
int yOffset = inputRows[0].Length;
char[] mapChars = inputRows.SelectMany(x => x.ToCharArray()).ToArray();
MapSpace[] map = Enumerable.Range(0, mapChars.Length).Select(x => MapSpace.Parse(mapChars[x], x)).ToArray();

return new State { Map = map, YOffset = yOffset, MaxY = inputRows.Length };
}

public override string ToString()
{
string mapString = string.Join(string.Empty, this.Map.Select(x => x?.ToString() ?? "#"));
IEnumerable<string> rows = Enumerable.Range(0, this.Map.Length / this.YOffset).Select(x => mapString.Substring(x * this.YOffset, this.YOffset));
return string.Join(Environment.NewLine, rows);
}
}
}
68 changes: 68 additions & 0 deletions AoC2018.Solutions/Day15/StateExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
namespace AoC2018.Solutions.Day15
{
using System.Collections.Generic;
using System.Linq;

public static class StateExtensions
{
public static bool Round(this State initialState)
{
// Every unit gets a turn, taken in reading order.
// (we get reading order just by iterating the original
// state
State currentState = initialState;

// Get the units. Note that it is important to materialise this collection immediately,
// otherwise we run the risk of double moving units as we iterate through the map.
Unit[] units = initialState.Map.Where(x => x?.Unit != null).OrderBy(x => x.Location).Select(x => x.Unit).ToArray();

foreach (Unit current in units)
{
if (currentState.IsCombatEnded())
{
return false;
}

// Make sure it hasn't been killed already
if (!current.IsKilled())
{
current.TakeTurn(currentState);
}
}

return true;
}

public static IEnumerable<MapSpace> GetAdjacentSpaces(this State state, MapSpace space)
{
// Note: because we know the caverns in question are walled all around, we
// don't need to worry about bounds checking. If this wasn't the case we'd
// need to check to see if the space we're looking at was on the edge of the
// map before checking the adjacent spaces.
int[] adjacentLocations = new[]
{
space.Location - state.YOffset,
space.Location - 1,
space.Location + 1,
space.Location + state.YOffset,
};

return adjacentLocations.Select(x => state.Map[x]).Where(x => x != null);
}

public static IEnumerable<MapSpace> GetEmptyAdjacentSpaces(this State state, MapSpace space)
{
return state.GetAdjacentSpaces(space).Where(MapSpaceExtensions.IsEmpty);
}

public static bool IsCombatEnded(this State state)
{
return !state.Map.Any(x => x?.Unit is Elf) || !state.Map.Any(x => x?.Unit is Goblin);
}

public static int TotalRemainingHitPoints(this State state)
{
return state.Map.Sum(x => x?.Unit?.HitPoints ?? 0);
}
}
}
13 changes: 13 additions & 0 deletions AoC2018.Solutions/Day15/Unit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace AoC2018.Solutions.Day15
{
using System;

public abstract class Unit
{
public MapSpace CurrentLocation { get; set; }

public int AttackStrength { get; set; } = 3;

public int HitPoints { get; set; } = 200;
}
}
Loading

0 comments on commit 62505c2

Please sign in to comment.