public static int Magnitude(ISnailfishNumber num) { if (num is SnailfishValue value) { return(value.Value); } if (num is SnailfishPair pair) { return(3 * Magnitude(pair.X) + 2 * Magnitude(pair.Y)); } throw new NotImplementedException(); }
public static bool Split(ISnailfishNumber num) { if (num is SnailfishValue) { return(false); } Stack <(ISnailfishNumber number, SnailfishPair?parent)> stack = new(); stack.Push((num, null)); while (stack.Count > 0) { (var curr, var parent) = stack.Pop(); if (curr is SnailfishValue value) { if (value.Value >= 10) { int x = value.Value / 2; int y = value.Value / 2 + value.Value % 2; var newValue = new SnailfishPair(x, y); if (parent?.X == curr) { parent.X = newValue; } else if (parent?.Y == curr) { parent.Y = newValue; } return(true); } } else if (curr is SnailfishPair pair) { stack.Push((pair.Y, pair)); stack.Push((pair.X, pair)); } } return(false); }
public static bool Explode(ISnailfishNumber num) { if (num is SnailfishValue) { return(false); } Stack <(int level, ISnailfishNumber number, SnailfishPair?parent)> stack = new(); stack.Push((1, num, null)); SnailfishValue?lastValue = null; int? toMoveRight = null; while (stack.Count > 0) { (int level, var curr, var parent) = stack.Pop(); if (curr is SnailfishPair pair) { if (toMoveRight == null && level > 4 && pair.X is SnailfishValue x && pair.Y is SnailfishValue y) { if (lastValue != null) { lastValue.Value += x.Value; } toMoveRight = y.Value; if (parent?.X == curr) { parent.X = new SnailfishValue(0); } else if (parent?.Y == curr) { parent.Y = new SnailfishValue(0); } } else { stack.Push((level + 1, pair.Y, pair)); stack.Push((level + 1, pair.X, pair)); } }
public static void Reduce(ISnailfishNumber num) { while (Explode(num) || Split(num)) { } }