Skip to content

Commit abd6dd1

Browse files
authored
feat(util): added some helpful utility functions (#9)
1 parent b07694d commit abd6dd1

File tree

1 file changed

+120
-13
lines changed

1 file changed

+120
-13
lines changed

AdventOfCode/Solutions/Utilities.cs

Lines changed: 120 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
using System;
77
using System.Collections.Generic;
8+
using System.Diagnostics;
89
using System.Linq;
910

1011
namespace AdventOfCode.Solutions
@@ -15,10 +16,10 @@ public static class Utilities
1516

1617
public static int[] ToIntArray(this string str, string delimiter = "")
1718
{
18-
if(delimiter == "")
19+
if (delimiter == "")
1920
{
2021
var result = new List<int>();
21-
foreach(char c in str) if(int.TryParse(c.ToString(), out int n)) result.Add(n);
22+
foreach (char c in str) if (int.TryParse(c.ToString(), out int n)) result.Add(n);
2223
return result.ToArray();
2324
}
2425
else
@@ -32,11 +33,40 @@ public static int[] ToIntArray(this string str, string delimiter = "")
3233

3334
}
3435

36+
public static long[] ToLongArray(this string str, string delimiter = "")
37+
{
38+
if (delimiter == "")
39+
{
40+
var result = new List<long>();
41+
foreach (char c in str) if (long.TryParse(c.ToString(), out long n)) result.Add(n);
42+
return result.ToArray();
43+
}
44+
else
45+
{
46+
return str
47+
.Split(delimiter)
48+
.Where(n => long.TryParse(n, out long v))
49+
.Select(n => Convert.ToInt64(n))
50+
.ToArray();
51+
}
52+
53+
}
54+
55+
public static int[] ToIntArray(this string[] array)
56+
{
57+
return string.Join(",", array).ToIntArray(",");
58+
}
59+
60+
public static void WriteLine(object str)
61+
{
62+
Console.WriteLine(str);
63+
Trace.WriteLine(str);
64+
}
3565

3666
public static int MinOfMany(params int[] items)
3767
{
3868
var result = items[0];
39-
for(int i = 1; i < items.Length; i++)
69+
for (int i = 1; i < items.Length; i++)
4070
{
4171
result = Math.Min(result, items[i]);
4272
}
@@ -46,7 +76,7 @@ public static int MinOfMany(params int[] items)
4676
public static int MaxOfMany(params int[] items)
4777
{
4878
var result = items[0];
49-
for(int i = 1; i < items.Length; i++)
79+
for (int i = 1; i < items.Length; i++)
5080
{
5181
result = Math.Max(result, items[i]);
5282
}
@@ -56,9 +86,9 @@ public static int MaxOfMany(params int[] items)
5686
// https://stackoverflow.com/a/3150821/419956 by @RonWarholic
5787
public static IEnumerable<T> Flatten<T>(this T[,] map)
5888
{
59-
for(int row = 0; row < map.GetLength(0); row++)
89+
for (int row = 0; row < map.GetLength(0); row++)
6090
{
61-
for(int col = 0; col < map.GetLength(1); col++)
91+
for (int col = 0; col < map.GetLength(1); col++)
6292
{
6393
yield return map[row, col];
6494
}
@@ -91,13 +121,17 @@ public static int ManhattanDistance((int x, int y) a, (int x, int y) b)
91121
return Math.Abs(a.x - b.x) + Math.Abs(a.y - b.y);
92122
}
93123

94-
public static double FindGCD(double a, double b) => (a % b == 0) ? b : FindGCD(b, a % b);
124+
public static double FindGCD(double a, double b)
125+
{
126+
if (a == 0 || b == 0) return Math.Max(a, b);
127+
return (a % b == 0) ? b : FindGCD(b, a % b);
128+
}
95129

96130
public static double FindLCM(double a, double b) => a * b / FindGCD(a, b);
97131

98132
public static void Repeat(this Action action, int count)
99133
{
100-
for(int i = 0; i < count; i++) action();
134+
for (int i = 0; i < count; i++) action();
101135
}
102136

103137
// https://github.com/tslater2006/AdventOfCode2019
@@ -106,25 +140,85 @@ public static IEnumerable<IEnumerable<T>> Permutations<T>(this IEnumerable<T> va
106140
return (values.Count() == 1) ? new[] { values } : values.SelectMany(v => Permutations(values.Where(x => x.Equals(v) == false)), (v, p) => p.Prepend(v));
107141
}
108142

143+
public static IEnumerable<IEnumerable<T>> Permutations<T>(this IEnumerable<T> values, int subcount)
144+
{
145+
foreach(var combination in Combinations(values, subcount))
146+
{
147+
var perms = Permutations(combination);
148+
foreach (int i in Enumerable.Range(0, perms.Count())) yield return perms.ElementAt(i);
149+
}
150+
}
151+
152+
private static IEnumerable<int[]> Combinations(int subcount, int length)
153+
{
154+
int[] res = new int[subcount];
155+
Stack<int> stack = new Stack<int>(subcount);
156+
stack.Push(0);
157+
while (stack.Count > 0)
158+
{
159+
int index = stack.Count - 1;
160+
int value = stack.Pop();
161+
while (value < length)
162+
{
163+
res[index++] = value++;
164+
stack.Push(value);
165+
if (index != subcount) continue;
166+
yield return (int[])res.Clone();
167+
break;
168+
}
169+
}
170+
}
171+
172+
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> values, int subcount)
173+
{
174+
if (values.Count() < subcount) throw new ArgumentException("Array Length can't be less than sub-array length");
175+
if (subcount < 1) throw new ArgumentException("Subarrays must be at least length 1 long");
176+
T[] res = new T[subcount];
177+
foreach (var combination in Combinations(subcount, values.Count()))
178+
{
179+
foreach (int i in Enumerable.Range(0, subcount))
180+
{
181+
res[i] = values.ElementAt(combination[i]);
182+
}
183+
184+
yield return res;
185+
}
186+
}
187+
109188
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> array, int size)
110189
{
111-
for(var i = 0; i < (float)array.Count() / size; i++)
190+
for (var i = 0; i < (float)array.Count() / size; i++)
112191
{
113192
yield return array.Skip(i * size).Take(size);
114193
}
115194
}
116195

196+
/// <summary>
197+
/// Rotates an IEnumarable by the requested amount
198+
/// </summary>
199+
/// <typeparam name="T"></typeparam>
200+
/// <param name="array"></param>
201+
/// <param name="rotations">Number of steps to take, positive numbers move indices up (item at end moves to start), negative numbers move them down (first item moves to end of array)</param>
202+
/// <returns></returns>
203+
public static IEnumerable<T> Rotate<T>(this IEnumerable<T> array, int rotations)
204+
{
205+
for(int i = 0; i < array.Count(); i++)
206+
{
207+
yield return i + rotations >= 0 ? array.ElementAt((i + rotations) % array.Count()) : array.ElementAt((i + rotations) + array.Count());
208+
}
209+
}
210+
117211
// https://stackoverflow.com/questions/49190830/is-it-possible-for-string-split-to-return-tuple
118212
public static void Deconstruct<T>(this IList<T> list, out T first, out IList<T> rest)
119213
{
120-
first = list.Count > 0 ? list[0] : default(T); // or throw
214+
first = list.Count > 0 ? list[0] : default; // or throw
121215
rest = list.Skip(1).ToList();
122216
}
123217

124218
public static void Deconstruct<T>(this IList<T> list, out T first, out T second, out IList<T> rest)
125219
{
126-
first = list.Count > 0 ? list[0] : default(T); // or throw
127-
second = list.Count > 1 ? list[1] : default(T); // or throw
220+
first = list.Count > 0 ? list[0] : default; // or throw
221+
second = list.Count > 1 ? list[1] : default; // or throw
128222
rest = list.Skip(2).ToList();
129223
}
130224

@@ -140,5 +234,18 @@ public static T[] Subarray<T>(this T[] array, int offset, int length = -1)
140234
Array.Copy(array, offset, result, 0, length);
141235
return result;
142236
}
237+
238+
//https://stackoverflow.com/questions/2641326/finding-all-positions-of-substring-in-a-larger-string-in-c-sharp
239+
public static IEnumerable<int> AllIndexesOf(this string str, string value)
240+
{
241+
if (String.IsNullOrEmpty(value))
242+
throw new ArgumentException("the string to find may not be empty", nameof(value));
243+
for (int index = 0; ; index += value.Length)
244+
{
245+
index = str.IndexOf(value, index);
246+
if (index == -1) break;
247+
yield return index;
248+
}
249+
}
143250
}
144-
}
251+
}

0 commit comments

Comments
 (0)