-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay22.cs
118 lines (101 loc) · 3.62 KB
/
Day22.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
class Day22
{
public static List<int> Part1(List<int> player1, List<int> player2)
{
while (player1.Count() > 0 && player2.Count() > 0)
{
if (player1[0] > player2[0])
{
player1.Add(player1[0]);
player1.Add(player2[0]);
player1.RemoveAt(0);
player2.RemoveAt(0);
}
else
{
player2.Add(player2[0]);
player2.Add(player1[0]);
player1.RemoveAt(0);
player2.RemoveAt(0);
}
}
return player1.Count() == 0 ? player2 : player1;
}
public static bool Contains(List<(int[], int[])> list, (int[], int[]) item)
{
foreach ((int[], int[]) i in list)
{
if (Enumerable.SequenceEqual(i.Item1, item.Item1) && Enumerable.SequenceEqual(i.Item2, item.Item2))
{
return true;
}
}
return false;
}
public static (bool, List<int>) Part2(List<int> player1, List<int> player2)
{
List<(int[], int[])> previousRounds = new List<(int[], int[])>();
while (player1.Count() > 0 && player2.Count() > 0)
{
//Console.WriteLine("Player 1's deck: " + String.Join(", ", player1));
//Console.WriteLine("Player 2's deck: " + String.Join(", ", player2));
if (Contains(previousRounds, (player1.ToArray(), player2.ToArray())))
{
return (true, player1);
}
previousRounds.Add((player1.ToArray(), player2.ToArray()));
bool player1Win;
if (player1.Count() > player1[0] && player2.Count() > player2[0])
{
player1Win = Part2(player1.GetRange(1, player1[0]), player2.GetRange(1, player2[0])).Item1;
}
else if (player1[0] > player2[0])
player1Win = true;
else
player1Win = false;
if (player1Win)
{
player1.Add(player1[0]);
player1.Add(player2[0]);
player1.RemoveAt(0);
player2.RemoveAt(0);
}
else
{
player2.Add(player2[0]);
player2.Add(player1[0]);
player1.RemoveAt(0);
player2.RemoveAt(0);
}
//Console.WriteLine($"Player " + (player1Win ? 1 : 2) + " win!");
//Console.ReadLine();
}
bool win = player1.Count() > 0;
return (win, win ? player1 : player2);
}
public static int CalculateScore(List<int> winningDeck)
{
int score = 0;
for (int i = 1; i <= winningDeck.Count(); i++)
{
score += i * winningDeck[winningDeck.Count() - i];
}
return score;
}
public static void Main(string[] args)
{
List<string> puzzleInput = File.ReadLines("input.txt").ToList();
string[] players = Regex.Split(String.Join("\n", puzzleInput), "[\n\n]{0,2}Player [1-9]:\n");
List<int> player1 = players[1].Split('\n').Select(int.Parse).ToList();
List<int> player2 = players[2].Split('\n').Select(int.Parse).ToList();
List<int> part1 = Part1(new List<int>(player1), new List<int>(player2));
Console.WriteLine($"Part 1: {CalculateScore(part1)}");
List<int> part2 = Part2(new List<int>(player1), new List<int>(player2)).Item2;
Console.WriteLine($"Part 2: {CalculateScore(part2)}");
}
}