Skip to content

Instantly share code, notes, and snippets.

@hatelove
Last active December 6, 2022 19:38
Show Gist options
  • Save hatelove/355b0740f9f76d1187dc61d6bb21b4fa to your computer and use it in GitHub Desktop.
Save hatelove/355b0740f9f76d1187dc61d6bb21b4fa to your computer and use it in GitHub Desktop.
Find Repeated Item Group from DarkThread: https://blog.darkthread.net/blog/find-repeated-item-group/
[TestFixture]
public class DarkThreadTests
{
[Test]
public void find_repeat_group()
{
var source = new[] { "A", "B", "B", "C", "X", "C", "C", "B", "B", "D", "D", "D" };
var expected = new[]
{
new[] { "B", "B" },
new[] { "C", "C" },
new[] { "B", "B" },
new[] { "D", "D", "D" },
};
ResultShouldBe(source, expected);
}
[Test]
public void find_repeat_group_with_empty_source()
{
var source = new string[] { };
var expected = new IEnumerable<string>[] { };
ResultShouldBe(source, expected);
}
[Test]
public void find_repeat_group_with_only_1_element()
{
var source = new string[] { "A" };
var expected = new IEnumerable<string>[] { };
ResultShouldBe(source, expected);
}
private void ResultShouldBe(IEnumerable<string> source, IEnumerable<IEnumerable<string>> expected)
{
var actual = FindRepeat(source);
actual.Should().BeEquivalentTo(expected, options => options.WithStrictOrdering());
}
private IEnumerable<IEnumerable<string>> FindRepeat(IEnumerable<string> source)
{
var enumerator = source.GetEnumerator();
if (!enumerator.MoveNext())
{
yield break;
}
var queue = new Queue<string>();
var last = enumerator.Current;
queue.Enqueue(last);
while (enumerator.MoveNext())
{
if (enumerator.Current != last)
{
if (queue.Count > 1)
{
yield return queue.ToArray();
}
queue.Clear();
}
last = enumerator.Current;
queue.Enqueue(enumerator.Current);
}
if (queue.Count > 1)
{
yield return queue.ToArray();
}
}
}
[TestFixture]
public class DarkThreadTests
{
[Test]
public void find_repeat_group()
{
var source = new[] { "A", "B", "B", "C", "X", "C", "C", "B", "B", "D", "D", "D" };
var expected = new[]
{
new[] { "B", "B" },
new[] { "C", "C" },
new[] { "B", "B" },
new[] { "D", "D", "D" },
};
ResultShouldBe(source, expected);
}
[Test]
public void find_repeat_group_with_empty_source()
{
var source = new string[] { };
var expected = new IEnumerable<string>[] { };
ResultShouldBe(source, expected);
}
[Test]
public void find_repeat_group_with_only_1_element()
{
var source = new string[] { "A" };
var expected = new IEnumerable<string>[] { };
ResultShouldBe(source, expected);
}
private void ResultShouldBe(IEnumerable<string> source, IEnumerable<IEnumerable<string>> expected)
{
var actual = FindRepeat(source, EqualityComparer<string>.Default);
actual.Should().BeEquivalentTo(expected, options => options.WithStrictOrdering());
}
private IEnumerable<IEnumerable<T>> FindRepeat<T>(IEnumerable<T> source, IEqualityComparer<T> equalityComparer)
{
var enumerator = source.GetEnumerator();
if (!enumerator.MoveNext())
{
yield break;
}
var queue = new Queue<T>();
var last = enumerator.Current;
queue.Enqueue(last);
while (enumerator.MoveNext())
{
if (!equalityComparer.Equals(enumerator.Current, last))
{
if (queue.Count > 1)
{
yield return queue.ToArray();
}
queue.Clear();
}
last = enumerator.Current;
queue.Enqueue(enumerator.Current);
}
if (queue.Count > 1)
{
yield return queue.ToArray();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment