-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day23.cs
158 lines (149 loc) · 4.64 KB
/
Day23.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
using Draco18s.AoCLib;
using System;
using System.Collections.Generic;
using System.Linq;
namespace AdventofCode2022 {
internal static class DayTwentythree {
public class Elf
{
public Vector2 pos;
public Vector2 proposedMove;
}
enum Direction { North, South, West, East }
internal static long Part1(string input) {
string[] lines = input.Split('\n');
int sum = 0;
Grid ground = new Grid(input, true);
List<Elf> elves = new List<Elf>();
Direction nextConsider = Direction.North;
for (int y = ground.MinY; y < ground.MaxY; y++)
{
for (int x = ground.MinX; x < ground.MaxX; x++)
{
if(ground[x,y] == '#')
{
elves.Add(new Elf()
{
pos = new Vector2(x, y)
});
}
}
}
for(int round = 0; round < 10; round++)
{
//Console.WriteLine(ground.ToString("char+0"));
Grid proposal = new Grid(ground.Width, ground.Height, ground.MinX, ground.MinY);
ProposeMoves(ground, elves, proposal, nextConsider);
ExecuteMoves(ground, elves, proposal, nextConsider);
nextConsider = (Direction)(((int)nextConsider + 1) % 4);
//Console.WriteLine(nextConsider);
}
ground.TrimGrid(()=>'.');
//Console.WriteLine(ground.ToString("char+0"));
return (ground.Width+2) * (ground.Height+2) - elves.Count;
}
private static bool ExecuteMoves(Grid ground, List<Elf> elves, Grid proposal, Direction nextConsider)
{
bool anyMoves = false;
foreach (Elf elf in elves)
{
if (proposal[elf.proposedMove] == 1)
{
//if(elf.pos != elf.proposedMove)
anyMoves = true;
ground[elf.pos] = '.';
ground.IncreaseGridToInclude(elf.proposedMove, () => '.');
elf.pos = elf.proposedMove;
ground[elf.pos] = '#';
}
}
return anyMoves;
}
private static void ProposeMoves(Grid ground, List<Elf> elves, Grid proposal, Direction nextConsider)
{
foreach(Elf elf in elves)
{
int otherElves = 0;
for (int x = -1; x <= 1; x++)
for (int y = -1; y <= 1; y++)
otherElves += ground[elf.pos + new Vector2(x, y), true, () => '.'] == '#' ? 1 : 0;
if (otherElves <= 1)
{
elf.proposedMove = elf.pos;
continue;
}
for (Direction dir = nextConsider; dir < nextConsider + 4; dir++)
if (Consider(elf, dir, ground)) break;
proposal.IncreaseGridToInclude(elf.proposedMove, () => 0);
proposal[elf.proposedMove]++;
}
}
private static bool Consider(Elf elf, Direction dir, Grid ground)
{
switch ((Direction)((int)dir % 4))
{
case Direction.North:
if (ground[elf.pos + new Vector2(0, -1), true, () => '.'] == '.' && ground[elf.pos + new Vector2(-1, -1), true, () => '.'] == '.' && ground[elf.pos + new Vector2(1, -1), true, () => '.'] == '.')
{
elf.proposedMove = elf.pos + new Vector2(0, -1);
return true;
}
break;
case Direction.South:
if (ground[elf.pos + new Vector2(0, 1), true, () => '.'] == '.' && ground[elf.pos + new Vector2(-1, 1), true, () => '.'] == '.' && ground[elf.pos + new Vector2(1, 1), true, () => '.'] == '.')
{
elf.proposedMove = elf.pos + new Vector2(0, 1);
return true;
}
break;
case Direction.West:
if (ground[elf.pos + new Vector2(-1, 1), true, () => '.'] == '.' && ground[elf.pos + new Vector2(-1, 0), true, () => '.'] == '.' && ground[elf.pos + new Vector2(-1, -1), true, () => '.'] == '.')
{
elf.proposedMove = elf.pos + new Vector2(-1, 0);
return true;
}
break;
case Direction.East:
if (ground[elf.pos + new Vector2(1, 1), true, () => '.'] == '.' && ground[elf.pos + new Vector2(1, 0), true, () => '.'] == '.' && ground[elf.pos + new Vector2(1, -1), true, () => '.'] == '.')
{
elf.proposedMove = elf.pos + new Vector2(1, 0);
return true;
}
break;
}
return false;
}
internal static long Part2(string input) {
string[] lines = input.Split('\n');
int sum = 0;
Grid ground = new Grid(input, true);
List<Elf> elves = new List<Elf>();
Direction nextConsider = Direction.North;
for (int y = ground.MinY; y < ground.MaxY; y++)
{
for (int x = ground.MinX; x < ground.MaxX; x++)
{
if (ground[x, y] == '#')
{
elves.Add(new Elf()
{
pos = new Vector2(x, y)
});
}
}
}
while(true)
{
sum++;
//Console.WriteLine(ground.ToString("char+0"));
Grid proposal = new Grid(ground.Width, ground.Height, ground.MinX, ground.MinY);
ProposeMoves(ground, elves, proposal, nextConsider);
bool r = ExecuteMoves(ground, elves, proposal, nextConsider);
if (!r) break;
nextConsider = (Direction)(((int)nextConsider + 1) % 4);
//Console.WriteLine(nextConsider);
}
return sum;
}
}
}