Merge pull request #8 from StevanFreeborn/stevanfreeborn/feat/solve-puzzle-8
feat: solve puzzle 8
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Diagnostics;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Trebuchet;
|
||||
|
||||
@@ -23,9 +24,15 @@ public class Program
|
||||
: new PartOnePuzzleSolver();
|
||||
|
||||
var input = await File.ReadAllLinesAsync(args[0]);
|
||||
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
var result = puzzleSolver.SumCalibrationValues(input);
|
||||
|
||||
Console.WriteLine($"The sum of all calibration values is {result}.");
|
||||
stopwatch.Stop();
|
||||
|
||||
Console.WriteLine($"The sum of all calibration values is {result}. ({stopwatch.ElapsedMilliseconds}ms)");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
global using Xunit;
|
||||
global using FluentAssertions;
|
||||
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\HauntedWasteland\HauntedWasteland.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\INPUT.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,118 @@
|
||||
namespace HauntedWasteland.Tests;
|
||||
|
||||
public class MapTests
|
||||
{
|
||||
[Theory]
|
||||
[MemberData(nameof(TestData.ParseMapTestData), MemberType = typeof(TestData))]
|
||||
public void Parse_WhenGivenStringArray_ItShouldReturnMap(string[] input, Map expected)
|
||||
{
|
||||
Map.Parse(input).Should().BeEquivalentTo(expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(TestData.CountStepsTestData), MemberType = typeof(TestData))]
|
||||
public void CountStepsToZ_WhenGivenMap_ItShouldReturnNumberOfSteps(string[] input, int expected)
|
||||
{
|
||||
Map.Parse(input).CountStepsToZ().Should().Be(expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(TestData.CountStepsToAllZNodesData), MemberType = typeof(TestData))]
|
||||
public void CountStepsToAllZNodes_WhenGivenMap_ItShouldReturnNumberOfSteps(string[] input, long expected)
|
||||
{
|
||||
Map.Parse(input).CountStepsToAllZNodes().Should().Be(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FindPrimeFactors_WhenGivenNumber_ItShouldReturnPrimeFactors()
|
||||
{
|
||||
new Map([], []).FindPrimeFactors(11911).Should().BeEquivalentTo([43, 277]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FindLeastCommonMultiple_WhenGivenNumbers_ItShouldReturnLeastCommonMultiple()
|
||||
{
|
||||
new Map([], []).FindLeastCommonMultiple([16343, 11911, 20221, 21883, 13019, 19667]).Should().Be(13524038372771);
|
||||
}
|
||||
|
||||
public static class TestData
|
||||
{
|
||||
private static readonly string[] MapInput =
|
||||
[
|
||||
"RL",
|
||||
"",
|
||||
"AAA = (BBB, CCC)",
|
||||
"BBB = (DDD, EEE)",
|
||||
"CCC = (ZZZ, GGG)",
|
||||
"DDD = (DDD, DDD)",
|
||||
"EEE = (EEE, EEE)",
|
||||
"GGG = (GGG, GGG)",
|
||||
"ZZZ = (ZZZ, ZZZ)",
|
||||
];
|
||||
|
||||
private static readonly string[] Input = File.ReadAllLines("INPUT.txt");
|
||||
|
||||
public static IEnumerable<object[]> CountStepsTestData =>
|
||||
new List<object[]>
|
||||
{
|
||||
new object[]
|
||||
{
|
||||
MapInput,
|
||||
2
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
Input,
|
||||
13019
|
||||
}
|
||||
};
|
||||
|
||||
public static IEnumerable<object[]> CountStepsToAllZNodesData =>
|
||||
new List<object[]>
|
||||
{
|
||||
new object[]
|
||||
{
|
||||
new string[]
|
||||
{
|
||||
"LR",
|
||||
"",
|
||||
"11A = (11B, XXX)",
|
||||
"11B = (XXX, 11Z)",
|
||||
"11Z = (11B, XXX)",
|
||||
"22A = (22B, XXX)",
|
||||
"22B = (22C, 22C)",
|
||||
"22C = (22Z, 22Z)",
|
||||
"22Z = (22B, 22B)",
|
||||
"XXX = (XXX, XXX)",
|
||||
},
|
||||
6
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
Input,
|
||||
13524038372771
|
||||
}
|
||||
};
|
||||
|
||||
public static IEnumerable<object[]> ParseMapTestData =>
|
||||
new List<object[]>
|
||||
{
|
||||
new object[]
|
||||
{
|
||||
MapInput,
|
||||
new Map(
|
||||
['R', 'L'],
|
||||
[
|
||||
new("AAA", "BBB", "CCC"),
|
||||
new("BBB", "DDD", "EEE"),
|
||||
new("CCC", "ZZZ", "GGG"),
|
||||
new("DDD", "DDD", "DDD"),
|
||||
new("EEE", "EEE", "EEE"),
|
||||
new("GGG", "GGG", "GGG"),
|
||||
new("ZZZ", "ZZZ", "ZZZ"),
|
||||
]
|
||||
)
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
namespace HauntedWasteland.Tests;
|
||||
|
||||
public class NodeTests
|
||||
{
|
||||
[Theory]
|
||||
[MemberData(nameof(TestData.ParseNodeTestData), MemberType = typeof(TestData))]
|
||||
public void Parse_WhenGivenString_ItShouldReturnNode(string input, Node expected)
|
||||
{
|
||||
Node.Parse(input).Should().BeEquivalentTo(expected);
|
||||
}
|
||||
|
||||
public static class TestData
|
||||
{
|
||||
public static IEnumerable<object[]> ParseNodeTestData =>
|
||||
new List<object[]>
|
||||
{
|
||||
new object[]
|
||||
{
|
||||
"AAA = (BBB, CCC)",
|
||||
new Node("AAA", "BBB", "CCC")
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
"BBB = (DDD, EEE)",
|
||||
new Node("BBB", "DDD", "EEE")
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
"CCC = (ZZZ, GGG)",
|
||||
new Node("CCC", "ZZZ", "GGG")
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
"DDD = (DDD, DDD)",
|
||||
new Node("DDD", "DDD", "DDD")
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
"EEE = (EEE, EEE)",
|
||||
new Node("EEE", "EEE", "EEE")
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
"GGG = (GGG, GGG)",
|
||||
new Node("GGG", "GGG", "GGG")
|
||||
},
|
||||
new object[]
|
||||
{
|
||||
"ZZZ = (ZZZ, ZZZ)",
|
||||
new Node("ZZZ", "ZZZ", "ZZZ")
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,254 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace HauntedWasteland;
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static async Task<int> Main(string[] args)
|
||||
{
|
||||
if (args.Length is 0)
|
||||
{
|
||||
Console.WriteLine("Please provide a path to the input file.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (File.Exists(args[0]) is false)
|
||||
{
|
||||
Console.WriteLine("The provided file does not exist.");
|
||||
return -2;
|
||||
}
|
||||
|
||||
var isPart2 = args.Length > 1 && args[1] == "part2";
|
||||
var input = await File.ReadAllLinesAsync(args[0]);
|
||||
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
var map = Map.Parse(input);
|
||||
var result = isPart2
|
||||
? map.CountStepsToAllZNodes()
|
||||
: map.CountStepsToZ();
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
Console.WriteLine($"The number of steps is {result}. ({stopwatch.ElapsedMilliseconds}ms)");
|
||||
|
||||
return (int)result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A map of the Haunted Wasteland.
|
||||
/// </summary>
|
||||
/// <param name="turns">The turns to take at each step.</param>
|
||||
/// <param name="nodes">The nodes in the map.</param>
|
||||
/// <returns>An instance of <see cref="Map"/>.</returns>
|
||||
public class Map(
|
||||
List<char> turns,
|
||||
List<Node> nodes
|
||||
)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the turns to take at each step.
|
||||
/// </summary>
|
||||
public List<char> Turns { get; init; } = turns;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the nodes in the map.
|
||||
/// </summary>
|
||||
public List<Node> Nodes { get; init; } = nodes;
|
||||
|
||||
/// <summary>
|
||||
/// Parses a map from a string array.
|
||||
/// </summary>
|
||||
/// <param name="mapInput">The map input.</param>
|
||||
/// <returns>An instance of <see cref="Map"/>.</returns>
|
||||
public static Map Parse(string[] mapInput)
|
||||
{
|
||||
var turns = mapInput[0].ToList();
|
||||
var nodes = mapInput[2..]
|
||||
.Select(Node.Parse)
|
||||
.ToList();
|
||||
|
||||
return new Map(turns, nodes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Counts the number of steps to the Z node.
|
||||
/// </summary>
|
||||
/// <returns>The number of steps to the Z node.</returns>
|
||||
public int CountStepsToZ()
|
||||
{
|
||||
var current = Nodes.First(n => n.Current == "AAA");
|
||||
var steps = 0;
|
||||
|
||||
while (current.Current != "ZZZ")
|
||||
{
|
||||
var next = Turns[steps % Turns.Count] switch
|
||||
{
|
||||
'R' => current.Right,
|
||||
'L' => current.Left,
|
||||
_ => throw new Exception("Invalid turn")
|
||||
};
|
||||
current = Nodes.First(n => n.Current == next);
|
||||
steps++;
|
||||
}
|
||||
|
||||
return steps;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the prime factors of a number.
|
||||
/// </summary>
|
||||
/// <param name="number">The number to find the prime factors of.</param>
|
||||
/// <returns>The prime factors of the number.</returns>
|
||||
public List<long> FindPrimeFactors(long number)
|
||||
{
|
||||
var factors = new List<long>();
|
||||
|
||||
// Start with the smallest prime number, 2.
|
||||
var divisor = 2;
|
||||
|
||||
// Continue until the number is reduced to 2 or less.
|
||||
while (number >= 2)
|
||||
{
|
||||
// If the number is divisible by the current divisor,
|
||||
if (number % divisor == 0)
|
||||
{
|
||||
// Add the divisor to the list of factors.
|
||||
factors.Add(divisor);
|
||||
// Divide the number by the divisor to reduce it.
|
||||
number /= divisor;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the number is not divisible by the current divisor, increment the divisor.
|
||||
divisor++;
|
||||
}
|
||||
}
|
||||
|
||||
return factors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the least common multiple of a list of numbers.
|
||||
/// </summary>
|
||||
/// <param name="numbers">The numbers to find the least common multiple of.</param>
|
||||
/// <returns>The least common multiple of the numbers.</returns>
|
||||
public long FindLeastCommonMultiple(List<long> numbers)
|
||||
{
|
||||
var primeFactors = numbers.Select(FindPrimeFactors).ToList();
|
||||
|
||||
var uniquePrimeFactors = primeFactors
|
||||
.SelectMany(pf => pf)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
var maxPrimeFactors = uniquePrimeFactors
|
||||
.Select(upf => primeFactors.Max(pf => pf.Count(f => f == upf)))
|
||||
.ToList();
|
||||
|
||||
var result = uniquePrimeFactors
|
||||
.Zip(maxPrimeFactors)
|
||||
.Aggregate(
|
||||
(long)1,
|
||||
(acc, b) =>
|
||||
// b.First is the prime factor
|
||||
// b.Second is the number of times it occurs
|
||||
acc * (long)Math.Pow(b.First, b.Second)
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Counts the number of steps to all Z nodes.
|
||||
/// </summary>
|
||||
/// <returns>The number of steps to all Z nodes.</returns>
|
||||
public long CountStepsToAllZNodes()
|
||||
{
|
||||
var startNodes = Nodes.Where(n => n.Current.EndsWith('A')).ToList();
|
||||
var nodeSteps = new List<long>();
|
||||
|
||||
foreach (var startNode in startNodes)
|
||||
{
|
||||
var current = startNode;
|
||||
var steps = 0;
|
||||
|
||||
while (current.Current.EndsWith('Z') is false)
|
||||
{
|
||||
var next = Turns[steps % Turns.Count] switch
|
||||
{
|
||||
'R' => current.Right,
|
||||
'L' => current.Left,
|
||||
_ => throw new Exception("Invalid turn")
|
||||
};
|
||||
current = Nodes.First(n => n.Current == next);
|
||||
steps++;
|
||||
}
|
||||
|
||||
nodeSteps.Add(steps);
|
||||
}
|
||||
|
||||
return FindLeastCommonMultiple(nodeSteps);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A node in the map.
|
||||
/// </summary>
|
||||
/// <param name="current">The current node.</param>
|
||||
/// <param name="left">The left node.</param>
|
||||
/// <param name="right">The right node.</param>
|
||||
/// <returns>An instance of <see cref="Node"/>.</returns>
|
||||
public class Node(
|
||||
string current,
|
||||
string left,
|
||||
string right
|
||||
)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the current node.
|
||||
/// </summary>
|
||||
public string Current { get; init; } = current;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the left node.
|
||||
/// </summary>
|
||||
public string Left { get; init; } = left;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the right node.
|
||||
/// </summary>
|
||||
public string Right { get; init; } = right;
|
||||
|
||||
/// <summary>
|
||||
/// Casts the node to a string.
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Current} = ({Left},{Right})";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a node from a string.
|
||||
/// </summary>
|
||||
/// <param name="nodeString">The node string.</param>
|
||||
/// <returns>An instance of <see cref="Node"/>.</returns>
|
||||
public static Node Parse(string nodeString)
|
||||
{
|
||||
var parts = nodeString.Split(
|
||||
'=',
|
||||
StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries
|
||||
);
|
||||
var current = parts[0];
|
||||
var nextNodes = parts[1].Split(
|
||||
',',
|
||||
StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries
|
||||
);
|
||||
var left = nextNodes[0].Trim('(');
|
||||
var right = nextNodes[1].Trim(')');
|
||||
|
||||
return new Node(current, left, right);
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CamelCards", "07\CamelCards
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CamelCards.Tests", "07\CamelCards.Tests\CamelCards.Tests.csproj", "{8F04A78E-D2E1-41AC-B43C-74608B7B4FCB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "08", "08", "{F21CCF39-1F8A-40DA-A0E5-F1426B09BAA2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HauntedWasteland", "08\HauntedWasteland\HauntedWasteland.csproj", "{332B56C1-8ECB-4E34-9E69-54BF6A192CFB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HauntedWasteland.Tests", "08\HauntedWasteland.Tests\HauntedWasteland.Tests.csproj", "{FA8DDDD1-4DD9-4927-A9FB-C4FACDEAF901}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -110,6 +116,14 @@ Global
|
||||
{8F04A78E-D2E1-41AC-B43C-74608B7B4FCB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8F04A78E-D2E1-41AC-B43C-74608B7B4FCB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8F04A78E-D2E1-41AC-B43C-74608B7B4FCB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{332B56C1-8ECB-4E34-9E69-54BF6A192CFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{332B56C1-8ECB-4E34-9E69-54BF6A192CFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{332B56C1-8ECB-4E34-9E69-54BF6A192CFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{332B56C1-8ECB-4E34-9E69-54BF6A192CFB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FA8DDDD1-4DD9-4927-A9FB-C4FACDEAF901}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FA8DDDD1-4DD9-4927-A9FB-C4FACDEAF901}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FA8DDDD1-4DD9-4927-A9FB-C4FACDEAF901}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FA8DDDD1-4DD9-4927-A9FB-C4FACDEAF901}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{3F8EAC09-4BC7-43AA-B72B-48DDD2710F6D} = {8C29858C-623A-461A-BF0B-254E151CD9C2}
|
||||
@@ -126,5 +140,7 @@ Global
|
||||
{8C89E1D0-2617-4B89-BA9C-9189FC69BC43} = {86704890-D6B8-4166-853B-F1424B8396C7}
|
||||
{DC16CBE1-B1FA-4E6B-AAD8-43CDECA46659} = {7F8AD027-D8D7-407B-9E08-B363B7B34621}
|
||||
{8F04A78E-D2E1-41AC-B43C-74608B7B4FCB} = {7F8AD027-D8D7-407B-9E08-B363B7B34621}
|
||||
{332B56C1-8ECB-4E34-9E69-54BF6A192CFB} = {F21CCF39-1F8A-40DA-A0E5-F1426B09BAA2}
|
||||
{FA8DDDD1-4DD9-4927-A9FB-C4FACDEAF901} = {F21CCF39-1F8A-40DA-A0E5-F1426B09BAA2}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -43,7 +43,7 @@ dotnet build
|
||||
## Challenges
|
||||
|
||||
| Day | Problem | Solution | Status | Notes |
|
||||
| --- | -------------------------- | :-----------------------------: | :----: | ------------------------------------------------------------------------------------------------------- |
|
||||
| --- | -------------------------- | :--------------------------------: | :----: | ------------------------------------------------------------------------------------------------------- |
|
||||
| 01 | [Problem](./01/PROBLEM.md) | [Solution](./01/Trebuchet/) | ✅ | The trickiest part here was accounting for overlapping digit words. |
|
||||
| 02 | [Problem](./02/PROBLEM.md) | [Solution](./02/CubeConundrum/) | ✅ | The key to me here was to parse the input into a useful model. |
|
||||
| 03 | [Problem](./03/PROBLEM.md) | [Solution](./03/GearRatios/) | ✅ | The edge case that got me here was lines ending with a part number. |
|
||||
@@ -51,7 +51,7 @@ dotnet build
|
||||
| 05 | [Problem](./05/PROBLEM.md) | [Solution](./05/IYGASAF/) | ✅ | I brute forced part 2 using parallelism. I know shame. |
|
||||
| 06 | [Problem](./06/PROBLEM.md) | [Solution](./06/WaitForIt/) | ✅ | Thank goodness part 2 was not like 5's part 2. 😅 |
|
||||
| 07 | [Problem](./07/PROBLEM.md) | [Solution](./07/CamelCards/) | ✅ | What took me longest here was I missed a case when jokers are wild and there are three groups of cards. |
|
||||
| 08 | [Problem](./08/PROBLEM.md) | [Solution](./08/) | ⌛ |
|
||||
| 08 | [Problem](./08/PROBLEM.md) | [Solution](./08/HauntedWasteland/) | ✅ | Got to implement a least common multiple algorithm for part 2. |
|
||||
| 09 | [Problem](./09/PROBLEM.md) | [Solution](./09/) | ⌛ |
|
||||
| 10 | [Problem](./10/PROBLEM.md) | [Solution](./10/) | ⌛ |
|
||||
| 11 | [Problem](./11/PROBLEM.md) | [Solution](./11/) | ⌛ |
|
||||
|
||||
Reference in New Issue
Block a user