Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #load "xunit"
- #load "..\AOC Connector"
- #load "..\AOC 2d Array"
- 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, 10);
- //solve A
- var answerA = SolveA(aoc.InputLines);
- aoc.SubmitAnswer(answerA.d1 * answerA.d3, Part.A);
- //solve B
- aoc.SubmitAnswer(SolveB(aoc.InputLines), Part.B);
- }
- public (int d1, int d3) SolveA(string[] input)
- {
- //add first 0, and last + 3
- var adaptors = CreateListWithSocketAndLast(input);
- //store deltas
- var lstDeltas = new List<int>();
- for(int i = 0; i < adaptors.Length - 1; i++)
- {
- lstDeltas.Add(adaptors[i + 1] - adaptors[i]);
- }
- //done
- return (lstDeltas.Count(x => x == 1), lstDeltas.Count(x => x == 3));
- }
- public long SolveB(string[] input)
- {
- //final answer is stored here, it is multiplication so start with 1
- long result = 1;
- //repeating combo results are stored here
- int[] resultCaching = new int[10];
- //get data
- var adaptors = CreateListWithSocketAndLast(input);
- //start of current slice
- int startOfCurrentSlice = 0;
- //loop through the data
- for (int i = 0; i < adaptors.Length - 1; i++)
- {
- //next step is 3, so get all posibble
- if(adaptors[i + 1] - adaptors[i] == 3)
- {
- //determin length
- int setLength = i - startOfCurrentSlice + 1;
- //not cached?
- if (resultCaching[setLength] == 0)
- {
- var set = adaptors[startOfCurrentSlice..(i+1)];
- resultCaching[setLength] = GetAllPossibe(set, new List<int>(), 0).Distinct().Count();
- }
- result *= resultCaching[setLength];
- startOfCurrentSlice = i + 1;
- }
- }
- //done
- return result;
- //quick recursive search for all possible
- IEnumerable<string> GetAllPossibe(int[] input, List<int> lst, int startIndex)
- {
- //valid combo?
- if (lst.Count == 0 || input[startIndex] - lst.Last() <= 3)
- {
- //create new list, and add item
- lst = new List<int>(lst);
- lst.Add(input[startIndex]);
- //are we finished?
- if (input.Length - 1 == startIndex)
- yield return string.Join("", lst);
- else
- {
- //try all other combos, start and the next item in the array
- for (int i = startIndex + 1; i < input.Length; i++)
- {
- foreach (var element in GetAllPossibe(input, lst, i))
- {
- yield return element;
- }
- }
- }
- }
- }
- }
- int[] CreateListWithSocketAndLast(string[] lines)
- {
- var result = new List<int> { 0 };
- result.AddRange(lines.Select(x => int.Parse(x)));
- result.Add(result.Max() + 3);
- result = result.OrderBy(x => x).ToList();
- return result.ToArray();
- }
- #region private::Tests
- #region test data
- string[] testData = new []
- {
- "16",
- "10",
- "15",
- "5",
- "1",
- "11",
- "7",
- "19",
- "6",
- "12",
- "4",
- };
- string[] testData2 = new []
- {
- "28",
- "33",
- "18",
- "42",
- "31",
- "14",
- "46",
- "20",
- "48",
- "47",
- "24",
- "23",
- "49",
- "45",
- "19",
- "38",
- "39",
- "11",
- "1",
- "32",
- "25",
- "35",
- "8",
- "17",
- "7",
- "9",
- "4",
- "2",
- "34",
- "10",
- "3",
- };
- #endregion
- //tests
- [Fact] void TestA1() => Assert.Equal((7,5), SolveA(testData));
- [Fact] void TestA2() => Assert.Equal((22, 10), SolveA(testData2));
- [Fact] void TestB1() => Assert.Equal(8, SolveB(testData));
- [Fact] void TestB2() => Assert.Equal(19208, SolveB(testData2));
- #endregion
Advertisement
Add Comment
Please, Sign In to add comment