Skip to content

Instantly share code, notes, and snippets.

@aannenko
Last active October 16, 2021 05:20
Show Gist options
  • Save aannenko/f4acf8659504ff98ba62c6be0807c2bf to your computer and use it in GitHub Desktop.
Save aannenko/f4acf8659504ff98ba62c6be0807c2bf to your computer and use it in GitHub Desktop.
Efficient Brute Force generator that can be consumed by foreach. Replace contents of Program.cs in your .NET 5 project with the following code and run.
using System;
foreach (var text in new BruteForceEnumerable(2, "abc"))
Console.WriteLine(text.ToString());
public class BruteForceEnumerable
{
private readonly int _maxTextLength;
private readonly string _characters;
public BruteForceEnumerable(int maxTextLength, string characters)
{
_maxTextLength = maxTextLength > 0
? maxTextLength
: throw new ArgumentOutOfRangeException(nameof(maxTextLength), maxTextLength,
"Value must be greater than 0.");
_characters = string.IsNullOrEmpty(characters)
? throw new ArgumentException("Value cannot be null or empty string.", nameof(characters))
: characters;
}
public Enumerator GetEnumerator() => new Enumerator(this);
public class Enumerator
{
private readonly BruteForceEnumerable _enumerable;
private readonly char[] _textBuffer;
private readonly int[] _indices;
private int _position;
internal Enumerator(BruteForceEnumerable enumerable)
{
_enumerable = enumerable;
_textBuffer = new char[_enumerable._maxTextLength];
_indices = new int[_enumerable._maxTextLength];
_position = 0;
}
public ReadOnlySpan<char> Current => _textBuffer.AsSpan(0, _position + 1);
public bool MoveNext() => MoveNext(_position);
private bool MoveNext(int position)
{
if (_indices[position] < _enumerable._characters.Length)
{
_textBuffer[position] = _enumerable._characters[_indices[position]];
_indices[position]++;
return true;
}
_textBuffer[position] = _enumerable._characters[0];
_indices[position] = 1;
return position > 0
? MoveNext(position - 1)
: ++_position < _enumerable._maxTextLength
? MoveNext(_position)
: false;
}
}
}
// Output:
// a
// b
// c
// aa
// ab
// ac
// ba
// bb
// bc
// ca
// cb
// cc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment