public void Split() { //To split a regular number, replace it with a pair; //the left element of the pair should be the regular number divided by two and rounded down, //while the right element of the pair should be the regular number divided by two and rounded up. //For example, 10 becomes [5,5], 11 becomes [5,6], 12 becomes [6,6], and so on. var half = Math.DivRem(Number, 2, out int remainder); Number = half; var right = new SnailfishRegularNumber(half + remainder); var currentParent = Parent; var currenPosition = NumberPosition; SnailfishNumberPair replacement = new SnailfishNumberPair(this, right); replacement.Parent = currentParent; replacement.NumberPosition = currenPosition; if (currenPosition == PairPosition.Left) { currentParent.LeftNumber = replacement; } else { currentParent.RightNumber = replacement; } }
public void Explode() { //To explode a pair, the pair's left value is added to the first regular number to the left of the exploding pair (if any), //and the pair's right value is added to the first regular number to the right of the exploding pair (if any). //Exploding pairs will always consist of two regular numbers. Then, the entire exploding pair is replaced with the regular number 0. //Change number to the left var current = this; while (current != null) { if (current.NumberPosition == PairPosition.Right) { current.Parent.LeftNumber.AddToRight(((SnailfishRegularNumber)LeftNumber).Number); break; } current = current.Parent; } //Change number to the right current = this; while (current != null) { if (current.NumberPosition == PairPosition.Left) { current.Parent.RightNumber.AddToLeft(((SnailfishRegularNumber)RightNumber).Number); break; } current = current.Parent; } //Replace this pair with a zero var currentParent = Parent; SnailfishRegularNumber replacement = new SnailfishRegularNumber(0) { Parent = currentParent }; if (NumberPosition == PairPosition.Left) { replacement.NumberPosition = PairPosition.Left; replacement.Parent.LeftNumber = replacement; } else { replacement.NumberPosition = PairPosition.Right; replacement.Parent.RightNumber = replacement; } }
internal static SnailfishNumberPair ParseNumber(string numberString) { SnailfishNumberPair currentPair = null; Stack <SnailfishNumberPair> pairs = new Stack <SnailfishNumberPair>(); foreach (var letter in numberString) { switch (letter) { case '[': //add pair if (currentPair != null) { pairs.Push(currentPair); } currentPair = new SnailfishNumberPair(); var parent = pairs.Count > 0 ? pairs.Peek() : null; if (parent != null) { currentPair.Parent = parent; if (parent?.LeftNumber == null) { parent.SetLeft(currentPair); } else { parent.SetRight(currentPair); } } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': var number = new SnailfishRegularNumber(Convert.ToInt32(letter.ToString())); if (currentPair?.LeftNumber == null) { currentPair.SetLeft(number); } else { currentPair.SetRight(number); } break; case ']': currentPair = pairs.Count > 0 ? pairs.Pop() : currentPair; break; case ',': //do nothing, logic is in set number default: break; } } return(currentPair); }