Skip to content

Commit

Permalink
Day 9
Browse files Browse the repository at this point in the history
  • Loading branch information
jongeorge1 committed Feb 18, 2019
1 parent 1ffba41 commit 24ebb9f
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 0 deletions.
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\day09.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Input\day08.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
1 change: 1 addition & 0 deletions AoC2018.Runner/Input/day09.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
428 players; last marble is worth 72061 points
14 changes: 14 additions & 0 deletions AoC2018.Solutions/Day09/Marble.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace AoC2018.Solutions.Day09
{
using System.Diagnostics;

[DebuggerDisplay("{Number} : {CounterClockwise.Number} - {Number} - {Clockwise.Number}")]
public class Marble
{
public int Number { get; set; }

public Marble Clockwise { get; set; }

public Marble CounterClockwise { get; set; }
}
}
86 changes: 86 additions & 0 deletions AoC2018.Solutions/Day09/MarbleExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
namespace AoC2018.Solutions.Day09
{
using System.Text;

public static class MarbleExtensions
{
public static Marble Clockwise(this Marble marble, int count)
{
Marble current = marble;
for (int i = 0; i < count; i++)
{
current = current.Clockwise;
}

return current;
}

public static Marble CounterClockwise(this Marble marble, int count)
{
Marble current = marble;
for (int i = 0; i < count; i++)
{
current = current.CounterClockwise;
}

return current;
}

public static Marble InsertAfter(this Marble marble, int number)
{
Marble next = marble.Clockwise;
var newMarble = new Marble
{
Number = number,
Clockwise = next,
CounterClockwise = marble,
};

marble.Clockwise = newMarble;
next.CounterClockwise = newMarble;

return newMarble;
}

public static Marble Remove(this Marble marble)
{
Marble prev = marble.CounterClockwise;
Marble next = marble.Clockwise;

prev.Clockwise = next;
next.CounterClockwise = prev;

marble.Clockwise = null;
marble.CounterClockwise = null;

return marble;
}

public static string Visualise(this Marble start, Marble current)
{
var visualisation = new StringBuilder();

Marble active = start;

do
{
if (active == current)
{
visualisation.Append("(");
visualisation.Append(active.Number);
visualisation.Append(")");
}
else
{
visualisation.Append(active.Number);
}

visualisation.Append(" ");
active = active.Clockwise;
}
while (active != start);

return visualisation.ToString();
}
}
}
56 changes: 56 additions & 0 deletions AoC2018.Solutions/Day09/Part01.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
namespace AoC2018.Solutions.Day09
{
using System;
using System.Linq;

public class Part01 : ISolution
{
public string Solve(string input)
{
string[] components = input.Split(' ');

return this.Solve(int.Parse(components[0]), int.Parse(components[6])).ToString();
}

public long Solve(int players, int marbles)
{
long[] scores = new long[players];

// Set up Marble 0.
// We're going to solve this using a doubly linked list
var marble0 = new Marble
{
Number = 0,
};

marble0.Clockwise = marble0;
marble0.CounterClockwise = marble0;

Marble currentMarble = marble0;
int currentPlayer = 0;

for (int i = 1; i <= marbles; i++)
{
if (i % 23 == 0)
{
// Current player keeps this marble
scores[currentPlayer] += i;

// Also keeps the marble 7 counter clockwise
Marble marbleToRemove = currentMarble.CounterClockwise(7);
currentMarble = marbleToRemove.Clockwise;
scores[currentPlayer] += marbleToRemove.Number;
marbleToRemove.Remove();
}
else
{
currentMarble = currentMarble.Clockwise(1).InsertAfter(i);
}

currentPlayer = ++currentPlayer % players;
}

return scores.Max();
}
}
}
17 changes: 17 additions & 0 deletions AoC2018.Solutions/Day09/Part02.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace AoC2018.Solutions.Day09
{
using System;
using System.Linq;

public class Part02 : ISolution
{
public string Solve(string input)
{
var part1 = new Part01();

string[] components = input.Split(' ');

return part1.Solve(int.Parse(components[0]), int.Parse(components[6]) * 100).ToString();
}
}
}
13 changes: 13 additions & 0 deletions AoC2018.Tests/AoCTestCases.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,18 @@ public void Day07Part02()
string result = solution.Solve("Step C must be finished before step A can begin.\r\nStep C must be finished before step F can begin.\r\nStep A must be finished before step B can begin.\r\nStep A must be finished before step D can begin.\r\nStep B must be finished before step E can begin.\r\nStep D must be finished before step E can begin.\r\nStep F must be finished before step E can begin.", 2, 0);
Assert.That(result, Is.EqualTo("15"));
}

[TestCase(9, 25, 32)]
[TestCase(10, 1618, 8317)]
[TestCase(13, 7999, 146373)]
[TestCase(17, 1104, 2764)]
[TestCase(21, 6111, 54718)]
[TestCase(30, 5807, 37305)]
public void Day09Part01(int players, int lastMarble, long expectedHighScore)
{
var solution = new AoC2018.Solutions.Day09.Part01();
long result = solution.Solve(players, lastMarble);
Assert.That(result, Is.EqualTo(expectedHighScore));
}
}
}

0 comments on commit 24ebb9f

Please sign in to comment.