I am implementing a compare method (IComparer) for the game Manille and I need to compare certain cards (enum values) with each other.
I want to order them in a certain way so that Number 10 is the biggest card and Ace the second biggest.
There is also a certain symbol that is always higher then other cards (for example Hearts)
The problem:
I don't know how to tell that Nummer.Tien is bigger then B, D, H
Also Ace has to be the second highest card, but the algorithm is putting him on the first place.
public class ManilleComparer : IComparer<Kaart>
{
private Kleur symbol; // the symbol that is higher
public ManilleComparer(Kleur symbol)
{
this.symbol = symbol;
}
public int Compare(Kaart x, Kaart y)
{
int compareTo = x.Kleur.CompareTo(y.Kleur); //check symbols against each other
if (compareTo == 0) // if value is 0 they have the same symbol
{
compareTo = x.Nummer.CompareTo(y.Nummer); // order them
return compareTo;
}
return x.Nummer.CompareTo(y.Nummer); // else compare values
}
}
public enum Nummer { Aas, Twee, Drie, Vier, Vijf, Zes, Zeven, Acht, Negen, Tien, Boer, Dame, Heer } // Ace, Two, Three, Four, Five, Six, Zeven, Eight, Nine, Ten, 11, 12, 13
public enum Kleur { Schoppen, Harten, Klaveren, Ruiten }
I have a Sort methot that sorts all the cards in the correct orde, which words fine:
public int CompareTo(object obj)
{
Kaart dezeKaart = this;
Kaart andereKaart = obj as Kaart;
int compareTo = dezeKaart.Kleur.CompareTo(andereKaart.Kleur);
if(compareTo == 0)
{
compareTo = dezeKaart.Nummer.CompareTo(andereKaart.Nummer);
return compareTo;
}
return compareTo;
}
The outcome of this sort method is:
// ♠A - ♠2 - ♠3 - ♠4 - ♠5 - ♠6 - ♠7 - ♠8 - ♠9 - ♠10 - ♠B - ♠D - ♠H
// ♥A - ♥2 - ♥3 - ♥4 - ♥5 - ♥6 - ♥7 - ♥8 - ♥9 - ♥10 - ♥B - ♥D - ♥H
// ♣A - ♣2 - ♣3 - ♣4 - ♣5 - ♣6 - ♣7 - ♣8 - ♣9 - ♣10 - ♣B - ♣D - ♣H
// ♦A - ♦2 - ♦3 - ♦4 - ♦5 - ♦6 - ♦7 - ♦8 - ♦9 - ♦10 - ♦B - ♦D - ♦H
I now want to implement Icompare
to have this as an outcome:
// ♦7 - ♦8 - ♦9 - ♦B - ♦D - ♦H - ♦A - ♦10
// ♣7 - ♣8 - ♣9 - ♣B - ♣D - ♣H - ♣A - ♣10
// ♠7 - ♠8 - ♠9 - ♠B - ♠D - ♠H - ♠A - ♠10
// ♥7 - ♥8 - ♥9 - ♥B - ♥D - ♥H - ♥A - ♥10
You can do the following:
public class ManilleComparer : IComparer<Kaart>
{
public ManilleComparer(){}
public ManilleComparer(List<Kleur> PrefKleurRank)
{
KleurRank = PrefKleurRank;
}
public ManilleComparer(Kleur LastColor)
{
KleurRank.Remove(LastColor);
KleurRank.Add(LastColor);
}
private List<Kleur> KleurRank = new List<Kleur>() { Kleur.Ruiten , Kleur.Klaveren, Kleur.Schoppen, Kleur.Harten };
private List<Nummer> NummerRank = new List<Nummer>() { Nummer.Twee, Nummer.Drie, Nummer.Vier, Nummer.Vier, Nummer.Zes, Nummer.Zeven, Nummer.Acht, Nummer.Negen, Nummer.Boer, Nummer.Dame, Nummer.Heer, Nummer.Aas, Nummer.Tien };
public int Compare(Kaart x, Kaart y)
{
int compareTo = KleurRank.IndexOf(x.Kleur).CompareTo(KleurRank.IndexOf(y.Kleur)); //check symbols against each other
if (compareTo == 0) // if value is 0 they have the same symbol
{
compareTo = NummerRank.IndexOf(x.Nummer).CompareTo(NummerRank.IndexOf(y.Nummer));
}
return compareTo;
}
}
you can also pass the order to the contructor to be more flexible
This is how to use it:
Kaart k1 = new Kaart() { Kleur = Kleur.Ruiten, Nummer = Nummer.Drie };
Kaart k2 = new Kaart() { Kleur = Kleur.Harten, Nummer = Nummer.Heer };
Kaart k3 = new Kaart() { Kleur = Kleur.Ruiten, Nummer = Nummer.Aas };
Kaart.ManilleComparer m = new Kaart.ManilleComparer();
List<Kaart> mylist = new List<Kaart>();
mylist.Add(k1);
mylist.Add(k2);
mylist.Add(k3);
mylist.Sort(m);
private List<Kleur> MyKleurRank = new List<Kleur>() { Kleur.Ruiten , Kleur.Klaveren, Kleur.Harten , Kleur.Schoppen};
Kaart.ManilleComparer m2 = new Kaart.ManilleComparer(MyKleurRank);
mylist.Sort(m2);
Related
I need to compare section numbers in a document, at first I was just going to convert to decimal and check to see if one number is greater than another.
The issue there is that some sections have multiple decimals.
Example: I need to perform a math comparison on 1.1 with 1.1.2.3 to determine which one is farther along in a document.
They are strings to begin with and I need to do some math comparisons on them essentially.
I though about removing the decimals then converting to int but this throws off certain sections, like section 2 would be considered less than section 1.1 since 1.1 would be changed to a 11, which is no good.
string section1 = "1.1";
string section2 = "2";
int convertedSection1 = Convert.ToInt32(section1.Replace(".",""));
int convertedSection2 = Convert.ToInt32(section2.Replace(".",""));
if(convertedSection1 < convertedSection2)
//This will incorrectly say 1.1 is greater than 2
string section1 = "1.1.2.4";
string section2 = "2.4";
decimal convertedSection1 = Convert.ToDecimal(section1);
decimal convertedSection2 = Convert.ToDecimal(section2);
if(convertedSection1 < convertedSection2)
//This will convert 1.1.2.4 to 1.1 which is no good
You can create a class similar to the Version class of the .NET framework. If you implement some operators and IComparable, it's really nice.
How does it work? It will convert the given string into a list of integer numbers. Upon comparison, it will start at the beginning of each list and compare each individual part.
public class Section: IComparable<Section>
{
// Stores all individual components of the section
private List<int> parts = new List<int>();
// Construct a section from a string
public Section(string section)
{
var strings = section.Split('.');
foreach (var s in strings)
{
parts.Add(int.Parse(s));
}
}
// Make it nice for display
public override string ToString()
{
return string.Join(".", parts);
}
// Implement comparison operators for convenience
public static bool operator ==(Section a, Section b)
{
// Comparing the identical object
if (ReferenceEquals(a, b)) return true;
// One object is null and the other isn't
if ((object)a == null) return false;
if ((object)b == null) return false;
// Different amount of items
if (a.parts.Count != b.parts.Count) return false;
// Check all individual items
for (int i=0; i<a.parts.Count;i++)
{
if (a.parts[i] != b.parts[i]) return false;
}
return true;
}
public static bool operator !=(Section a, Section b)
{
return !(a == b);
}
public static bool operator <(Section a, Section b)
{
// Use minimum, otherwise we exceed the index
for (int i=0; i< Math.Min(a.parts.Count, b.parts.Count); i++)
{
if (a.parts[i] < b.parts[i]) return true;
}
if (b.parts.Count > a.parts.Count) return true;
return false;
}
public static bool operator >(Section a, Section b)
{
// Use minimum, otherwise we exceed the index
for (int i = 0; i < Math.Min(a.parts.Count, b.parts.Count); i++)
{
if (a.parts[i] > b.parts[i]) return true;
}
if (a.parts.Count > b.parts.Count) return true;
return false;
}
// Implement the IComparable interface for sorting
public int CompareTo(Section other)
{
if (this == other) return 0;
if (this < other) return -1;
return 1;
}
}
Tests for 96% coverage:
Assert.IsTrue(new Section("1.2.3.4") > new Section("1.2.3"));
Assert.IsFalse(new Section("1.2.3.4") < new Section("1.2.3"));
Assert.IsFalse(new Section("1.2.3.4") == new Section("1.2.3"));
Assert.IsTrue(new Section("1.2.3.4") == new Section("1.2.3.4"));
Assert.IsFalse(new Section("1.2.3.4") == new Section("1.2.3.5"));
Assert.IsTrue(new Section("1.2.3.4") != new Section("1.2.3.5"));
var sec = new Section("1");
Assert.IsTrue(sec == sec);
Assert.AreEqual("1.2.3.4", new Section("1.2.3.4").ToString());
var sortTest = new List<Section> { new Section("2"), new Section("1.2"), new Section("1"), new Section("3.1") };
sortTest.Sort();
var expected = new List<Section> { new Section("1"), new Section("1.2"), new Section("2"), new Section("3.1") };
CollectionAssert.AreEqual(expected, sortTest, new SectionComparer());
If you know that your section strings are always well formed, and you know that they don't go deeper than 6 levels, and that no level has more than 999 items, then this works nicely:
string zero = ".0.0.0.0.0.0";
long Section2Long(string section) =>
(section + zero)
.Split('.')
.Take(6)
.Select(t => long.Parse(t))
.Aggregate((x, y) => x * 1000 + y);
Now, if I have this:
string[] sections = new []
{
"1.2.4", "2.3", "1", "1.2", "1.1.1.1", "1.0.0.1.0.1", "2.2.9"
};
I can easily sort it like this:
string[] sorted = sections.OrderBy(x => Section2Long(x)).ToArray();
I get this output:
1
1.0.0.1.0.1
1.1.1.1
1.2
1.2.4
2.2.9
2.3
I am trying to sort a list using IComparer there are about 20,000 items in my list. The first approximately 100 and last 100 items are sorted but the center is not. I am not sure what I am doing wrong. Attached is the parts of the code that does the sort.
class myclass:me
{
private void mysort()
{
// Sort the data
DistComparer dc = new DistComparer();
st.Sort(dc);
}
}
class DistComparer : IComparer<Tower>
{
public int Compare(st x, st y)
{
double dist1 = getDistance(new PointF(45.0f, -80f), new PointF(x.Lat, x.Long));
double dist2 = getDistance(new PointF(45.0f, -80f), new PointF(y.Lat, y.Long));
if (dist1 > dist2)
return 1;
else if (dist1 == dist2)
return 0;
else
return -1;
}
private static double getDistance(PointF pt1, PointF pt2)
{
return Math.Sqrt(Math.Pow((pt1.X - pt2.X), 2) + Math.Pow((pt1.Y - pt2.Y), 2));
}
}
}
I have a number of objects each with 3 numerical properties: "high", "low" and "tiebreaker". They are to be sorted as such: if an object's low is higher than another object's high, it appears before it in the list. Likewise if an object's high is lower than another's low, it appears later in the list. But in the case that two objects have conflicting ranges (eg one's high is between the other object's low and high), the tiebreaker property is considered wherein the object with the higher tiebreaker value gets placed earlier on the list.
I am specifically working with c#, but I think the ideas here are language agnostic enough such that code of any sort (no puns) would be welcome.
Also, I have worked on this myself. I have a nested for-loop that is just not working out for me so far. I'd give up some code but I'm on my phone and that makes it a chore. Besides, this is probably a fun one for you and you don't need my ugly code in your way anyhow.
Are you assuming that Min <= Tie <= Max? You do not say so in your question, and if you do not, the sort order is not well defined because it is not transitive. For instance, writing your ranges as [Min, Tie, Max], consider:
A: [5,-10, 6]
B: [0, 1, 10]
C: [2, 3, 4]
A < B (because they overlap and -10 < 1)
B < C (because they overlap and 1 < 3)
but A > C (because they don't overlap and 5 > 4)
If they are you can define a custom IComparer<Range> for your Range class, and pass it to any c# sort method.
Update and here's one such implementation.
public struct RangeWithTie<T> where T : IEquatable<T>, IComparable<T>
{
readonly T min;
readonly T max;
readonly T tie;
readonly bool isNonEmpty;
public static Range<T> Empty = new Range<T>();
public static IComparer<RangeWithTie<T>> CreateSortingComparer()
{
return new RangeWithTieComparer();
}
public RangeWithTie(T start, T tie, T end)
{
// Enfore start <= tie <= end
var comparer = Comparer<T>.Default;
if (comparer.Compare(start, end) > 0) // if start > end
{
throw new ArgumentOutOfRangeException("start and end are reversed");
}
else if (comparer.Compare(start, tie) > 0)
{
throw new ArgumentOutOfRangeException("tie is less than start");
}
else if (comparer.Compare(tie, end) > 0)
{
throw new ArgumentOutOfRangeException("tie is bigger than end");
}
else
{
this.min = start;
this.max = end;
this.tie = tie;
}
this.isNonEmpty = true;
}
public T Min { get { return min; } }
public T Max { get { return max; } }
public T Tie { get { return tie; } }
public bool IsEmpty { get { return !isNonEmpty; } }
public class RangeWithTieComparer : IComparer<RangeWithTie<T>>
{
#region IComparer<RangeWithTie<T>> Members
public int Compare(RangeWithTie<T> x, RangeWithTie<T> y)
{
// return x - y.
if (x.IsEmpty)
{
if (y.IsEmpty)
return 0;
else
return -1;
}
else if (y.IsEmpty)
{
return 1;
}
var comparer = Comparer<T>.Default;
if (comparer.Compare(y.Min, x.Max) > 0)
return -1;
else if (comparer.Compare(x.Min, y.Max) > 0)
return 1;
return comparer.Compare(x.Tie, y.Tie);
}
#endregion
}
public override string ToString()
{
if (IsEmpty)
return "Empty";
StringBuilder s = new StringBuilder();
s.Append('[');
if (Min != null)
{
s.Append(Min.ToString());
}
s.Append(", ");
if (Tie != null)
{
s.Append(Tie.ToString());
}
s.Append(", ");
if (Max != null)
{
s.Append(Max.ToString());
}
s.Append(']');
return s.ToString();
}
}
This could be used like so:
var sortedRanges = ranges.OrderBy(x => x, RangeWithTie<double>.CreateSortingComparer()).ToArray();
I didn't make the struct implement IComparer<RangeWithTie<T>> directly because ranges with identical comparisons aren't necessarily equal. For instance, [-1,0,1] and [-2,0,1] have identical comparisons but are not equal.
A quick solution, and a console application to test it. This method will return the larger of two objects. Just replace dynamic with the appropriate object type you need.
class Program
{
private static object Sort(dynamic first, dynamic second)
{
if (OverlapExists(first, second))
{
// Note: If tiebreakers are equal, the first will be returned:
return first.tiebreaker >= second.tiebreaker ? first : second;
}
else
{
// Note: Only need to test one value (just high); Since we know
// there is no overlap, the whole object (both high and low) must
// be either over or under that which it is compared to:
return first.high > second.high ? first : second;
}
}
private static bool OverlapExists(dynamic first, dynamic second)
{
return (first.low < second.high) && (second.low < first.high);
}
static void Main(string[] args)
{
dynamic first = new {name="first", high = 10,
tiebreaker = 5, low = 1 };
dynamic second = new {name="second", high = 15,
tiebreaker = 12, low = 11 };
dynamic third = new {name="third", high = 20,
tiebreaker = 9, low = 6 };
var firstResult = Sort(first, second);
var secondResult = Sort(first, third);
var thirdResult = Sort(second, third);
Console.WriteLine("1) " + first.ToString()
+ "\nVS: " + second.ToString());
Console.WriteLine("Winner: " + firstResult.name);
Console.WriteLine("\n2) " + first.ToString()
+ "\nVS: " + third.ToString());
Console.WriteLine("Winner: " + secondResult.name);
Console.WriteLine("\n3) " + second.ToString()
+ "\nVS: " + third.ToString());
Console.WriteLine("Winner: " + thirdResult.name);
Console.ReadKey();
}
}
Let’s say you have a List<T> (T being your objects with High-, Low- and Tie- Property), then you can use
list.Sort(…);
with a Comparison<T> as a Parameter. That’s a delegate that takes 2 of you objects and should return < 0, when the first instance of your object should be a head of the other instance or 0 if they are of equal order (or > 0 if the second second object should be ahead of first).
Or you could pass an custom comparer (implementing IComparer<T>) which does basically the same as the Comparison<T> but inform of an interface.
No matter what your logic is, you may implement IComparable to enable an Array or List's sorting capability. So, as the follow code shows,
public class MyStuff : IComparable<MyStuff>
{
public int High { get; set; }
public int Low { get; set; }
public int TieBreaker { get; set; }
public int CompareTo(MyStuff other)
{
// if an object's low is higher than another object's high,
// it appears before it in the list
if ((this.Low > other.High) ||
// if its high is between the other object's low and
// high then compare their tiebreaker
(this.High > other.Low && this.High < other.High &&
this.TieBreaker > other.TieBreaker))
return 1;
else if (this.Low == other.High)
return 0;
else
return -1;
}
}
The basic idea is CompareTo returns either 1 (move this before other), 0 (retain both positions) or -1 (move this after other), depending on your ordering logic.
See IComparable<T>
class DataObject : IComparable<DataObject>
{
public double High, Low, Tiebreaker;
public int CompareTo(DataObject obj)
{
// this doesn't seem to make sense as a range sort, but seems to match your question...
// low > another high
if (this.Low != obj.High)
return this.Low.CompareTo(obj.High);
// otherwise sort tiebreaker ascending
else this.TieBreaker.CompareTo(obj.TieBreaker);
}
}
used as
var items = new[] { new DataObject(1,2,3), new DataObject(4,5,6) };
Array.Sort<DataObject>(items);
// items is now sorted
This question already has answers here:
Is there a C# type for representing an integer Range?
(10 answers)
Closed 8 years ago.
I have a interval of number [1, 20].
I want a method which returns me range of number available if I decide to ban range [15, 18]. My method should return me a list containing [1,15] and [18, 20]
Range object could looks like something like that
public class Range
{
int Start {get;set;}
int End {get;set;}
}
Any help would be appreciated.
What about this?
IEnumerable<int> range = Enumerable.Range(1, 20);
IEnumerable<int> banned = Enumerable.Range(15, 4);
return range.Except(banned);
The Enumerable class already has a static method which will return a range of values for you - might be simpler to just use those semantics.
This is one of the ways:
static void Main(string[] args)
{
int[] allNumbers = Enumerable.Range(1, 20).ToArray();
GetNumbers(ref allNumbers, new int[] { 16, 17 });
}
private static void GetNumbers(ref int[] nums, int[]exclude)
{
List<int> numsToExlucde =new List<int>();
numsToExlucde.InsertRange(0, exclude);
nums = nums.Where(w => !numsToExlucde.Contains(w)).ToArray();
}
You have four possible cases. The method could look like this (I assume that range contain integer numbers only):
public class Range
{
public int Start { get; set; }
public int End { get; set; }
public IList<Range> Exclude(Range r)
{
if (r.Start <= Start && r.End < End)
{
return new List<Range>{new Range { Start = r.End + 1, End = End }};
}
else if (r.Start > Start && r.End >= End)
{
return new List<Range>{new Range { Start = Start, End = r.Start - 1 }};
}
else if (r.Start > Start && r.End < End)
{
return new List<Range>
{
new Range { Start = Start, End = r.Start - 1 },
new Range { Start = r.End + 1, End = End }
};
}
return new List<Range>();
}
}
// ...
static void Main(string[] args)
{
Range r = new Range { Start = 1, End = 20};
var list = r.Exclude(new Range{ Start = 1, End = 2} );
}
This can help you remove a range from another, or from a set of ranges:
public class Range {
public int Start { get; private set; }
public int End { get; private set; }
public Range(int start, int end) {
Start = start;
End = end;
}
public IEnumerable<Range> RemoveFrom(Range range) {
return RemoveFrom(new Range[] { range });
}
public IEnumerable<Range> RemoveFrom(IEnumerable<Range> items) {
foreach (Range item in items) {
if (End >= item.Start && Start <= item.End) {
if (item.Start <= Start) {
yield return new Range(item.Start, Start);
}
if (item.End >= End) {
yield return new Range(End, item.End);
}
} else {
yield return item;
}
}
}
}
Example:
Range range = new Range(1, 20);
foreach (Range r in new Range(15,18).RemoveFrom(range)) {
Console.WriteLine("{0} - {1}", r.Start, r.End);
}
Output:
1 - 15
18 - 20
Example of removing multiple ranges from other ranges:
Range[] items = new Range[] { new Range(1, 100), new Range(200, 300) };
Range[] exclude = new Range[] { new Range(25, 75), new Range(250, 280), new Range(90, 210) };
foreach (Range r in exclude) {
items = r.RemoveFrom(items).ToArray();
}
foreach (Range r in items) {
Console.WriteLine("{0} - {1}", r.Start, r.End);
}
Output:
1 - 25
75 - 90
210 - 250
280 - 300
You need to traverse through the banned ranges and iteratively create the valid ranges while doing so.
public List<Range> getValidRanges(Range total, List<Range> banned)
{
List<Range> valid = new ArrayList<Range>();
int start = total.getStartTime();
for(Range range: banned)
{
valid.add(new Range(start,banned.getStart()));
start = banned.getEnd();
}
valid.add(new Range(start,total.getEnd()));
return valid;
}
I'm very much a vb person, but have had to use this id number class in c#. I got it from http://www.codingsanity.com/idnumber.htm :
namespace Utilities
{
[Serializable]
public class IdentityNumber
{
public enum PersonGender
{
Female = 0,
Male = 5
}
public enum PersonCitizenship
{
SouthAfrican = 0,
Foreign = 1
}
static Regex _expression;
Match _match;
const string _IDExpression = #"(?<Year>[0-9][0-9])(?<Month>([0][1-9])|([1][0-2]))(?<Day>([0-2][0-9])|([3][0-1]))(?<Gender>[0-9])(?<Series>[0-9]{3})(?<Citizenship>[0-9])(?<Uniform>[0-9])(?<Control>[0-9])";
static IdentityNumber()
{
_expression = new Regex(_IDExpression, RegexOptions.Compiled | RegexOptions.Singleline);
}
public IdentityNumber(string IDNumber)
{
_match = _expression.Match(IDNumber.Trim());
}
public DateTime DateOfBirth
{
get
{
if(IsUsable == false)
{
throw new ArgumentException("ID Number is unusable!", "IDNumber");
}
int year = int.Parse(_match.Groups["Year"].Value);
// NOTE: Do not optimize by moving these to static, otherwise the calculation may be incorrect
// over year changes, especially century changes.
int currentCentury = int.Parse(DateTime.Now.Year.ToString().Substring(0, 2) + "00");
int lastCentury = currentCentury - 100;
int currentYear = int.Parse(DateTime.Now.Year.ToString().Substring(2, 2));
// If the year is after or at the current YY, then add last century to it, otherwise add
// this century.
// TODO: YY -> YYYY logic needs thinking about
if(year > currentYear)
{
year += lastCentury;
}
else
{
year += currentCentury;
}
return new DateTime(year, int.Parse(_match.Groups["Month"].Value), int.Parse(_match.Groups["Day"].Value));
}
}
public PersonGender Gender
{
get
{
if(IsUsable == false)
{
throw new ArgumentException("ID Number is unusable!", "IDNumber");
}
int gender = int.Parse(_match.Groups["Gender"].Value);
if(gender < (int) PersonGender.Male)
{
return PersonGender.Female;
}
else
{
return PersonGender.Male;
}
}
}
public PersonCitizenship Citizenship
{
get
{
if(IsUsable == false)
{
throw new ArgumentException("ID Number is unusable!", "IDNumber");
}
return (PersonCitizenship) Enum.Parse(typeof(PersonCitizenship), _match.Groups["Citizenship"].Value);
}
}
/// <summary>
/// Indicates if the IDNumber is usable or not.
/// </summary>
public bool IsUsable
{
get
{
return _match.Success;
}
}
/// <summary>
/// Indicates if the IDNumber is valid or not.
/// </summary>
public bool IsValid
{
get
{
if(IsUsable == true)
{
// Calculate total A by adding the figures in the odd positions i.e. the first, third, fifth,
// seventh, ninth and eleventh digits.
int a = int.Parse(_match.Value.Substring(0, 1)) + int.Parse(_match.Value.Substring(2, 1)) + int.Parse(_match.Value.Substring(4, 1)) + int.Parse(_match.Value.Substring(6, 1)) + int.Parse(_match.Value.Substring(8, 1)) + int.Parse(_match.Value.Substring(10, 1));
// Calculate total B by taking the even figures of the number as a whole number, and then
// multiplying that number by 2, and then add the individual figures together.
int b = int.Parse(_match.Value.Substring(1, 1) + _match.Value.Substring(3, 1) + _match.Value.Substring(5, 1) + _match.Value.Substring(7, 1) + _match.Value.Substring(9, 1) + _match.Value.Substring(11, 1));
b *= 2;
string bString = b.ToString();
b = 0;
for(int index = 0; index < bString.Length; index++)
{
b += int.Parse(bString.Substring(index, 1));
}
// Calculate total C by adding total A to total B.
int c = a + b;
// The control-figure can now be determined by subtracting the ones in figure C from 10.
string cString = c.ToString() ;
cString = cString.Substring(cString.Length - 1, 1) ;
int control = 0;
// Where the total C is a multiple of 10, the control figure will be 0.
if(cString != "0")
{
control = 10 - int.Parse(cString.Substring(cString.Length - 1, 1));
}
if(_match.Groups["Control"].Value == control.ToString())
{
return true;
}
}
return false;
}
}
}
}
Can someone please tell the syntax for how I pass an id number to the class?
You'll have to use the constructor.
var someNumber = new IdentityNumber("123456");
Then, you can use the properties of that class to find out the specifics of that Id number.
Console.WriteLine (someNumber.DateOfBirth);
Console.WriteLine (someNumber.Gender);
Console.WriteLine (someNumber.Citizenship);
Console.WriteLine (someNumber.IsValid);
Console.WriteLine (someNumber.IsUsable);
IdentityNumber number = new IdentityNumber("123456");
All you need is to use provided Constructor like
IdentityNumber someNumber = new IdentityNumber("006834");