Created
December 22, 2020 06:34
-
-
Save RichardVasquez/3cfcb3c8a539de0e48b643c51d71551f to your computer and use it in GitHub Desktop.
Day 22 Advent of Code 2020
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using AdventOfCode.Library; | |
namespace AdventOfCode | |
{ | |
// Day 22 | |
internal static class Program | |
{ | |
private const bool DoPart1 = true; | |
private const bool DoPart2 = true; | |
public static void Main() | |
{ | |
var data = TextUtility.ReadBlobs(); | |
// var data = TextUtility.ReadBlobs(filename: "input-sample.txt",); | |
data.Process(DoPart1, 1, Solver1); | |
data.Process(DoPart2, 2, Solver2); | |
} | |
private static string Solver1(List<string> data) | |
{ | |
var playerCards = new List<Queue<int>>(); | |
foreach (string s in data) | |
{ | |
string[] parts = s.Split(":", StringSplitOptions.RemoveEmptyEntries); | |
string[] numbers = parts[1].Split(' ', StringSplitOptions.RemoveEmptyEntries); | |
var tempQueue = new Queue<int>(); | |
foreach (string number in numbers) | |
{ | |
tempQueue.Enqueue(Convert.ToInt32(number)); | |
} | |
playerCards.Add(tempQueue); | |
} | |
while (playerCards.All(q=>q.Count!=0)) | |
{ | |
int p1 = playerCards[0].Dequeue(); | |
int p2 = playerCards[1].Dequeue(); | |
switch (p1>p2) | |
{ | |
case true: | |
playerCards[0].Enqueue(p1); | |
playerCards[0].Enqueue(p2); | |
break; | |
default: | |
playerCards[1].Enqueue(p2); | |
playerCards[1].Enqueue(p1); | |
break; | |
} | |
} | |
var winner = playerCards[0]; | |
if (playerCards[0].Count == 0) | |
{ | |
winner = playerCards[1]; | |
} | |
var final = winner.ToList(); | |
int cardCount = final.Count; | |
var total = 0; | |
for (var i = 0; i < cardCount; i++) | |
{ | |
total += (cardCount - i) * final[i]; | |
} | |
return $"{total}"; | |
} | |
private static string Solver2(List<string> data) | |
{ | |
var playerCards = new List<Queue<int>>(); | |
foreach (string s in data) | |
{ | |
string[] parts = s.Split(":", StringSplitOptions.RemoveEmptyEntries); | |
string[] numbers = parts[1].Split(' ', StringSplitOptions.RemoveEmptyEntries); | |
var tempQueue = new Queue<int>(); | |
foreach (string number in numbers) | |
{ | |
tempQueue.Enqueue(Convert.ToInt32(number)); | |
} | |
playerCards.Add(tempQueue); | |
} | |
PlayRecursive(playerCards, 0); | |
Queue<int> winner = playerCards[0]; | |
if (playerCards[0].Count == 0) | |
{ | |
winner = playerCards[1]; | |
} | |
var final = winner.ToList(); | |
int cardCount = final.Count; | |
var total = 0; | |
for (var i = 0; i < cardCount; i++) | |
{ | |
total += (cardCount - i) * final[i]; | |
} | |
return $"{total}"; | |
} | |
private static List<Queue<int>> PlayRecursive(List<Queue<int>> hands, int level) | |
{ | |
var prevRounds = new HashSet<string>(); | |
while (hands.All(q=>q.Count!=0)) | |
{ | |
if (level != 0) | |
{ | |
var l1 = hands[0].ToList(); | |
var l2 = hands[1].ToList(); | |
string n1 = string.Join('.', l1.Select(l => l.ToString())); | |
string n2 = string.Join('.', l2.Select(l => l.ToString())); | |
var uniqueCheck = $"{n1}|{n2}"; | |
if (prevRounds.Contains(uniqueCheck)) | |
{ | |
//p1 wins | |
var q1 = new Queue<int>(); | |
q1.Enqueue(0); | |
return new List<Queue<int>> {q1 , new Queue<int>()}; | |
} | |
prevRounds.Add(uniqueCheck); | |
} | |
int p1 = hands[0].Dequeue(); | |
int p2 = hands[1].Dequeue(); | |
if (hands[0].Count >= p1 && hands[1].Count >= p2) | |
{ | |
var recurseHand = new List<Queue<int>>(); | |
var tempList1 = hands[0].ToList().Take(p1).ToList(); | |
var tempList2 = hands[1].ToList().Take(p2).ToList(); | |
var tempQ1 = new Queue<int>(); | |
var tempQ2 = new Queue<int>(); | |
foreach (int i in tempList1) | |
{ | |
tempQ1.Enqueue(i); | |
} | |
foreach (int i in tempList2) | |
{ | |
tempQ2.Enqueue(i); | |
} | |
recurseHand.AddRange(new[] {tempQ1, tempQ2}); | |
var val = PlayRecursive(recurseHand, level + 1); | |
if (val[0].Count == 0) | |
{ | |
hands[1].Enqueue(p2); | |
hands[1].Enqueue(p1); | |
} | |
else | |
{ | |
hands[0].Enqueue(p1); | |
hands[0].Enqueue(p2); | |
} | |
} | |
else | |
{ | |
switch (p1 > p2) | |
{ | |
case true: | |
hands[0].Enqueue(p1); | |
hands[0].Enqueue(p2); | |
break; | |
default: | |
hands[1].Enqueue(p2); | |
hands[1].Enqueue(p1); | |
break; | |
} | |
} | |
} | |
var winner = new Queue<int>(); | |
winner.Enqueue(0); | |
var loser = new Queue<int>(); | |
return hands[0].Count == 0 | |
? new List<Queue<int>> {loser, winner} | |
: new List<Queue<int>> {winner, loser}; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment