-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c4f152e
commit 01935ae
Showing
7 changed files
with
242 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
namespace AoC2018.Solutions.Day18 | ||
{ | ||
using System.Collections.Generic; | ||
|
||
public static class MapAcre | ||
{ | ||
public const char Open = '.'; | ||
|
||
public const char Trees = '|'; | ||
|
||
public const char Lumberyard = '#'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
namespace AoC2018.Solutions.Day18 | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
public static class MapExtensions | ||
{ | ||
public static void WriteToConsole(this (char[] Map, int yOffset) state) | ||
{ | ||
int rows = state.Map.Length / state.yOffset; | ||
|
||
for (int i = 0; i < rows; i++) | ||
{ | ||
string row = new string(state.Map.Skip(i * state.yOffset).Take(state.yOffset).ToArray()); | ||
Console.WriteLine(row); | ||
} | ||
} | ||
|
||
public static (char[] Map, int yOffset) GetNextState(this (char[] Map, int yOffset) state) | ||
{ | ||
char[] result = new char[state.Map.Length]; | ||
|
||
for (int i = 0; i < result.Length; i++) | ||
{ | ||
result[i] = state.GetNextStateForAcre(i); | ||
} | ||
|
||
return (result, state.yOffset); | ||
} | ||
|
||
public static string Memoize(this (char[] Map, int yOffset) state) | ||
{ | ||
// Lazy, as I'm not bothering to include the yOffset... | ||
return new string(state.Map); | ||
} | ||
|
||
public static char GetNextStateForAcre(this (char[] Map, int yOffset) state, int acre) | ||
{ | ||
char[] adjacentAcres = state.GetAdjacentAcres(acre).ToArray(); | ||
|
||
switch (state.Map[acre]) | ||
{ | ||
case MapAcre.Open: | ||
if (adjacentAcres.Count(x => x == MapAcre.Trees) >= 3) | ||
{ | ||
return MapAcre.Trees; | ||
} | ||
|
||
return MapAcre.Open; | ||
|
||
case MapAcre.Trees: | ||
if (adjacentAcres.Count(x => x == MapAcre.Lumberyard) >= 3) | ||
{ | ||
return MapAcre.Lumberyard; | ||
} | ||
|
||
return MapAcre.Trees; | ||
|
||
case MapAcre.Lumberyard: | ||
if (adjacentAcres.Count(x => x == MapAcre.Lumberyard) >= 1 && adjacentAcres.Count(x => x == MapAcre.Trees) >= 1) | ||
{ | ||
return MapAcre.Lumberyard; | ||
} | ||
|
||
return MapAcre.Open; | ||
} | ||
|
||
throw new InvalidOperationException(); | ||
} | ||
|
||
public static IEnumerable<char> GetAdjacentAcres(this (char[] Map, int yOffset) state, int acre) | ||
{ | ||
int up = acre - state.yOffset; | ||
int left = acre - 1; | ||
int right = acre + 1; | ||
int down = acre + state.yOffset; | ||
|
||
int minX = (acre / state.yOffset) * state.yOffset; | ||
int maxX = minX + state.yOffset; | ||
|
||
bool canLookUp = up >= 0; | ||
bool canLookDown = down < state.Map.Length; | ||
bool canLookLeft = left >= minX; | ||
bool canLookRight = right < maxX; | ||
|
||
if (canLookUp) | ||
{ | ||
yield return state.Map[up]; | ||
|
||
if (canLookLeft) | ||
{ | ||
yield return state.Map[up - 1]; | ||
} | ||
|
||
if (canLookRight) | ||
{ | ||
yield return state.Map[up + 1]; | ||
} | ||
} | ||
|
||
if (canLookDown) | ||
{ | ||
yield return state.Map[down]; | ||
|
||
if (canLookLeft) | ||
{ | ||
yield return state.Map[down - 1]; | ||
} | ||
|
||
if (canLookRight) | ||
{ | ||
yield return state.Map[down + 1]; | ||
} | ||
} | ||
|
||
if (canLookLeft) | ||
{ | ||
yield return state.Map[left]; | ||
} | ||
|
||
if (canLookRight) | ||
{ | ||
yield return state.Map[right]; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
namespace AoC2018.Solutions.Day18 | ||
{ | ||
using System; | ||
using System.Linq; | ||
|
||
public static class MapParser | ||
{ | ||
public static (char[] Map, int yOffset) Parse(string input) | ||
{ | ||
string[] rows = input.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); | ||
int yOffset = rows[0].Length; | ||
char[] map = rows.SelectMany(x => x.ToCharArray()).ToArray(); | ||
|
||
return (map, yOffset); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
namespace AoC2018.Solutions.Day18 | ||
{ | ||
using System; | ||
using System.Linq; | ||
|
||
public class Part01 : ISolution | ||
{ | ||
public string Solve(string input) | ||
{ | ||
(char[] Map, int yOffset) map = MapParser.Parse(input); | ||
|
||
////Console.WriteLine("Initial state:"); | ||
////map.WriteToConsole(); | ||
|
||
for (int i = 0; i < 10; i++) | ||
{ | ||
map = map.GetNextState(); | ||
|
||
////Console.WriteLine($"After {i + 1} minute:"); | ||
////map.WriteToConsole(); | ||
} | ||
|
||
int woodCount = map.Map.Count(x => x == MapAcre.Trees); | ||
int lumberYardCount = map.Map.Count(x => x == MapAcre.Lumberyard); | ||
|
||
return (woodCount * lumberYardCount).ToString(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
namespace AoC2018.Solutions.Day18 | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
public class Part02 : ISolution | ||
{ | ||
public string Solve(string input) | ||
{ | ||
(char[] Map, int yOffset) map = MapParser.Parse(input); | ||
|
||
// Predictably, part 2 is just part 1 amped up. Equally predictably, this means | ||
// that after a certain amount of time, the pattern will settle into a loop. This | ||
// means we need to: | ||
// 1. Work out the point at which we start iterating. | ||
// 2. Find the iteration length. | ||
// 3. Do some maths | ||
// 4. Iterate a few more times | ||
var states = new List<string>(10000); | ||
string mapMemo = map.Memoize(); | ||
|
||
do | ||
{ | ||
states.Add(mapMemo); | ||
|
||
map = map.GetNextState(); | ||
mapMemo = map.Memoize(); | ||
} | ||
while (!states.Contains(mapMemo)); | ||
|
||
Console.WriteLine($"Iteration point hit after {states.Count} iterations"); | ||
|
||
// We've hit a point where we've seen this state before. | ||
int originalIterationForThisState = states.IndexOf(mapMemo); | ||
int iterationLength = states.Count - originalIterationForThisState; | ||
|
||
const int target = 1000000000; | ||
int numberOfWholeIterations = (target - originalIterationForThisState) / iterationLength; | ||
int remainingTicksRequired = target - originalIterationForThisState - (numberOfWholeIterations * iterationLength); | ||
|
||
for (int i = 0; i < remainingTicksRequired; i++) | ||
{ | ||
map = map.GetNextState(); | ||
} | ||
|
||
int woodCount = map.Map.Count(x => x == MapAcre.Trees); | ||
int lumberYardCount = map.Map.Count(x => x == MapAcre.Lumberyard); | ||
|
||
return (woodCount * lumberYardCount).ToString(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters