-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMatrix.cs
130 lines (107 loc) · 4.13 KB
/
Matrix.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
using System;
using System.Collections.Generic;
using System.Linq;
namespace AdventOfCode2016
{
public static class Matrix
{
public enum Corner
{
TopLeft,
TopRight,
BottomLeft,
BottomRight,
}
public enum Edge
{
Top,
Bottom,
Left,
Right
}
public static T[,] Create<T>(T[][] data)
{
var height = data.Length;
var width = data.GroupBy(row => row.Length).Single().Key;
var result = new T[width, height];
for (var y = 0; y < height; ++y)
for (var x = 0; x < width; ++x)
result[x, y] = data[y][x];
return result;
}
public static int Width<T>(this T[,] matrix) => matrix.GetLength(0);
public static int Height<T>(this T[,] matrix) => matrix.GetLength(1);
public static T[] GetColumn<T>(this T[,] matrix, int x) =>
Enumerable.Range(0, matrix.Height())
.Select(y => matrix[x, y])
.ToArray();
public static T[] GetRow<T>(this T[,] matrix, int y) =>
Enumerable.Range(0, matrix.Width())
.Select(x => matrix[x, y])
.ToArray();
public static T[] TopEdge<T>(this T[,] matrix) => matrix.GetRow(0);
public static T[] BottomEdge<T>(this T[,] matrix) => matrix.GetRow(matrix.Height() - 1);
public static T[] LeftEdge<T>(this T[,] matrix) => matrix.GetColumn(0);
public static T[] RightEdge<T>(this T[,] matrix) => matrix.GetColumn(matrix.Width() - 1);
public static T[] GetEdge<T>(this T[,] matrix, Edge edge) => edge switch
{
Edge.Top => matrix.TopEdge(),
Edge.Bottom => matrix.BottomEdge(),
Edge.Left => matrix.LeftEdge(),
Edge.Right => matrix.RightEdge(),
_ => throw new ArgumentOutOfRangeException(nameof(edge), edge, null)
};
public static IEnumerable<T[]> GetEdges<T>(this T[,] matrix) =>
Enum.GetValues(typeof(Edge))
.Cast<Edge>()
.Select(matrix.GetEdge);
public static T GetCorner<T>(this T[,] matrix, Corner corner) => corner switch
{
Corner.TopLeft => matrix.TopEdge().First(),
Corner.TopRight => matrix.TopEdge().Last(),
Corner.BottomLeft => matrix.BottomEdge().First(),
Corner.BottomRight => matrix.BottomEdge().Last(),
_ => throw new ArgumentOutOfRangeException(nameof(corner), corner, null)
};
public static IEnumerable<T> GetCorners<T>(this T[,] matrix) =>
Enum.GetValues(typeof(Corner))
.Cast<Corner>()
.Select(matrix.GetCorner);
public static T[,] RotateRight<T>(this T[,] matrix)
{
var height = matrix.GetLength(1);
var width = matrix.GetLength(0);
var result = new T[height, width];
for (var x = 0; x < width; x++)
for (var y = 0; y < height; y++)
{
result[height - 1 - y, x] = matrix[x, y];
}
return result;
}
public static T[,] FlipHorizontal<T>(this T[,] matrix)
{
var width = matrix.GetLength(0);
var height = matrix.GetLength(1);
var result = new T[width, height];
for (var x = 0; x < width; x++)
for (var y = 0; y < height; y++)
{
result[x, y] = matrix[width - 1 - x, y];
}
return result;
}
public static T[,] Transpose<T>(this T[,] matrix)
{
var width = matrix.GetLength(0);
var height = matrix.GetLength(1);
var result = new T[height, width];
for (var x = 0; x < width; x++)
for (var y = 0; y < height; y++)
{
result[y, x] = matrix[x, y];
}
return result;
}
}
}