Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Day 22 Advent of Code 2020
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