Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #load "xunit"
- #load "..\AOC Connector"
- void Main(string[] args)
- {
- if(args == null)
- RunTests(); // Call RunTests() or press Alt+Shift+T to initiate testing.
- //get aoc data
- var aoc = new AdventOfCode(2020, 17);
- //solve A
- aoc.SubmitAnswer(SolveA(aoc.InputLines), Part.A);
- //solve B
- aoc.SubmitAnswer(SolveB(aoc.InputLines), Part.B);
- }
- abstract class ConwayDimension<T>
- {
- protected static int[] dirs = new[] { -1, 0, 1 };
- protected Dictionary<T, bool> d1 = new Dictionary<T, bool>();
- protected Dictionary<T, bool> d2 = new Dictionary<T, bool>();
- public int Solve(string[] data)
- {
- //fill the dictionary
- for (int i = 0; i < data.Length; i++)
- {
- for (int j = 0; j < data[i].Length; j++)
- {
- //create location
- var loc = CreateItem(i, j);
- d1[loc] = data[i][j] == '#';
- //add the neighbourds of this point
- foreach (var nb in GetNeighbours(loc))
- {
- //might be overwritten again.
- if (d1.ContainsKey(nb) == false) d1[nb] = false;
- }
- }
- }
- //execute the cycles
- for (int cycles = 0; cycles < 6; cycles++)
- {
- //check all point in the dictionary
- foreach (var point in d1)
- {
- //get all the neighbourss
- var pointNeighbours = GetNeighbours(point.Key).ToArray();
- //count the actives
- var count = pointNeighbours.Count(x => d1.TryGetValue(x, out bool b) && b);
- //should this point be active?
- bool active = point.Value
- ? count is 2 or 3
- : count is 3;
- //store result
- d2[point.Key] = active;
- //add the neighbours for the next cycle
- if (count != 0)
- {
- foreach (var nb in pointNeighbours)
- {
- //only write empty cells
- if (d2.ContainsKey(nb) == false) d2[nb] = false;
- }
- }
- }
- d1 = d2;
- d2 = new Dictionary<T, bool>();
- }
- return d1.Values.Count(x => x);
- }
- protected abstract T CreateItem(int i, int j);
- protected abstract IEnumerable<T> GetNeighbours(T loc);
- }
- class Conway3D : ConwayDimension<(int x, int y, int z)>
- {
- protected override (int x, int y, int z) CreateItem(int i, int j) => (i,j,0);
- protected override IEnumerable<(int x, int y, int z)> GetNeighbours((int x, int y, int z) loc)
- {
- /*
- foreach (var a in dirs)
- foreach (var b in dirs)
- foreach (var c in dirs)
- {
- if (a == 0 && b == 0 && c == 0) continue;
- yield return (loc.x + a, loc.y + b, loc.z + c);
- }
- */
- //13ms -> 11ms
- return new []
- {
- (loc.x + -1, loc.y + -1, loc.z + -1),
- (loc.x + -1, loc.y + -1, loc.z + 0),
- (loc.x + -1, loc.y + -1, loc.z + 1),
- (loc.x + -1, loc.y + 0, loc.z + -1),
- (loc.x + -1, loc.y + 0, loc.z + 0),
- (loc.x + -1, loc.y + 0, loc.z + 1),
- (loc.x + -1, loc.y + 1, loc.z + -1),
- (loc.x + -1, loc.y + 1, loc.z + 0),
- (loc.x + -1, loc.y + 1, loc.z + 1),
- (loc.x + 0, loc.y + -1, loc.z + -1),
- (loc.x + 0, loc.y + -1, loc.z + 0),
- (loc.x + 0, loc.y + -1, loc.z + 1),
- (loc.x + 0, loc.y + 0, loc.z + -1),
- (loc.x + 0, loc.y + 0, loc.z + 1),
- (loc.x + 0, loc.y + 1, loc.z + -1),
- (loc.x + 0, loc.y + 1, loc.z + 0),
- (loc.x + 0, loc.y + 1, loc.z + 1),
- (loc.x + 1, loc.y + -1, loc.z + -1),
- (loc.x + 1, loc.y + -1, loc.z + 0),
- (loc.x + 1, loc.y + -1, loc.z + 1),
- (loc.x + 1, loc.y + 0, loc.z + -1),
- (loc.x + 1, loc.y + 0, loc.z + 0),
- (loc.x + 1, loc.y + 0, loc.z + 1),
- (loc.x + 1, loc.y + 1, loc.z + -1),
- (loc.x + 1, loc.y + 1, loc.z + 0),
- (loc.x + 1, loc.y + 1, loc.z + 1),
- };
- }
- }
- class Conway4D : ConwayDimension<(int x, int y, int z, int w)>
- {
- protected override (int x, int y, int z, int w) CreateItem(int i, int j) => (i, j, 0, 0);
- protected override IEnumerable<(int x, int y, int z, int w)> GetNeighbours((int x, int y, int z, int w) loc)
- {
- //foreach (var a in dirs)
- //foreach (var b in dirs)
- //foreach (var c in dirs)
- //foreach (var d in dirs)
- //{
- // if (a == 0 && b == 0 && c == 0 && d == 0) continue;
- // yield return (loc.x + a, loc.y + b, loc.z + c, loc.w + d);
- //}
- //optimize 450ms vs 385ms
- return new[]
- {
- (loc.x + -1, loc.y + -1, loc.z + -1, loc.w + -1),
- (loc.x + -1, loc.y + -1, loc.z + -1, loc.w + 0),
- (loc.x + -1, loc.y + -1, loc.z + -1, loc.w + 1),
- (loc.x + -1, loc.y + -1, loc.z + 0, loc.w + -1),
- (loc.x + -1, loc.y + -1, loc.z + 0, loc.w + 0),
- (loc.x + -1, loc.y + -1, loc.z + 0, loc.w + 1),
- (loc.x + -1, loc.y + -1, loc.z + 1, loc.w + -1),
- (loc.x + -1, loc.y + -1, loc.z + 1, loc.w + 0),
- (loc.x + -1, loc.y + -1, loc.z + 1, loc.w + 1),
- (loc.x + -1, loc.y + 0, loc.z + -1, loc.w + -1),
- (loc.x + -1, loc.y + 0, loc.z + -1, loc.w + 0),
- (loc.x + -1, loc.y + 0, loc.z + -1, loc.w + 1),
- (loc.x + -1, loc.y + 0, loc.z + 0, loc.w + -1),
- (loc.x + -1, loc.y + 0, loc.z + 0, loc.w + 0),
- (loc.x + -1, loc.y + 0, loc.z + 0, loc.w + 1),
- (loc.x + -1, loc.y + 0, loc.z + 1, loc.w + -1),
- (loc.x + -1, loc.y + 0, loc.z + 1, loc.w + 0),
- (loc.x + -1, loc.y + 0, loc.z + 1, loc.w + 1),
- (loc.x + -1, loc.y + 1, loc.z + -1, loc.w + -1),
- (loc.x + -1, loc.y + 1, loc.z + -1, loc.w + 0),
- (loc.x + -1, loc.y + 1, loc.z + -1, loc.w + 1),
- (loc.x + -1, loc.y + 1, loc.z + 0, loc.w + -1),
- (loc.x + -1, loc.y + 1, loc.z + 0, loc.w + 0),
- (loc.x + -1, loc.y + 1, loc.z + 0, loc.w + 1),
- (loc.x + -1, loc.y + 1, loc.z + 1, loc.w + -1),
- (loc.x + -1, loc.y + 1, loc.z + 1, loc.w + 0),
- (loc.x + -1, loc.y + 1, loc.z + 1, loc.w + 1),
- (loc.x + 0, loc.y + -1, loc.z + -1, loc.w + -1),
- (loc.x + 0, loc.y + -1, loc.z + -1, loc.w + 0),
- (loc.x + 0, loc.y + -1, loc.z + -1, loc.w + 1),
- (loc.x + 0, loc.y + -1, loc.z + 0, loc.w + -1),
- (loc.x + 0, loc.y + -1, loc.z + 0, loc.w + 0),
- (loc.x + 0, loc.y + -1, loc.z + 0, loc.w + 1),
- (loc.x + 0, loc.y + -1, loc.z + 1, loc.w + -1),
- (loc.x + 0, loc.y + -1, loc.z + 1, loc.w + 0),
- (loc.x + 0, loc.y + -1, loc.z + 1, loc.w + 1),
- (loc.x + 0, loc.y + 0, loc.z + -1, loc.w + -1),
- (loc.x + 0, loc.y + 0, loc.z + -1, loc.w + 0),
- (loc.x + 0, loc.y + 0, loc.z + -1, loc.w + 1),
- (loc.x + 0, loc.y + 0, loc.z + 0, loc.w + -1),
- (loc.x + 0, loc.y + 0, loc.z + 0, loc.w + 1),
- (loc.x + 0, loc.y + 0, loc.z + 1, loc.w + -1),
- (loc.x + 0, loc.y + 0, loc.z + 1, loc.w + 0),
- (loc.x + 0, loc.y + 0, loc.z + 1, loc.w + 1),
- (loc.x + 0, loc.y + 1, loc.z + -1, loc.w + -1),
- (loc.x + 0, loc.y + 1, loc.z + -1, loc.w + 0),
- (loc.x + 0, loc.y + 1, loc.z + -1, loc.w + 1),
- (loc.x + 0, loc.y + 1, loc.z + 0, loc.w + -1),
- (loc.x + 0, loc.y + 1, loc.z + 0, loc.w + 0),
- (loc.x + 0, loc.y + 1, loc.z + 0, loc.w + 1),
- (loc.x + 0, loc.y + 1, loc.z + 1, loc.w + -1),
- (loc.x + 0, loc.y + 1, loc.z + 1, loc.w + 0),
- (loc.x + 0, loc.y + 1, loc.z + 1, loc.w + 1),
- (loc.x + 1, loc.y + -1, loc.z + -1, loc.w + -1),
- (loc.x + 1, loc.y + -1, loc.z + -1, loc.w + 0),
- (loc.x + 1, loc.y + -1, loc.z + -1, loc.w + 1),
- (loc.x + 1, loc.y + -1, loc.z + 0, loc.w + -1),
- (loc.x + 1, loc.y + -1, loc.z + 0, loc.w + 0),
- (loc.x + 1, loc.y + -1, loc.z + 0, loc.w + 1),
- (loc.x + 1, loc.y + -1, loc.z + 1, loc.w + -1),
- (loc.x + 1, loc.y + -1, loc.z + 1, loc.w + 0),
- (loc.x + 1, loc.y + -1, loc.z + 1, loc.w + 1),
- (loc.x + 1, loc.y + 0, loc.z + -1, loc.w + -1),
- (loc.x + 1, loc.y + 0, loc.z + -1, loc.w + 0),
- (loc.x + 1, loc.y + 0, loc.z + -1, loc.w + 1),
- (loc.x + 1, loc.y + 0, loc.z + 0, loc.w + -1),
- (loc.x + 1, loc.y + 0, loc.z + 0, loc.w + 0),
- (loc.x + 1, loc.y + 0, loc.z + 0, loc.w + 1),
- (loc.x + 1, loc.y + 0, loc.z + 1, loc.w + -1),
- (loc.x + 1, loc.y + 0, loc.z + 1, loc.w + 0),
- (loc.x + 1, loc.y + 0, loc.z + 1, loc.w + 1),
- (loc.x + 1, loc.y + 1, loc.z + -1, loc.w + -1),
- (loc.x + 1, loc.y + 1, loc.z + -1, loc.w + 0),
- (loc.x + 1, loc.y + 1, loc.z + -1, loc.w + 1),
- (loc.x + 1, loc.y + 1, loc.z + 0, loc.w + -1),
- (loc.x + 1, loc.y + 1, loc.z + 0, loc.w + 0),
- (loc.x + 1, loc.y + 1, loc.z + 0, loc.w + 1),
- (loc.x + 1, loc.y + 1, loc.z + 1, loc.w + -1),
- (loc.x + 1, loc.y + 1, loc.z + 1, loc.w + 0),
- (loc.x + 1, loc.y + 1, loc.z + 1, loc.w + 1),
- };
- }
- }
- int SolveA(string[] data)
- {
- var cw = new Conway3D();
- return cw.Solve(data);
- }
- int SolveB(string[] data)
- {
- var cw = new Conway4D();
- return cw.Solve(data);
- }
- // You can define other methods, fields, classes and namespaces here
- #region private::Tests
- //test data
- string[] testdata = new[]
- {
- ".#.",
- "..#",
- "###",
- };
- //tests
- [Fact] void TestA() => Assert.Equal(112, SolveA(testdata));
- [Fact] void TestB() => Assert.Equal(848, SolveB(testdata));
- #endregion
Advertisement
Add Comment
Please, Sign In to add comment