84 lines
2.6 KiB
C#
84 lines
2.6 KiB
C#
using System.Collections;
|
|
|
|
namespace Numbers.NumberString;
|
|
|
|
/// <summary>
|
|
/// Represents a string consisting of digits and letters intermixed
|
|
/// </summary>
|
|
/// <inheritdoc cref="IEnumerable{T}" />
|
|
/// <inheritdoc cref="IComparable{T}" />
|
|
public sealed class NumberString : IEnumerable<int>, IComparable<NumberString>
|
|
{
|
|
private readonly string _text;
|
|
private int? _numericValue;
|
|
|
|
/// <summary>
|
|
/// Creates a new instance of <see cref="NumberString" /> based on the given text.
|
|
/// As a simplification, the text is assumed to be a valid number string.
|
|
/// </summary>
|
|
/// <param name="text">A string containing digits and letters</param>
|
|
public NumberString(string text)
|
|
{
|
|
_text = text;
|
|
string digitsOnly = new string(text.Where(char.IsDigit).ToArray());
|
|
_numericValue = digitsOnly.Length > 0 ? int.Parse(digitsOnly) : 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the numeric value contained in the number string
|
|
/// </summary>
|
|
public int NumericValue => _numericValue ?? 0;
|
|
|
|
/// <summary>
|
|
/// Gets the digit at the given index.
|
|
/// If the index is out of range, -1 is returned.
|
|
/// </summary>
|
|
/// <param name="index">Digit index</param>
|
|
public int this[int index]
|
|
{
|
|
get
|
|
{
|
|
string numberString = _numericValue.HasValue ? _numericValue.Value.ToString() : string.Empty;
|
|
if (index < 0 || index >= numberString.Length || numberString == string.Empty)
|
|
{
|
|
return -1;
|
|
}
|
|
return GetDigit(numberString[index]);
|
|
static int GetDigit(char c) => c - '0';
|
|
}
|
|
}
|
|
|
|
public int CompareTo(NumberString? other)
|
|
{
|
|
if (ReferenceEquals(this, other))
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return NumericValue.CompareTo(other?.NumericValue);
|
|
}
|
|
|
|
public IEnumerator<int> GetEnumerator() => new DigitEnumerator(_text);
|
|
|
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
|
|
|
public override bool Equals(object? obj)
|
|
{
|
|
if (obj is not NumberString numberString)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return numberString._numericValue == _numericValue;
|
|
}
|
|
|
|
public override int GetHashCode() => _numericValue?.GetHashCode() ?? 0;
|
|
|
|
public static bool operator >(NumberString a, NumberString b) => a.CompareTo(b) > 0;
|
|
|
|
public static bool operator <(NumberString a, NumberString b) => a.CompareTo(b) < 0;
|
|
|
|
public static bool operator ==(NumberString a, NumberString b) => a?.Equals(b) ?? ReferenceEquals(b, null);
|
|
|
|
public static bool operator !=(NumberString a, NumberString b) => !(a == b);
|
|
}
|