AdventOfCode2018: Move tests to the corresponding day
This commit is contained in:
@@ -4,4 +4,7 @@
|
|||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VM/@EntryIndexedValue">VM</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VM/@EntryIndexedValue">VM</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VX/@EntryIndexedValue">VX</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VX/@EntryIndexedValue">VX</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VY/@EntryIndexedValue">VY</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VY/@EntryIndexedValue">VY</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></s:String></wpf:ResourceDictionary>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></s:String>
|
||||||
|
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=AdventOfCode_002A_002ETests_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=AdventOfCode_002ECommon_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=_002A_003B_002A_003BProgram_003B_002A/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
namespace AdventOfCode2018.Tests;
|
|
||||||
|
|
||||||
public class ChronoLicenceNode_Tests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void BuildFromIntStream__Test()
|
|
||||||
{
|
|
||||||
IntStream values = new("2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2");
|
|
||||||
ChronoLicenceNode result = ChronoLicenceNode.BuildFromIntStream(values);
|
|
||||||
|
|
||||||
Assert.Equal(2, result.Childs.Count);
|
|
||||||
Assert.Equal(3, result.Metadata.Count);
|
|
||||||
Assert.Equal(1, result.Metadata[0]);
|
|
||||||
Assert.Equal(1, result.Metadata[1]);
|
|
||||||
Assert.Equal(2, result.Metadata[2]);
|
|
||||||
|
|
||||||
Assert.Empty(result.Childs[0].Childs);
|
|
||||||
Assert.Equal(3, result.Childs[0].Metadata.Count);
|
|
||||||
Assert.Equal(10, result.Childs[0].Metadata[0]);
|
|
||||||
Assert.Equal(11, result.Childs[0].Metadata[1]);
|
|
||||||
Assert.Equal(12, result.Childs[0].Metadata[2]);
|
|
||||||
|
|
||||||
Assert.Single(result.Childs[1].Childs);
|
|
||||||
Assert.Single(result.Childs[1].Metadata);
|
|
||||||
Assert.Equal(2, result.Childs[1].Metadata[0]);
|
|
||||||
|
|
||||||
Assert.Empty(result.Childs[1].Childs[0].Childs);
|
|
||||||
Assert.Single(result.Childs[1].Childs[0].Metadata);
|
|
||||||
Assert.Equal(99, result.Childs[1].Childs[0].Metadata[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
namespace AdventOfCode2018.Tests;
|
|
||||||
|
|
||||||
public class ChronoPoint_Tests
|
|
||||||
{
|
|
||||||
#region FromString
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void FromString__Test1()
|
|
||||||
{
|
|
||||||
ChronoPoint point = ChronoPoint.FromString("1, 1");
|
|
||||||
|
|
||||||
Assert.Equal(1, point.X);
|
|
||||||
Assert.Equal(1, point.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void FromString__Test2()
|
|
||||||
{
|
|
||||||
ChronoPoint point = ChronoPoint.FromString("1, 6");
|
|
||||||
|
|
||||||
Assert.Equal(1, point.X);
|
|
||||||
Assert.Equal(6, point.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void FromString__Test3()
|
|
||||||
{
|
|
||||||
ChronoPoint point = ChronoPoint.FromString("8, 9");
|
|
||||||
|
|
||||||
Assert.Equal(8, point.X);
|
|
||||||
Assert.Equal(9, point.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion FromString
|
|
||||||
|
|
||||||
#region ManhattanDistance
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void ManhattanDistance__Test1()
|
|
||||||
{
|
|
||||||
ChronoPoint p0 = ChronoPoint.FromString("8, 9");
|
|
||||||
ChronoPoint p1 = ChronoPoint.FromString("1, 6");
|
|
||||||
|
|
||||||
int distance = ChronoPoint.ManhattanDistance(p0, p1);
|
|
||||||
|
|
||||||
Assert.Equal(10, distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void ManhattanDistance__Test2()
|
|
||||||
{
|
|
||||||
ChronoPoint p0 = ChronoPoint.FromString("1, 1");
|
|
||||||
ChronoPoint p1 = ChronoPoint.FromString("1, 6");
|
|
||||||
|
|
||||||
int distance = ChronoPoint.ManhattanDistance(p0, p1);
|
|
||||||
|
|
||||||
Assert.Equal(5, distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion ManhattanDistance
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
namespace AdventOfCode2018.Tests;
|
|
||||||
|
|
||||||
public class Claim_Tests
|
|
||||||
{
|
|
||||||
#region FromString
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void FromString__Test1()
|
|
||||||
{
|
|
||||||
Day03.Claim claim = Day03.Claim.FromString("#123 @ 3,2: 5x4");
|
|
||||||
|
|
||||||
Assert.Equal(123, claim.ID);
|
|
||||||
Assert.Equal(3, claim.Left);
|
|
||||||
Assert.Equal(2, claim.Top);
|
|
||||||
Assert.Equal(5, claim.Width);
|
|
||||||
Assert.Equal(4, claim.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void FromString__Test2()
|
|
||||||
{
|
|
||||||
Day03.Claim claim = Day03.Claim.FromString("#1 @ 1,3: 4x4");
|
|
||||||
|
|
||||||
Assert.Equal(1, claim.ID);
|
|
||||||
Assert.Equal(1, claim.Left);
|
|
||||||
Assert.Equal(3, claim.Top);
|
|
||||||
Assert.Equal(4, claim.Width);
|
|
||||||
Assert.Equal(4, claim.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void FromString__Test3()
|
|
||||||
{
|
|
||||||
Day03.Claim claim = Day03.Claim.FromString("#2 @ 3,1: 4x4");
|
|
||||||
|
|
||||||
Assert.Equal(2, claim.ID);
|
|
||||||
Assert.Equal(3, claim.Left);
|
|
||||||
Assert.Equal(1, claim.Top);
|
|
||||||
Assert.Equal(4, claim.Width);
|
|
||||||
Assert.Equal(4, claim.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void FromString__Test4()
|
|
||||||
{
|
|
||||||
Day03.Claim claim = Day03.Claim.FromString("#3 @ 5,5: 2x2");
|
|
||||||
|
|
||||||
Assert.Equal(3, claim.ID);
|
|
||||||
Assert.Equal(5, claim.Left);
|
|
||||||
Assert.Equal(5, claim.Top);
|
|
||||||
Assert.Equal(2, claim.Width);
|
|
||||||
Assert.Equal(2, claim.Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion FromString
|
|
||||||
|
|
||||||
#region Overlaps
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Overlaps__Test1()
|
|
||||||
{
|
|
||||||
Day03.Claim claim1 = Day03.Claim.FromString("#1 @ 1,3: 4x4");
|
|
||||||
Day03.Claim claim2 = Day03.Claim.FromString("#3 @ 5,5: 2x2");
|
|
||||||
|
|
||||||
bool result = Day03.Claim.Overlaps(claim1, claim2);
|
|
||||||
|
|
||||||
Assert.False(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Overlaps__Test2()
|
|
||||||
{
|
|
||||||
Day03.Claim claim1 = Day03.Claim.FromString("#2 @ 3,1: 4x4");
|
|
||||||
Day03.Claim claim2 = Day03.Claim.FromString("#3 @ 5,5: 2x2");
|
|
||||||
|
|
||||||
bool result = Day03.Claim.Overlaps(claim1, claim2);
|
|
||||||
|
|
||||||
Assert.False(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void Overlaps__Test3()
|
|
||||||
{
|
|
||||||
Day03.Claim claim1 = Day03.Claim.FromString("#1 @ 1,3: 4x4");
|
|
||||||
Day03.Claim claim2 = Day03.Claim.FromString("#2 @ 3,1: 4x4");
|
|
||||||
|
|
||||||
bool result = Day03.Claim.Overlaps(claim1, claim2);
|
|
||||||
|
|
||||||
Assert.True(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Overlaps
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,95 @@
|
|||||||
|
|
||||||
public class Day03_Tests
|
public class Day03_Tests
|
||||||
{
|
{
|
||||||
|
#region Claim_FromString
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Claim_FromString__Test1()
|
||||||
|
{
|
||||||
|
Day03.Claim claim = Day03.Claim.FromString("#123 @ 3,2: 5x4");
|
||||||
|
|
||||||
|
Assert.Equal(123, claim.ID);
|
||||||
|
Assert.Equal(3, claim.Left);
|
||||||
|
Assert.Equal(2, claim.Top);
|
||||||
|
Assert.Equal(5, claim.Width);
|
||||||
|
Assert.Equal(4, claim.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Claim_FromString__Test2()
|
||||||
|
{
|
||||||
|
Day03.Claim claim = Day03.Claim.FromString("#1 @ 1,3: 4x4");
|
||||||
|
|
||||||
|
Assert.Equal(1, claim.ID);
|
||||||
|
Assert.Equal(1, claim.Left);
|
||||||
|
Assert.Equal(3, claim.Top);
|
||||||
|
Assert.Equal(4, claim.Width);
|
||||||
|
Assert.Equal(4, claim.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Claim_FromString__Test3()
|
||||||
|
{
|
||||||
|
Day03.Claim claim = Day03.Claim.FromString("#2 @ 3,1: 4x4");
|
||||||
|
|
||||||
|
Assert.Equal(2, claim.ID);
|
||||||
|
Assert.Equal(3, claim.Left);
|
||||||
|
Assert.Equal(1, claim.Top);
|
||||||
|
Assert.Equal(4, claim.Width);
|
||||||
|
Assert.Equal(4, claim.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Claim_FromString__Test4()
|
||||||
|
{
|
||||||
|
Day03.Claim claim = Day03.Claim.FromString("#3 @ 5,5: 2x2");
|
||||||
|
|
||||||
|
Assert.Equal(3, claim.ID);
|
||||||
|
Assert.Equal(5, claim.Left);
|
||||||
|
Assert.Equal(5, claim.Top);
|
||||||
|
Assert.Equal(2, claim.Width);
|
||||||
|
Assert.Equal(2, claim.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Claim_FromString
|
||||||
|
|
||||||
|
#region Claim_Overlaps
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Claim_Overlaps__Test1()
|
||||||
|
{
|
||||||
|
Day03.Claim claim1 = Day03.Claim.FromString("#1 @ 1,3: 4x4");
|
||||||
|
Day03.Claim claim2 = Day03.Claim.FromString("#3 @ 5,5: 2x2");
|
||||||
|
|
||||||
|
bool result = Day03.Claim.Overlaps(claim1, claim2);
|
||||||
|
|
||||||
|
Assert.False(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Claim_Overlaps__Test2()
|
||||||
|
{
|
||||||
|
Day03.Claim claim1 = Day03.Claim.FromString("#2 @ 3,1: 4x4");
|
||||||
|
Day03.Claim claim2 = Day03.Claim.FromString("#3 @ 5,5: 2x2");
|
||||||
|
|
||||||
|
bool result = Day03.Claim.Overlaps(claim1, claim2);
|
||||||
|
|
||||||
|
Assert.False(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Claim_Overlaps__Test3()
|
||||||
|
{
|
||||||
|
Day03.Claim claim1 = Day03.Claim.FromString("#1 @ 1,3: 4x4");
|
||||||
|
Day03.Claim claim2 = Day03.Claim.FromString("#2 @ 3,1: 4x4");
|
||||||
|
|
||||||
|
bool result = Day03.Claim.Overlaps(claim1, claim2);
|
||||||
|
|
||||||
|
Assert.True(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Claim_Overlaps
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ResolvePart1__Test()
|
public void ResolvePart1__Test()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,134 @@
|
|||||||
namespace AdventOfCode2018.Tests;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AdventOfCode2018.Tests;
|
||||||
|
|
||||||
public class Day04_Tests
|
public class Day04_Tests
|
||||||
{
|
{
|
||||||
|
#region GuardEvent_FromString
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GuardEvent_FromString__ShiftBegin()
|
||||||
|
{
|
||||||
|
Day04.GuardEvent guardEvent = Day04.GuardEvent.FromString("[1518-11-01 00:00] Guard #10 begins shift");
|
||||||
|
|
||||||
|
Assert.Equal(10, guardEvent.ID);
|
||||||
|
Assert.Equal(11, guardEvent.Date.Month);
|
||||||
|
Assert.Equal(1, guardEvent.Date.Day);
|
||||||
|
Assert.Equal(0, guardEvent.Date.Hour);
|
||||||
|
Assert.Equal(0, guardEvent.Date.Minute);
|
||||||
|
Assert.Equal(Day04.GuardEventType.ShiftBegin, guardEvent.Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GuardEvent_FromString__FallSleep()
|
||||||
|
{
|
||||||
|
Day04.GuardEvent guardEvent = Day04.GuardEvent.FromString("[1518-11-02 00:40] falls asleep");
|
||||||
|
|
||||||
|
Assert.Null(guardEvent.ID);
|
||||||
|
Assert.Equal(11, guardEvent.Date.Month);
|
||||||
|
Assert.Equal(2, guardEvent.Date.Day);
|
||||||
|
Assert.Equal(0, guardEvent.Date.Hour);
|
||||||
|
Assert.Equal(40, guardEvent.Date.Minute);
|
||||||
|
Assert.Equal(Day04.GuardEventType.FallSleep, guardEvent.Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GuardEvent_FromString__WakeUp()
|
||||||
|
{
|
||||||
|
Day04.GuardEvent guardEvent = Day04.GuardEvent.FromString("[1518-11-03 00:29] wakes up");
|
||||||
|
|
||||||
|
Assert.Null(guardEvent.ID);
|
||||||
|
Assert.Equal(11, guardEvent.Date.Month);
|
||||||
|
Assert.Equal(3, guardEvent.Date.Day);
|
||||||
|
Assert.Equal(0, guardEvent.Date.Hour);
|
||||||
|
Assert.Equal(29, guardEvent.Date.Minute);
|
||||||
|
Assert.Equal(Day04.GuardEventType.WakeUp, guardEvent.Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion GuardEvent_FromString
|
||||||
|
|
||||||
|
#region GuardEvent_FromStringArray
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GuardEvent_FromStringArray__TestBase()
|
||||||
|
{
|
||||||
|
List<Day04.GuardEvent> guardEvents = Day04.GuardEvent.FromStringArray(new[] {
|
||||||
|
"[1518-11-01 00:00] Guard #10 begins shift",
|
||||||
|
"[1518-11-01 00:05] falls asleep",
|
||||||
|
"[1518-11-01 00:25] wakes up",
|
||||||
|
"[1518-11-01 00:30] falls asleep",
|
||||||
|
"[1518-11-01 00:55] wakes up",
|
||||||
|
"[1518-11-01 23:58] Guard #99 begins shift",
|
||||||
|
"[1518-11-02 00:40] falls asleep",
|
||||||
|
"[1518-11-02 00:50] wakes up",
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.Equal(10, guardEvents[0].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.ShiftBegin, guardEvents[0].Type);
|
||||||
|
|
||||||
|
Assert.Equal(10, guardEvents[1].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.FallSleep, guardEvents[1].Type);
|
||||||
|
|
||||||
|
Assert.Equal(10, guardEvents[2].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.WakeUp, guardEvents[2].Type);
|
||||||
|
|
||||||
|
Assert.Equal(10, guardEvents[3].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.FallSleep, guardEvents[3].Type);
|
||||||
|
|
||||||
|
Assert.Equal(10, guardEvents[4].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.WakeUp, guardEvents[4].Type);
|
||||||
|
|
||||||
|
Assert.Equal(99, guardEvents[5].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.ShiftBegin, guardEvents[5].Type);
|
||||||
|
|
||||||
|
Assert.Equal(99, guardEvents[6].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.FallSleep, guardEvents[6].Type);
|
||||||
|
|
||||||
|
Assert.Equal(99, guardEvents[7].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.WakeUp, guardEvents[7].Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GuardEvent_FromStringArray__TestBaseUnsorted()
|
||||||
|
{
|
||||||
|
List<Day04.GuardEvent> guardEvents = Day04.GuardEvent.FromStringArray(new[] {
|
||||||
|
"[1518-11-01 00:00] Guard #10 begins shift",
|
||||||
|
"[1518-11-01 23:58] Guard #99 begins shift",
|
||||||
|
"[1518-11-01 00:30] falls asleep",
|
||||||
|
"[1518-11-02 00:40] falls asleep",
|
||||||
|
"[1518-11-01 00:05] falls asleep",
|
||||||
|
"[1518-11-02 00:50] wakes up",
|
||||||
|
"[1518-11-01 00:55] wakes up",
|
||||||
|
"[1518-11-01 00:25] wakes up",
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.Equal(10, guardEvents[0].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.ShiftBegin, guardEvents[0].Type);
|
||||||
|
|
||||||
|
Assert.Equal(10, guardEvents[1].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.FallSleep, guardEvents[1].Type);
|
||||||
|
|
||||||
|
Assert.Equal(10, guardEvents[2].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.WakeUp, guardEvents[2].Type);
|
||||||
|
|
||||||
|
Assert.Equal(10, guardEvents[3].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.FallSleep, guardEvents[3].Type);
|
||||||
|
|
||||||
|
Assert.Equal(10, guardEvents[4].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.WakeUp, guardEvents[4].Type);
|
||||||
|
|
||||||
|
Assert.Equal(99, guardEvents[5].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.ShiftBegin, guardEvents[5].Type);
|
||||||
|
|
||||||
|
Assert.Equal(99, guardEvents[6].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.FallSleep, guardEvents[6].Type);
|
||||||
|
|
||||||
|
Assert.Equal(99, guardEvents[7].ID);
|
||||||
|
Assert.Equal(Day04.GuardEventType.WakeUp, guardEvents[7].Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion GuardEvent_FromStringArray
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ResolvePart1__BaseStatement()
|
public void ResolvePart1__BaseStatement()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,63 @@
|
|||||||
|
|
||||||
public class Day06_Tests
|
public class Day06_Tests
|
||||||
{
|
{
|
||||||
|
#region ChronoPoint_FromString
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ChronoPoint_FromString__Test1()
|
||||||
|
{
|
||||||
|
Day06.ChronoPoint point = Day06.ChronoPoint.FromString("1, 1");
|
||||||
|
|
||||||
|
Assert.Equal(1, point.X);
|
||||||
|
Assert.Equal(1, point.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ChronoPoint_FromString__Test2()
|
||||||
|
{
|
||||||
|
Day06.ChronoPoint point = Day06.ChronoPoint.FromString("1, 6");
|
||||||
|
|
||||||
|
Assert.Equal(1, point.X);
|
||||||
|
Assert.Equal(6, point.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ChronoPoint_FromString__Test3()
|
||||||
|
{
|
||||||
|
Day06.ChronoPoint point = Day06.ChronoPoint.FromString("8, 9");
|
||||||
|
|
||||||
|
Assert.Equal(8, point.X);
|
||||||
|
Assert.Equal(9, point.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion ChronoPoint_FromString
|
||||||
|
|
||||||
|
#region ChronoPoint_ManhattanDistance
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ChronoPoint_ManhattanDistance__Test1()
|
||||||
|
{
|
||||||
|
Day06.ChronoPoint p0 = Day06.ChronoPoint.FromString("8, 9");
|
||||||
|
Day06.ChronoPoint p1 = Day06.ChronoPoint.FromString("1, 6");
|
||||||
|
|
||||||
|
int distance = Day06.ChronoPoint.ManhattanDistance(p0, p1);
|
||||||
|
|
||||||
|
Assert.Equal(10, distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ChronoPoint_ManhattanDistance__Test2()
|
||||||
|
{
|
||||||
|
Day06.ChronoPoint p0 = Day06.ChronoPoint.FromString("1, 1");
|
||||||
|
Day06.ChronoPoint p1 = Day06.ChronoPoint.FromString("1, 6");
|
||||||
|
|
||||||
|
int distance = Day06.ChronoPoint.ManhattanDistance(p0, p1);
|
||||||
|
|
||||||
|
Assert.Equal(5, distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion ChronoPoint_ManhattanDistance
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ResolvePart1__Test()
|
public void ResolvePart1__Test()
|
||||||
{
|
{
|
||||||
@@ -18,7 +75,7 @@ public class Day06_Tests
|
|||||||
|
|
||||||
Assert.Equal("17", result);
|
Assert.Equal("17", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ResolvePart2__Test()
|
public void ResolvePart2__Test()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,33 @@
|
|||||||
|
|
||||||
public class Day08_Tests
|
public class Day08_Tests
|
||||||
{
|
{
|
||||||
|
[Fact]
|
||||||
|
public void ChronoLicenceNode_BuildFromIntStream__Test()
|
||||||
|
{
|
||||||
|
Day08.IntStream values = new("2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2");
|
||||||
|
Day08.ChronoLicenceNode result = Day08.ChronoLicenceNode.BuildFromIntStream(values);
|
||||||
|
|
||||||
|
Assert.Equal(2, result.Childs.Count);
|
||||||
|
Assert.Equal(3, result.Metadata.Count);
|
||||||
|
Assert.Equal(1, result.Metadata[0]);
|
||||||
|
Assert.Equal(1, result.Metadata[1]);
|
||||||
|
Assert.Equal(2, result.Metadata[2]);
|
||||||
|
|
||||||
|
Assert.Empty(result.Childs[0].Childs);
|
||||||
|
Assert.Equal(3, result.Childs[0].Metadata.Count);
|
||||||
|
Assert.Equal(10, result.Childs[0].Metadata[0]);
|
||||||
|
Assert.Equal(11, result.Childs[0].Metadata[1]);
|
||||||
|
Assert.Equal(12, result.Childs[0].Metadata[2]);
|
||||||
|
|
||||||
|
Assert.Single(result.Childs[1].Childs);
|
||||||
|
Assert.Single(result.Childs[1].Metadata);
|
||||||
|
Assert.Equal(2, result.Childs[1].Metadata[0]);
|
||||||
|
|
||||||
|
Assert.Empty(result.Childs[1].Childs[0].Childs);
|
||||||
|
Assert.Single(result.Childs[1].Childs[0].Metadata);
|
||||||
|
Assert.Equal(99, result.Childs[1].Childs[0].Metadata[0]);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ResolvePart1__Test()
|
public void ResolvePart1__Test()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,76 @@
|
|||||||
|
|
||||||
public class Day09_Tests
|
public class Day09_Tests
|
||||||
{
|
{
|
||||||
|
#region MarbleGame_PlayGame
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void MarbleGame_PlayGame__Test1()
|
||||||
|
{
|
||||||
|
Day09.MarbleGame marbleGame = new();
|
||||||
|
|
||||||
|
marbleGame.PlayGame(9, 25);
|
||||||
|
long highScore = marbleGame.GetHighScore();
|
||||||
|
|
||||||
|
Assert.Equal(32, highScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void MarbleGame_PlayGame__Test2()
|
||||||
|
{
|
||||||
|
Day09.MarbleGame marbleGame = new();
|
||||||
|
|
||||||
|
marbleGame.PlayGame(10, 1618);
|
||||||
|
long highScore = marbleGame.GetHighScore();
|
||||||
|
|
||||||
|
Assert.Equal(8317, highScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void MarbleGame_PlayGame__Test3()
|
||||||
|
{
|
||||||
|
Day09.MarbleGame marbleGame = new();
|
||||||
|
|
||||||
|
marbleGame.PlayGame(13, 7999);
|
||||||
|
long highScore = marbleGame.GetHighScore();
|
||||||
|
|
||||||
|
Assert.Equal(146373, highScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void MarbleGame_PlayGame__Test4()
|
||||||
|
{
|
||||||
|
Day09.MarbleGame marbleGame = new();
|
||||||
|
|
||||||
|
marbleGame.PlayGame(17, 1104);
|
||||||
|
long highScore = marbleGame.GetHighScore();
|
||||||
|
|
||||||
|
Assert.Equal(2764, highScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void MarbleGame_PlayGame__Test5()
|
||||||
|
{
|
||||||
|
Day09.MarbleGame marbleGame = new();
|
||||||
|
|
||||||
|
marbleGame.PlayGame(21, 6111);
|
||||||
|
long highScore = marbleGame.GetHighScore();
|
||||||
|
|
||||||
|
Assert.Equal(54718, highScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void MarbleGame_PlayGame__Test6()
|
||||||
|
{
|
||||||
|
Day09.MarbleGame marbleGame = new();
|
||||||
|
|
||||||
|
marbleGame.PlayGame(30, 5807);
|
||||||
|
long highScore = marbleGame.GetHighScore();
|
||||||
|
|
||||||
|
Assert.Equal(37305, highScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion MarbleGame_PlayGame
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ResolvePart1__Test1()
|
public void ResolvePart1__Test1()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,131 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace AdventOfCode2018.Tests;
|
|
||||||
|
|
||||||
public class GuardEvent_Tests
|
|
||||||
{
|
|
||||||
#region FromString
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void FromString__ShiftBegin()
|
|
||||||
{
|
|
||||||
GuardEvent guardEvent = GuardEvent.FromString("[1518-11-01 00:00] Guard #10 begins shift");
|
|
||||||
|
|
||||||
Assert.Equal(10, guardEvent.ID);
|
|
||||||
Assert.Equal(11, guardEvent.Date.Month);
|
|
||||||
Assert.Equal(1, guardEvent.Date.Day);
|
|
||||||
Assert.Equal(0, guardEvent.Date.Hour);
|
|
||||||
Assert.Equal(0, guardEvent.Date.Minute);
|
|
||||||
Assert.Equal(GuardEventType.ShiftBegin, guardEvent.Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void FromString__FallSleep()
|
|
||||||
{
|
|
||||||
GuardEvent guardEvent = GuardEvent.FromString("[1518-11-02 00:40] falls asleep");
|
|
||||||
|
|
||||||
Assert.Null(guardEvent.ID);
|
|
||||||
Assert.Equal(11, guardEvent.Date.Month);
|
|
||||||
Assert.Equal(2, guardEvent.Date.Day);
|
|
||||||
Assert.Equal(0, guardEvent.Date.Hour);
|
|
||||||
Assert.Equal(40, guardEvent.Date.Minute);
|
|
||||||
Assert.Equal(GuardEventType.FallSleep, guardEvent.Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void FromString__WakeUp()
|
|
||||||
{
|
|
||||||
GuardEvent guardEvent = GuardEvent.FromString("[1518-11-03 00:29] wakes up");
|
|
||||||
|
|
||||||
Assert.Null(guardEvent.ID);
|
|
||||||
Assert.Equal(11, guardEvent.Date.Month);
|
|
||||||
Assert.Equal(3, guardEvent.Date.Day);
|
|
||||||
Assert.Equal(0, guardEvent.Date.Hour);
|
|
||||||
Assert.Equal(29, guardEvent.Date.Minute);
|
|
||||||
Assert.Equal(GuardEventType.WakeUp, guardEvent.Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion FromString
|
|
||||||
|
|
||||||
#region FromStringArray
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void FromStringArray__TestBase()
|
|
||||||
{
|
|
||||||
List<GuardEvent> guardEvents = GuardEvent.FromStringArray(new[] {
|
|
||||||
"[1518-11-01 00:00] Guard #10 begins shift",
|
|
||||||
"[1518-11-01 00:05] falls asleep",
|
|
||||||
"[1518-11-01 00:25] wakes up",
|
|
||||||
"[1518-11-01 00:30] falls asleep",
|
|
||||||
"[1518-11-01 00:55] wakes up",
|
|
||||||
"[1518-11-01 23:58] Guard #99 begins shift",
|
|
||||||
"[1518-11-02 00:40] falls asleep",
|
|
||||||
"[1518-11-02 00:50] wakes up",
|
|
||||||
});
|
|
||||||
|
|
||||||
Assert.Equal(10, guardEvents[0].ID);
|
|
||||||
Assert.Equal(GuardEventType.ShiftBegin, guardEvents[0].Type);
|
|
||||||
|
|
||||||
Assert.Equal(10, guardEvents[1].ID);
|
|
||||||
Assert.Equal(GuardEventType.FallSleep, guardEvents[1].Type);
|
|
||||||
|
|
||||||
Assert.Equal(10, guardEvents[2].ID);
|
|
||||||
Assert.Equal(GuardEventType.WakeUp, guardEvents[2].Type);
|
|
||||||
|
|
||||||
Assert.Equal(10, guardEvents[3].ID);
|
|
||||||
Assert.Equal(GuardEventType.FallSleep, guardEvents[3].Type);
|
|
||||||
|
|
||||||
Assert.Equal(10, guardEvents[4].ID);
|
|
||||||
Assert.Equal(GuardEventType.WakeUp, guardEvents[4].Type);
|
|
||||||
|
|
||||||
Assert.Equal(99, guardEvents[5].ID);
|
|
||||||
Assert.Equal(GuardEventType.ShiftBegin, guardEvents[5].Type);
|
|
||||||
|
|
||||||
Assert.Equal(99, guardEvents[6].ID);
|
|
||||||
Assert.Equal(GuardEventType.FallSleep, guardEvents[6].Type);
|
|
||||||
|
|
||||||
Assert.Equal(99, guardEvents[7].ID);
|
|
||||||
Assert.Equal(GuardEventType.WakeUp, guardEvents[7].Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void FromStringArray__TestBaseUnsorted()
|
|
||||||
{
|
|
||||||
List<GuardEvent> guardEvents = GuardEvent.FromStringArray(new[] {
|
|
||||||
"[1518-11-01 00:00] Guard #10 begins shift",
|
|
||||||
"[1518-11-01 23:58] Guard #99 begins shift",
|
|
||||||
"[1518-11-01 00:30] falls asleep",
|
|
||||||
"[1518-11-02 00:40] falls asleep",
|
|
||||||
"[1518-11-01 00:05] falls asleep",
|
|
||||||
"[1518-11-02 00:50] wakes up",
|
|
||||||
"[1518-11-01 00:55] wakes up",
|
|
||||||
"[1518-11-01 00:25] wakes up",
|
|
||||||
});
|
|
||||||
|
|
||||||
Assert.Equal(10, guardEvents[0].ID);
|
|
||||||
Assert.Equal(GuardEventType.ShiftBegin, guardEvents[0].Type);
|
|
||||||
|
|
||||||
Assert.Equal(10, guardEvents[1].ID);
|
|
||||||
Assert.Equal(GuardEventType.FallSleep, guardEvents[1].Type);
|
|
||||||
|
|
||||||
Assert.Equal(10, guardEvents[2].ID);
|
|
||||||
Assert.Equal(GuardEventType.WakeUp, guardEvents[2].Type);
|
|
||||||
|
|
||||||
Assert.Equal(10, guardEvents[3].ID);
|
|
||||||
Assert.Equal(GuardEventType.FallSleep, guardEvents[3].Type);
|
|
||||||
|
|
||||||
Assert.Equal(10, guardEvents[4].ID);
|
|
||||||
Assert.Equal(GuardEventType.WakeUp, guardEvents[4].Type);
|
|
||||||
|
|
||||||
Assert.Equal(99, guardEvents[5].ID);
|
|
||||||
Assert.Equal(GuardEventType.ShiftBegin, guardEvents[5].Type);
|
|
||||||
|
|
||||||
Assert.Equal(99, guardEvents[6].ID);
|
|
||||||
Assert.Equal(GuardEventType.FallSleep, guardEvents[6].Type);
|
|
||||||
|
|
||||||
Assert.Equal(99, guardEvents[7].ID);
|
|
||||||
Assert.Equal(GuardEventType.WakeUp, guardEvents[7].Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion FromStringArray
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
namespace AdventOfCode2018.Tests;
|
|
||||||
|
|
||||||
public class MarbleGame_Tests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void PlayGame__Test1()
|
|
||||||
{
|
|
||||||
MarbleGame marbleGame = new();
|
|
||||||
|
|
||||||
marbleGame.PlayGame(9, 25);
|
|
||||||
long highScore = marbleGame.GetHighScore();
|
|
||||||
|
|
||||||
Assert.Equal(32, highScore);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void PlayGame__Test2()
|
|
||||||
{
|
|
||||||
MarbleGame marbleGame = new();
|
|
||||||
|
|
||||||
marbleGame.PlayGame(10, 1618);
|
|
||||||
long highScore = marbleGame.GetHighScore();
|
|
||||||
|
|
||||||
Assert.Equal(8317, highScore);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void PlayGame__Test3()
|
|
||||||
{
|
|
||||||
MarbleGame marbleGame = new();
|
|
||||||
|
|
||||||
marbleGame.PlayGame(13, 7999);
|
|
||||||
long highScore = marbleGame.GetHighScore();
|
|
||||||
|
|
||||||
Assert.Equal(146373, highScore);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void PlayGame__Test4()
|
|
||||||
{
|
|
||||||
MarbleGame marbleGame = new();
|
|
||||||
|
|
||||||
marbleGame.PlayGame(17, 1104);
|
|
||||||
long highScore = marbleGame.GetHighScore();
|
|
||||||
|
|
||||||
Assert.Equal(2764, highScore);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void PlayGame__Test5()
|
|
||||||
{
|
|
||||||
MarbleGame marbleGame = new();
|
|
||||||
|
|
||||||
marbleGame.PlayGame(21, 6111);
|
|
||||||
long highScore = marbleGame.GetHighScore();
|
|
||||||
|
|
||||||
Assert.Equal(54718, highScore);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void PlayGame__Test6()
|
|
||||||
{
|
|
||||||
MarbleGame marbleGame = new();
|
|
||||||
|
|
||||||
marbleGame.PlayGame(30, 5807);
|
|
||||||
long highScore = marbleGame.GetHighScore();
|
|
||||||
|
|
||||||
Assert.Equal(37305, highScore);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -175,100 +175,100 @@ public class Day04 : IDay
|
|||||||
|
|
||||||
return dictFullHistogram;
|
return dictFullHistogram;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public enum GuardEventType
|
public enum GuardEventType
|
||||||
{
|
|
||||||
ShiftBegin,
|
|
||||||
FallSleep,
|
|
||||||
WakeUp,
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GuardEvent
|
|
||||||
{
|
|
||||||
public DateTime Date { get; set; }
|
|
||||||
public int? ID { get; set; }
|
|
||||||
public GuardEventType Type { get; set; }
|
|
||||||
|
|
||||||
public static GuardEvent FromString(string strEvent)
|
|
||||||
{
|
{
|
||||||
GuardEvent guardEvent = new();
|
ShiftBegin,
|
||||||
string[] parts = strEvent.Split(new[] { "[", "-", " ", ":", "]", "#", }, StringSplitOptions.RemoveEmptyEntries);
|
FallSleep,
|
||||||
guardEvent.Date = new DateTime(
|
WakeUp,
|
||||||
Convert.ToInt32(parts[0]),
|
|
||||||
Convert.ToInt32(parts[1]),
|
|
||||||
Convert.ToInt32(parts[2]),
|
|
||||||
Convert.ToInt32(parts[3]),
|
|
||||||
Convert.ToInt32(parts[4]),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
if (parts[5] == "Guard")
|
|
||||||
{
|
|
||||||
guardEvent.ID = Convert.ToInt32(parts[6]);
|
|
||||||
guardEvent.Type = GuardEventType.ShiftBegin;
|
|
||||||
}
|
|
||||||
if (parts[5] == "falls")
|
|
||||||
{
|
|
||||||
guardEvent.Type = GuardEventType.FallSleep;
|
|
||||||
}
|
|
||||||
if (parts[5] == "wakes")
|
|
||||||
{
|
|
||||||
guardEvent.Type = GuardEventType.WakeUp;
|
|
||||||
}
|
|
||||||
return guardEvent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<GuardEvent> FromStringArray(string[] strEvents)
|
public class GuardEvent
|
||||||
{
|
{
|
||||||
List<GuardEvent> guardEvents = strEvents
|
public DateTime Date { get; set; }
|
||||||
.Select(strEvent => FromString(strEvent))
|
public int? ID { get; set; }
|
||||||
.OrderBy(guardEvent => guardEvent.Date)
|
public GuardEventType Type { get; set; }
|
||||||
.ToList();
|
|
||||||
|
|
||||||
int? guardID = null;
|
public static GuardEvent FromString(string strEvent)
|
||||||
foreach (GuardEvent guardEvent in guardEvents)
|
|
||||||
{
|
{
|
||||||
if (guardEvent.Type == GuardEventType.ShiftBegin)
|
GuardEvent guardEvent = new();
|
||||||
|
string[] parts = strEvent.Split(new[] { "[", "-", " ", ":", "]", "#", }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
guardEvent.Date = new DateTime(
|
||||||
|
Convert.ToInt32(parts[0]),
|
||||||
|
Convert.ToInt32(parts[1]),
|
||||||
|
Convert.ToInt32(parts[2]),
|
||||||
|
Convert.ToInt32(parts[3]),
|
||||||
|
Convert.ToInt32(parts[4]),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (parts[5] == "Guard")
|
||||||
{
|
{
|
||||||
guardID = guardEvent.ID;
|
guardEvent.ID = Convert.ToInt32(parts[6]);
|
||||||
|
guardEvent.Type = GuardEventType.ShiftBegin;
|
||||||
}
|
}
|
||||||
else
|
if (parts[5] == "falls")
|
||||||
{
|
{
|
||||||
guardEvent.ID = guardID;
|
guardEvent.Type = GuardEventType.FallSleep;
|
||||||
|
}
|
||||||
|
if (parts[5] == "wakes")
|
||||||
|
{
|
||||||
|
guardEvent.Type = GuardEventType.WakeUp;
|
||||||
|
}
|
||||||
|
return guardEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<GuardEvent> FromStringArray(string[] strEvents)
|
||||||
|
{
|
||||||
|
List<GuardEvent> guardEvents = strEvents
|
||||||
|
.Select(strEvent => FromString(strEvent))
|
||||||
|
.OrderBy(guardEvent => guardEvent.Date)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
int? guardID = null;
|
||||||
|
foreach (GuardEvent guardEvent in guardEvents)
|
||||||
|
{
|
||||||
|
if (guardEvent.Type == GuardEventType.ShiftBegin)
|
||||||
|
{
|
||||||
|
guardID = guardEvent.ID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
guardEvent.ID = guardID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return guardEvents;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GuardSleepHistogram
|
||||||
|
{
|
||||||
|
public const int MinutesOnHour = 60;
|
||||||
|
public int ID { get; set; }
|
||||||
|
public int[] SleepOnMunute { get; } = new int[MinutesOnHour];
|
||||||
|
|
||||||
|
public void FallSleep(int minute)
|
||||||
|
{
|
||||||
|
for (int i = minute; i < MinutesOnHour; i++)
|
||||||
|
{
|
||||||
|
SleepOnMunute[i] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return guardEvents;
|
public void WakeUp(int minute)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GuardSleepHistogram
|
|
||||||
{
|
|
||||||
public const int MinutesOnHour = 60;
|
|
||||||
public int ID { get; set; }
|
|
||||||
public int[] SleepOnMunute { get; } = new int[MinutesOnHour];
|
|
||||||
|
|
||||||
public void FallSleep(int minute)
|
|
||||||
{
|
|
||||||
for (int i = minute; i < MinutesOnHour; i++)
|
|
||||||
{
|
{
|
||||||
SleepOnMunute[i] = 1;
|
for (int i = minute; i < MinutesOnHour; i++)
|
||||||
|
{
|
||||||
|
SleepOnMunute[i] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void WakeUp(int minute)
|
public void AddHistogram(GuardSleepHistogram histogram)
|
||||||
{
|
|
||||||
for (int i = minute; i < MinutesOnHour; i++)
|
|
||||||
{
|
{
|
||||||
SleepOnMunute[i] = 0;
|
for (int i = 0; i < MinutesOnHour; i++)
|
||||||
}
|
{
|
||||||
}
|
SleepOnMunute[i] += histogram.SleepOnMunute[i];
|
||||||
|
}
|
||||||
public void AddHistogram(GuardSleepHistogram histogram)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < MinutesOnHour; i++)
|
|
||||||
{
|
|
||||||
SleepOnMunute[i] += histogram.SleepOnMunute[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,16 +112,16 @@ public class Day06 : IDay
|
|||||||
{
|
{
|
||||||
pointsAreas.Add(i, 0);
|
pointsAreas.Add(i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int minX = points.Min(p => p.X) - 1;
|
int minX = points.Min(p => p.X) - 1;
|
||||||
int maxX = points.Max(p => p.X) + 1;
|
int maxX = points.Max(p => p.X) + 1;
|
||||||
int minY = points.Min(p => p.Y) - 1;
|
int minY = points.Min(p => p.Y) - 1;
|
||||||
int maxY = points.Max(p => p.Y) + 1;
|
int maxY = points.Max(p => p.Y) + 1;
|
||||||
|
|
||||||
ChronoPoint samplingPoint = new();
|
ChronoPoint samplingPoint = new();
|
||||||
for(int i=minX; i <= maxX; i++)
|
for (int i = minX; i <= maxX; i++)
|
||||||
{
|
{
|
||||||
for(int j = minY; j <= maxY; j++)
|
for (int j = minY; j <= maxY; j++)
|
||||||
{
|
{
|
||||||
samplingPoint.X = i;
|
samplingPoint.X = i;
|
||||||
samplingPoint.Y = j;
|
samplingPoint.Y = j;
|
||||||
@@ -195,28 +195,28 @@ public class Day06 : IDay
|
|||||||
int areaInRange = AreaInThresold(points, DistanceThresold);
|
int areaInRange = AreaInThresold(points, DistanceThresold);
|
||||||
return areaInRange.ToString();
|
return areaInRange.ToString();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class ChronoPoint
|
public class ChronoPoint
|
||||||
{
|
|
||||||
public int X { get; set; }
|
|
||||||
public int Y { get; set; }
|
|
||||||
|
|
||||||
public static ChronoPoint FromString(string strPoint)
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(strPoint)) { return null; }
|
public int X { get; set; }
|
||||||
string[] parts = strPoint.Split(new[] { ", ", }, StringSplitOptions.RemoveEmptyEntries);
|
public int Y { get; set; }
|
||||||
if (parts.Length < 2) { return null; }
|
|
||||||
ChronoPoint point = new() {
|
|
||||||
X = Convert.ToInt32(parts[0]),
|
|
||||||
Y = Convert.ToInt32(parts[1]),
|
|
||||||
};
|
|
||||||
return point;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int ManhattanDistance(ChronoPoint p0, ChronoPoint p1)
|
public static ChronoPoint FromString(string strPoint)
|
||||||
{
|
{
|
||||||
int distance = Math.Abs(p1.X - p0.X) + Math.Abs(p1.Y - p0.Y);
|
if (string.IsNullOrEmpty(strPoint)) { return null; }
|
||||||
return distance;
|
string[] parts = strPoint.Split(new[] { ", ", }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (parts.Length < 2) { return null; }
|
||||||
|
ChronoPoint point = new() {
|
||||||
|
X = Convert.ToInt32(parts[0]),
|
||||||
|
Y = Convert.ToInt32(parts[1]),
|
||||||
|
};
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int ManhattanDistance(ChronoPoint p0, ChronoPoint p1)
|
||||||
|
{
|
||||||
|
int distance = Math.Abs(p1.X - p0.X) + Math.Abs(p1.Y - p0.Y);
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,154 +130,154 @@ public class Day07 : IDay
|
|||||||
int totalElapsedTime = instructions.SimulateInstructionsUsage(NumberOfWorkers);
|
int totalElapsedTime = instructions.SimulateInstructionsUsage(NumberOfWorkers);
|
||||||
return totalElapsedTime.ToString();
|
return totalElapsedTime.ToString();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class InstructionNode
|
public class InstructionNode
|
||||||
{
|
|
||||||
public string NodeID { get; set; }
|
|
||||||
|
|
||||||
public List<string> PreviousNodeIDs { get; } = new();
|
|
||||||
|
|
||||||
public int Cost { get; set; }
|
|
||||||
|
|
||||||
public bool Running { get; set; }
|
|
||||||
|
|
||||||
public bool Used { get; set; }
|
|
||||||
|
|
||||||
public bool CanBeUsed(Dictionary<string, InstructionNode> allNodes)
|
|
||||||
{
|
{
|
||||||
if (PreviousNodeIDs.Count == 0) { return true; }
|
public string NodeID { get; set; }
|
||||||
bool allPreviousUsed = PreviousNodeIDs.All(nodeID => allNodes[nodeID].Used);
|
|
||||||
return allPreviousUsed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Instructions
|
public List<string> PreviousNodeIDs { get; } = new();
|
||||||
{
|
|
||||||
public Dictionary<string, InstructionNode> Nodes { get; } = new();
|
|
||||||
|
|
||||||
public InstructionNode GetNode(string nodeID)
|
public int Cost { get; set; }
|
||||||
{
|
|
||||||
InstructionNode node = null;
|
public bool Running { get; set; }
|
||||||
if (Nodes.ContainsKey(nodeID))
|
|
||||||
|
public bool Used { get; set; }
|
||||||
|
|
||||||
|
public bool CanBeUsed(Dictionary<string, InstructionNode> allNodes)
|
||||||
{
|
{
|
||||||
node = Nodes[nodeID];
|
if (PreviousNodeIDs.Count == 0) { return true; }
|
||||||
|
bool allPreviousUsed = PreviousNodeIDs.All(nodeID => allNodes[nodeID].Used);
|
||||||
|
return allPreviousUsed;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
node = new InstructionNode { NodeID = nodeID, };
|
|
||||||
Nodes.Add(nodeID, node);
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddNodeRelation(string nodeID, string previousNodeID)
|
public class Instructions
|
||||||
{
|
{
|
||||||
InstructionNode node = GetNode(nodeID);
|
public Dictionary<string, InstructionNode> Nodes { get; } = new();
|
||||||
InstructionNode previousNode = GetNode(previousNodeID);
|
|
||||||
node.PreviousNodeIDs.Add(previousNode.NodeID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<InstructionNode> SortInstructions()
|
public InstructionNode GetNode(string nodeID)
|
||||||
{
|
|
||||||
List<InstructionNode> finalNodes = new();
|
|
||||||
|
|
||||||
foreach (InstructionNode node in Nodes.Values)
|
|
||||||
{
|
{
|
||||||
node.Used = false;
|
InstructionNode node = null;
|
||||||
}
|
if (Nodes.ContainsKey(nodeID))
|
||||||
|
|
||||||
List<InstructionNode> unusedNodes;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
unusedNodes = Nodes.Values
|
|
||||||
.Where(n =>
|
|
||||||
n.Used == false &&
|
|
||||||
n.CanBeUsed(Nodes))
|
|
||||||
.OrderBy(n => n.NodeID)
|
|
||||||
.ToList();
|
|
||||||
if (unusedNodes.Count > 0)
|
|
||||||
{
|
{
|
||||||
InstructionNode node = unusedNodes.FirstOrDefault();
|
node = Nodes[nodeID];
|
||||||
finalNodes.Add(node);
|
|
||||||
node.Used = true;
|
|
||||||
}
|
}
|
||||||
} while (unusedNodes.Count > 0);
|
else
|
||||||
return finalNodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SimulatedWorker
|
|
||||||
{
|
|
||||||
public InstructionNode CurrentInstruction { get; set; }
|
|
||||||
public int ElapsedTime { get; set; }
|
|
||||||
|
|
||||||
public void SetInstruction(InstructionNode instruction)
|
|
||||||
{
|
|
||||||
CurrentInstruction = instruction;
|
|
||||||
ElapsedTime = 0;
|
|
||||||
instruction.Running = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Work()
|
|
||||||
{
|
|
||||||
if (CurrentInstruction == null) { return false; }
|
|
||||||
ElapsedTime++;
|
|
||||||
if (CurrentInstruction.Cost <= ElapsedTime)
|
|
||||||
{
|
{
|
||||||
CurrentInstruction.Running = false;
|
node = new InstructionNode { NodeID = nodeID, };
|
||||||
CurrentInstruction.Used = true;
|
Nodes.Add(nodeID, node);
|
||||||
CurrentInstruction = null;
|
|
||||||
}
|
}
|
||||||
return true;
|
return node;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int SimulateInstructionsUsage(int numberOfWorkers)
|
|
||||||
{
|
|
||||||
int totalElapsedTime = 0;
|
|
||||||
foreach (InstructionNode node in Nodes.Values)
|
|
||||||
{
|
|
||||||
node.Used = false;
|
|
||||||
node.Running = false;
|
|
||||||
}
|
|
||||||
List<SimulatedWorker> workers = new(numberOfWorkers);
|
|
||||||
for (int i = 0; i < numberOfWorkers; i++)
|
|
||||||
{
|
|
||||||
workers.Add(new SimulatedWorker());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool anyWorkerWitoutWork;
|
public void AddNodeRelation(string nodeID, string previousNodeID)
|
||||||
do
|
|
||||||
{
|
{
|
||||||
bool anyWorkDone = false;
|
InstructionNode node = GetNode(nodeID);
|
||||||
foreach (SimulatedWorker worker in workers)
|
InstructionNode previousNode = GetNode(previousNodeID);
|
||||||
|
node.PreviousNodeIDs.Add(previousNode.NodeID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<InstructionNode> SortInstructions()
|
||||||
|
{
|
||||||
|
List<InstructionNode> finalNodes = new();
|
||||||
|
|
||||||
|
foreach (InstructionNode node in Nodes.Values)
|
||||||
{
|
{
|
||||||
if (worker.Work())
|
node.Used = false;
|
||||||
{
|
|
||||||
anyWorkDone = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (anyWorkDone) { totalElapsedTime++; }
|
|
||||||
|
|
||||||
anyWorkerWitoutWork = workers.Any(w => w.CurrentInstruction == null);
|
List<InstructionNode> unusedNodes;
|
||||||
if (anyWorkerWitoutWork)
|
do
|
||||||
{
|
{
|
||||||
List<InstructionNode> unusedNodes = Nodes.Values
|
unusedNodes = Nodes.Values
|
||||||
.Where(n =>
|
.Where(n =>
|
||||||
n.Used == false && n.Running == false &&
|
n.Used == false &&
|
||||||
n.CanBeUsed(Nodes))
|
n.CanBeUsed(Nodes))
|
||||||
.OrderBy(n => n.NodeID)
|
.OrderBy(n => n.NodeID)
|
||||||
.ToList();
|
.ToList();
|
||||||
if (unusedNodes.Count > 0)
|
if (unusedNodes.Count > 0)
|
||||||
{
|
{
|
||||||
List<SimulatedWorker> workersWithoutWork = workers.Where(w => w.CurrentInstruction == null).ToList();
|
InstructionNode node = unusedNodes.FirstOrDefault();
|
||||||
for (int i = 0; i < workersWithoutWork.Count && i < unusedNodes.Count; i++)
|
finalNodes.Add(node);
|
||||||
|
node.Used = true;
|
||||||
|
}
|
||||||
|
} while (unusedNodes.Count > 0);
|
||||||
|
return finalNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SimulatedWorker
|
||||||
|
{
|
||||||
|
public InstructionNode CurrentInstruction { get; set; }
|
||||||
|
public int ElapsedTime { get; set; }
|
||||||
|
|
||||||
|
public void SetInstruction(InstructionNode instruction)
|
||||||
|
{
|
||||||
|
CurrentInstruction = instruction;
|
||||||
|
ElapsedTime = 0;
|
||||||
|
instruction.Running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Work()
|
||||||
|
{
|
||||||
|
if (CurrentInstruction == null) { return false; }
|
||||||
|
ElapsedTime++;
|
||||||
|
if (CurrentInstruction.Cost <= ElapsedTime)
|
||||||
|
{
|
||||||
|
CurrentInstruction.Running = false;
|
||||||
|
CurrentInstruction.Used = true;
|
||||||
|
CurrentInstruction = null;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SimulateInstructionsUsage(int numberOfWorkers)
|
||||||
|
{
|
||||||
|
int totalElapsedTime = 0;
|
||||||
|
foreach (InstructionNode node in Nodes.Values)
|
||||||
|
{
|
||||||
|
node.Used = false;
|
||||||
|
node.Running = false;
|
||||||
|
}
|
||||||
|
List<SimulatedWorker> workers = new(numberOfWorkers);
|
||||||
|
for (int i = 0; i < numberOfWorkers; i++)
|
||||||
|
{
|
||||||
|
workers.Add(new SimulatedWorker());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool anyWorkerWitoutWork;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
bool anyWorkDone = false;
|
||||||
|
foreach (SimulatedWorker worker in workers)
|
||||||
|
{
|
||||||
|
if (worker.Work())
|
||||||
{
|
{
|
||||||
workersWithoutWork[i].SetInstruction(unusedNodes[i]);
|
anyWorkDone = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (anyWorkDone) { totalElapsedTime++; }
|
||||||
} while (workers.Any(w => w.CurrentInstruction != null));
|
|
||||||
return totalElapsedTime;
|
anyWorkerWitoutWork = workers.Any(w => w.CurrentInstruction == null);
|
||||||
|
if (anyWorkerWitoutWork)
|
||||||
|
{
|
||||||
|
List<InstructionNode> unusedNodes = Nodes.Values
|
||||||
|
.Where(n =>
|
||||||
|
n.Used == false && n.Running == false &&
|
||||||
|
n.CanBeUsed(Nodes))
|
||||||
|
.OrderBy(n => n.NodeID)
|
||||||
|
.ToList();
|
||||||
|
if (unusedNodes.Count > 0)
|
||||||
|
{
|
||||||
|
List<SimulatedWorker> workersWithoutWork = workers.Where(w => w.CurrentInstruction == null).ToList();
|
||||||
|
for (int i = 0; i < workersWithoutWork.Count && i < unusedNodes.Count; i++)
|
||||||
|
{
|
||||||
|
workersWithoutWork[i].SetInstruction(unusedNodes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (workers.Any(w => w.CurrentInstruction != null));
|
||||||
|
return totalElapsedTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,82 +78,82 @@ public class Day08 : IDay
|
|||||||
int result = licenceTree.GetValue();
|
int result = licenceTree.GetValue();
|
||||||
return result.ToString();
|
return result.ToString();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class IntStream
|
public class IntStream
|
||||||
{
|
|
||||||
private int[] _values;
|
|
||||||
private int _index;
|
|
||||||
|
|
||||||
public IntStream(string strValues)
|
|
||||||
{
|
{
|
||||||
_values = strValues
|
private int[] _values;
|
||||||
.Split(new[] { " ", }, StringSplitOptions.RemoveEmptyEntries)
|
private int _index;
|
||||||
.Select(strVal => Convert.ToInt32(strVal))
|
|
||||||
.ToArray();
|
|
||||||
_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Get()
|
public IntStream(string strValues)
|
||||||
{
|
|
||||||
int value = _values[_index];
|
|
||||||
_index++;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ChronoLicenceNode
|
|
||||||
{
|
|
||||||
public List<ChronoLicenceNode> Childs { get; } = new();
|
|
||||||
|
|
||||||
public List<int> Metadata { get; } = new();
|
|
||||||
|
|
||||||
public static ChronoLicenceNode BuildFromIntStream(IntStream stream)
|
|
||||||
{
|
|
||||||
ChronoLicenceNode node = new();
|
|
||||||
int numChilds = stream.Get();
|
|
||||||
int numMetadata = stream.Get();
|
|
||||||
|
|
||||||
for (int i = 0; i < numChilds; i++)
|
|
||||||
{
|
{
|
||||||
ChronoLicenceNode childNode = BuildFromIntStream(stream);
|
_values = strValues
|
||||||
node.Childs.Add(childNode);
|
.Split(new[] { " ", }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
|
.Select(strVal => Convert.ToInt32(strVal))
|
||||||
|
.ToArray();
|
||||||
|
_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < numMetadata; i++)
|
public int Get()
|
||||||
{
|
{
|
||||||
node.Metadata.Add(stream.Get());
|
int value = _values[_index];
|
||||||
|
_index++;
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetChecksum()
|
public class ChronoLicenceNode
|
||||||
{
|
{
|
||||||
int checksum = Metadata.Sum();
|
public List<ChronoLicenceNode> Childs { get; } = new();
|
||||||
foreach (ChronoLicenceNode child in Childs)
|
|
||||||
{
|
|
||||||
checksum += child.GetChecksum();
|
|
||||||
}
|
|
||||||
return checksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetValue()
|
public List<int> Metadata { get; } = new();
|
||||||
{
|
|
||||||
int value = 0;
|
public static ChronoLicenceNode BuildFromIntStream(IntStream stream)
|
||||||
if (Childs.Count == 0)
|
|
||||||
{
|
{
|
||||||
value = Metadata.Sum();
|
ChronoLicenceNode node = new();
|
||||||
}
|
int numChilds = stream.Get();
|
||||||
else
|
int numMetadata = stream.Get();
|
||||||
{
|
|
||||||
foreach (int metadata in Metadata)
|
for (int i = 0; i < numChilds; i++)
|
||||||
{
|
{
|
||||||
int index = metadata - 1;
|
ChronoLicenceNode childNode = BuildFromIntStream(stream);
|
||||||
if (index < 0 || index >= Childs.Count) { continue; }
|
node.Childs.Add(childNode);
|
||||||
value += Childs[index].GetValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < numMetadata; i++)
|
||||||
|
{
|
||||||
|
node.Metadata.Add(stream.Get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetChecksum()
|
||||||
|
{
|
||||||
|
int checksum = Metadata.Sum();
|
||||||
|
foreach (ChronoLicenceNode child in Childs)
|
||||||
|
{
|
||||||
|
checksum += child.GetChecksum();
|
||||||
|
}
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetValue()
|
||||||
|
{
|
||||||
|
int value = 0;
|
||||||
|
if (Childs.Count == 0)
|
||||||
|
{
|
||||||
|
value = Metadata.Sum();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (int metadata in Metadata)
|
||||||
|
{
|
||||||
|
int index = metadata - 1;
|
||||||
|
if (index < 0 || index >= Childs.Count) { continue; }
|
||||||
|
value += Childs[index].GetValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,86 +87,86 @@ public class Day09 : IDay
|
|||||||
long result = marbleGame.GetHighScore();
|
long result = marbleGame.GetHighScore();
|
||||||
return result.ToString();
|
return result.ToString();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class Marble
|
public class Marble
|
||||||
{
|
|
||||||
public long Value { get; set; }
|
|
||||||
public Marble Previous { get; set; }
|
|
||||||
public Marble Next { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MarbleGame
|
|
||||||
{
|
|
||||||
public Dictionary<long, long> Scores { get; } = new();
|
|
||||||
|
|
||||||
private Marble _firstMarble;
|
|
||||||
private Marble _currentMarble;
|
|
||||||
private long _currentPlayer;
|
|
||||||
|
|
||||||
private const long PointValueMultiple = 23;
|
|
||||||
|
|
||||||
public void PlayGame(long numPlayers, long lastMarble, bool showStatus = false)
|
|
||||||
{
|
{
|
||||||
Scores.Clear();
|
public long Value { get; set; }
|
||||||
_firstMarble = new Marble { Value = 0 };
|
public Marble Previous { get; set; }
|
||||||
_firstMarble.Previous = _firstMarble;
|
public Marble Next { get; set; }
|
||||||
_firstMarble.Next = _firstMarble;
|
}
|
||||||
_currentMarble = _firstMarble;
|
|
||||||
|
|
||||||
for (long i = 1; i <= numPlayers; i++) { Scores.Add(i, 0); }
|
public class MarbleGame
|
||||||
|
{
|
||||||
|
public Dictionary<long, long> Scores { get; } = new();
|
||||||
|
|
||||||
for (long i = 0; i <= lastMarble; i++)
|
private Marble _firstMarble;
|
||||||
|
private Marble _currentMarble;
|
||||||
|
private long _currentPlayer;
|
||||||
|
|
||||||
|
private const long PointValueMultiple = 23;
|
||||||
|
|
||||||
|
public void PlayGame(long numPlayers, long lastMarble, bool showStatus = false)
|
||||||
{
|
{
|
||||||
if (showStatus) { PrintStatus(); }
|
Scores.Clear();
|
||||||
|
_firstMarble = new Marble { Value = 0 };
|
||||||
|
_firstMarble.Previous = _firstMarble;
|
||||||
|
_firstMarble.Next = _firstMarble;
|
||||||
|
_currentMarble = _firstMarble;
|
||||||
|
|
||||||
_currentPlayer = (i % numPlayers) + 1;
|
for (long i = 1; i <= numPlayers; i++) { Scores.Add(i, 0); }
|
||||||
Marble newMarble = new() { Value = i + 1 };
|
|
||||||
if ((newMarble.Value % PointValueMultiple) > 0)
|
for (long i = 0; i <= lastMarble; i++)
|
||||||
{
|
{
|
||||||
Marble previousMarble = _currentMarble.Next;
|
if (showStatus) { PrintStatus(); }
|
||||||
Marble nextMarble = previousMarble.Next;
|
|
||||||
newMarble.Previous = previousMarble;
|
_currentPlayer = (i % numPlayers) + 1;
|
||||||
newMarble.Next = nextMarble;
|
Marble newMarble = new() { Value = i + 1 };
|
||||||
previousMarble.Next = newMarble;
|
if ((newMarble.Value % PointValueMultiple) > 0)
|
||||||
nextMarble.Previous = newMarble;
|
{
|
||||||
_currentMarble = newMarble;
|
Marble previousMarble = _currentMarble.Next;
|
||||||
|
Marble nextMarble = previousMarble.Next;
|
||||||
|
newMarble.Previous = previousMarble;
|
||||||
|
newMarble.Next = nextMarble;
|
||||||
|
previousMarble.Next = newMarble;
|
||||||
|
nextMarble.Previous = newMarble;
|
||||||
|
_currentMarble = newMarble;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Marble marbleToRemove = _currentMarble.Previous.Previous.Previous.Previous.Previous.Previous.Previous;
|
||||||
|
_currentMarble = marbleToRemove.Next;
|
||||||
|
marbleToRemove.Previous.Next = marbleToRemove.Next;
|
||||||
|
marbleToRemove.Next.Previous = marbleToRemove.Previous;
|
||||||
|
|
||||||
|
long currentPlayerScore = Scores[_currentPlayer] + (newMarble.Value + marbleToRemove.Value);
|
||||||
|
Scores[_currentPlayer] = currentPlayerScore;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
public void PrintStatus()
|
||||||
|
{
|
||||||
|
Console.Write("[{0}] ", _currentPlayer);
|
||||||
|
Marble marble = _firstMarble;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
Marble marbleToRemove = _currentMarble.Previous.Previous.Previous.Previous.Previous.Previous.Previous;
|
if (_currentMarble.Value == marble.Value)
|
||||||
_currentMarble = marbleToRemove.Next;
|
{
|
||||||
marbleToRemove.Previous.Next = marbleToRemove.Next;
|
Console.Write("({0}) ", marble.Value);
|
||||||
marbleToRemove.Next.Previous = marbleToRemove.Previous;
|
}
|
||||||
|
else
|
||||||
long currentPlayerScore = Scores[_currentPlayer] + (newMarble.Value + marbleToRemove.Value);
|
{
|
||||||
Scores[_currentPlayer] = currentPlayerScore;
|
Console.Write("{0} ", marble.Value);
|
||||||
}
|
}
|
||||||
|
marble = marble.Next;
|
||||||
|
} while (marble.Value != 0);
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long GetHighScore()
|
||||||
|
{
|
||||||
|
return Scores.Values.Max();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PrintStatus()
|
|
||||||
{
|
|
||||||
Console.Write("[{0}] ", _currentPlayer);
|
|
||||||
Marble marble = _firstMarble;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (_currentMarble.Value == marble.Value)
|
|
||||||
{
|
|
||||||
Console.Write("({0}) ", marble.Value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.Write("{0} ", marble.Value);
|
|
||||||
}
|
|
||||||
marble = marble.Next;
|
|
||||||
} while (marble.Value != 0);
|
|
||||||
Console.WriteLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long GetHighScore()
|
|
||||||
{
|
|
||||||
return Scores.Values.Max();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -176,132 +176,132 @@ public class Day10 : IDay
|
|||||||
int t = lightField.SearchSmallerBoundindBox();
|
int t = lightField.SearchSmallerBoundindBox();
|
||||||
return t.ToString();
|
return t.ToString();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class LightPoint
|
public class LightPoint
|
||||||
{
|
|
||||||
public int X { get; set; }
|
|
||||||
public int Y { get; set; }
|
|
||||||
public int VX { get; set; }
|
|
||||||
public int VY { get; set; }
|
|
||||||
|
|
||||||
public static LightPoint FromString(string strPoint)
|
|
||||||
{
|
{
|
||||||
string[] parts = strPoint.Split(new[] { "position=<", " ", ",", "> velocity=<", ">" }, StringSplitOptions.RemoveEmptyEntries);
|
public int X { get; set; }
|
||||||
LightPoint point = new() {
|
public int Y { get; set; }
|
||||||
X = Convert.ToInt32(parts[0]),
|
public int VX { get; set; }
|
||||||
Y = Convert.ToInt32(parts[1]),
|
public int VY { get; set; }
|
||||||
VX = Convert.ToInt32(parts[2]),
|
|
||||||
VY = Convert.ToInt32(parts[3]),
|
|
||||||
};
|
|
||||||
return point;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetX(int t)
|
public static LightPoint FromString(string strPoint)
|
||||||
{
|
|
||||||
return X + (VX * t);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetY(int t)
|
|
||||||
{
|
|
||||||
return Y + (VY * t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class LightField
|
|
||||||
{
|
|
||||||
private readonly List<LightPoint> _points;
|
|
||||||
|
|
||||||
public LightField(string[] strPoints)
|
|
||||||
{
|
|
||||||
_points = strPoints.Select(strPoint => LightPoint.FromString(strPoint)).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int SearchSmallerBoundindBox()
|
|
||||||
{
|
|
||||||
int minHeight = int.MaxValue;
|
|
||||||
int minT = 0;
|
|
||||||
int missCount = 0;
|
|
||||||
int t = 0;
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
int minY = int.MaxValue;
|
string[] parts = strPoint.Split(new[] { "position=<", " ", ",", "> velocity=<", ">" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
int maxY = int.MinValue;
|
LightPoint point = new() {
|
||||||
foreach (LightPoint point in _points)
|
X = Convert.ToInt32(parts[0]),
|
||||||
{
|
Y = Convert.ToInt32(parts[1]),
|
||||||
int y = point.GetY(t);
|
VX = Convert.ToInt32(parts[2]),
|
||||||
if (y < minY) { minY = y; }
|
VY = Convert.ToInt32(parts[3]),
|
||||||
if (y > maxY) { maxY = y; }
|
};
|
||||||
}
|
return point;
|
||||||
int height = (maxY - minY);
|
|
||||||
if (height < minHeight)
|
|
||||||
{
|
|
||||||
minHeight = height;
|
|
||||||
minT = t;
|
|
||||||
missCount = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
missCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
t++;
|
|
||||||
} while (missCount < 1000);
|
|
||||||
return minT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Render(int t, int width, int height)
|
|
||||||
{
|
|
||||||
int minX = int.MaxValue;
|
|
||||||
int minY = int.MaxValue;
|
|
||||||
int maxX = int.MinValue;
|
|
||||||
int maxY = int.MinValue;
|
|
||||||
|
|
||||||
foreach (LightPoint point in _points)
|
|
||||||
{
|
|
||||||
int x = point.GetX(t);
|
|
||||||
int y = point.GetY(t);
|
|
||||||
if (x < minX) { minX = x; }
|
|
||||||
if (y < minY) { minY = y; }
|
|
||||||
if (x > maxX) { maxX = x; }
|
|
||||||
if (y > maxY) { maxY = y; }
|
|
||||||
}
|
|
||||||
minX--;
|
|
||||||
minY--;
|
|
||||||
maxX += 2;
|
|
||||||
maxY += 2;
|
|
||||||
|
|
||||||
double scaleX = (maxX - minX) / (double)width;
|
|
||||||
double scaleY = (maxY - minY) / (double)height;
|
|
||||||
|
|
||||||
int[,] field = new int[width, height];
|
|
||||||
foreach (LightPoint point in _points)
|
|
||||||
{
|
|
||||||
int x = point.GetX(t);
|
|
||||||
int y = point.GetY(t);
|
|
||||||
x = (int)(((x - minX) / scaleX) + 0.5);
|
|
||||||
y = (int)(((y - minY) / scaleY) + 0.5);
|
|
||||||
if (x < 0 || x >= width) { continue; }
|
|
||||||
if (y < 0 || y >= height) { continue; }
|
|
||||||
field[x, y]++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder sb = new();
|
public int GetX(int t)
|
||||||
for (int j = 0; j < height; j++)
|
|
||||||
{
|
{
|
||||||
sb.AppendLine();
|
return X + (VX * t);
|
||||||
for (int i = 0; i < width; i++)
|
}
|
||||||
|
|
||||||
|
public int GetY(int t)
|
||||||
|
{
|
||||||
|
return Y + (VY * t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LightField
|
||||||
|
{
|
||||||
|
private readonly List<LightPoint> _points;
|
||||||
|
|
||||||
|
public LightField(string[] strPoints)
|
||||||
|
{
|
||||||
|
_points = strPoints.Select(strPoint => LightPoint.FromString(strPoint)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SearchSmallerBoundindBox()
|
||||||
|
{
|
||||||
|
int minHeight = int.MaxValue;
|
||||||
|
int minT = 0;
|
||||||
|
int missCount = 0;
|
||||||
|
int t = 0;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
if (field[i, j] > 0)
|
int minY = int.MaxValue;
|
||||||
|
int maxY = int.MinValue;
|
||||||
|
foreach (LightPoint point in _points)
|
||||||
{
|
{
|
||||||
sb.Append("#");
|
int y = point.GetY(t);
|
||||||
|
if (y < minY) { minY = y; }
|
||||||
|
if (y > maxY) { maxY = y; }
|
||||||
|
}
|
||||||
|
int height = (maxY - minY);
|
||||||
|
if (height < minHeight)
|
||||||
|
{
|
||||||
|
minHeight = height;
|
||||||
|
minT = t;
|
||||||
|
missCount = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sb.Append(".");
|
missCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
t++;
|
||||||
|
} while (missCount < 1000);
|
||||||
|
return minT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Render(int t, int width, int height)
|
||||||
|
{
|
||||||
|
int minX = int.MaxValue;
|
||||||
|
int minY = int.MaxValue;
|
||||||
|
int maxX = int.MinValue;
|
||||||
|
int maxY = int.MinValue;
|
||||||
|
|
||||||
|
foreach (LightPoint point in _points)
|
||||||
|
{
|
||||||
|
int x = point.GetX(t);
|
||||||
|
int y = point.GetY(t);
|
||||||
|
if (x < minX) { minX = x; }
|
||||||
|
if (y < minY) { minY = y; }
|
||||||
|
if (x > maxX) { maxX = x; }
|
||||||
|
if (y > maxY) { maxY = y; }
|
||||||
|
}
|
||||||
|
minX--;
|
||||||
|
minY--;
|
||||||
|
maxX += 2;
|
||||||
|
maxY += 2;
|
||||||
|
|
||||||
|
double scaleX = (maxX - minX) / (double)width;
|
||||||
|
double scaleY = (maxY - minY) / (double)height;
|
||||||
|
|
||||||
|
int[,] field = new int[width, height];
|
||||||
|
foreach (LightPoint point in _points)
|
||||||
|
{
|
||||||
|
int x = point.GetX(t);
|
||||||
|
int y = point.GetY(t);
|
||||||
|
x = (int)(((x - minX) / scaleX) + 0.5);
|
||||||
|
y = (int)(((y - minY) / scaleY) + 0.5);
|
||||||
|
if (x < 0 || x >= width) { continue; }
|
||||||
|
if (y < 0 || y >= height) { continue; }
|
||||||
|
field[x, y]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = new();
|
||||||
|
for (int j = 0; j < height; j++)
|
||||||
|
{
|
||||||
|
sb.AppendLine();
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
if (field[i, j] > 0)
|
||||||
|
{
|
||||||
|
sb.Append("#");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.Append(".");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
return sb.ToString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user