-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSolution.cs
141 lines (117 loc) · 4.09 KB
/
Solution.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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace AdventOfCode2016.Day08
{
internal class Solution
{
private const int ScreenWidth = 50;
private const int ScreenHeight = 6;
private readonly IReadOnlyCollection<IInstruction> _instructions;
public Solution(IEnumerable<string> input)
{
_instructions = input.Select(ParseInstruction).ToList();
}
public int PartOne()
{
var screen = CreateScreen();
return screen.Cast<bool>().Count(x => x);
}
public string PartTwo()
{
var screen = CreateScreen();
var result = new StringBuilder();
for (var y = 0; y < screen.Height(); y++)
{
var line = string.Concat(screen.GetRow(y).Select(b => b ? '#' : ' '));
result.AppendLine(line);
}
return result.ToString();
}
private bool[,] CreateScreen()
{
var screen = new bool[ScreenWidth, ScreenHeight];
foreach (var instruction in _instructions)
{
instruction.Invoke(screen);
}
return screen;
}
private static IInstruction ParseInstruction(string line)
{
Match match;
const string rectPattern = @"rect (?<w>\d+)x(?<h>\d+)";
if (Regex.IsMatch(line, rectPattern))
{
match = Regex.Match(line, rectPattern);
var width = int.Parse(match.Groups["w"].Value);
var height = int.Parse(match.Groups["h"].Value);
return new DrawRectangle {Width = width, Height = height};
}
const string rotateRowPattern = @"rotate row y=(?<y>\d+) by (?<n>\d+)";
if (Regex.IsMatch(line, rotateRowPattern))
{
match = Regex.Match(line, rotateRowPattern);
var y = int.Parse(match.Groups["y"].Value);
var n = int.Parse(match.Groups["n"].Value);
return new RotateRow {Y = y, Pixels = n};
}
const string rotateColumnPattern = @"rotate column x=(?<x>\d+) by (?<n>\d+)";
if (Regex.IsMatch(line, rotateColumnPattern))
{
match = Regex.Match(line, rotateColumnPattern);
var x = int.Parse(match.Groups["x"].Value);
var n = int.Parse(match.Groups["n"].Value);
return new RotateColumn {X = x, Pixels = n};
}
throw new InvalidOperationException($"Unknown instruction: {line}");
}
}
internal interface IInstruction
{
void Invoke(bool[,] screen);
}
internal class DrawRectangle : IInstruction
{
public int Width { get; set; }
public int Height { get; set; }
public void Invoke(bool[,] screen)
{
for (var x = 0; x < Width; x++)
for (var y = 0; y < Height; y++)
{
screen[x, y] = true;
}
}
}
internal class RotateRow : IInstruction
{
public int Y { get; set; }
public int Pixels { get; set; }
public void Invoke(bool[,] screen)
{
var row = screen.GetRow(Y);
for (var x = 0; x < screen.Width(); x++)
{
var newX = (x + Pixels) % screen.Width();
screen[newX, Y] = row[x];
}
}
}
internal class RotateColumn : IInstruction
{
public int X { get; set; }
public int Pixels { get; set; }
public void Invoke(bool[,] screen)
{
var column = screen.GetColumn(X);
for (var y = 0; y < screen.Height(); y++)
{
var newY = (y + Pixels) % screen.Height();
screen[X, newY] = column[y];
}
}
}
}