Esempio n. 1
0
        public SnailNumber Split()
        {
            if (A > 9)
            {
                Left = MakeSplit(A, this);
                A    = 0;
                return(Left);
            }
            SnailNumber sn;

            if (Left != null)
            {
                sn = Left.Split();
                if (sn != null)
                {
                    return(sn);
                }
            }
            if (B > 9)
            {
                Right = MakeSplit(B, this);
                B     = 0;
                return(Right);
            }
            if (Right != null)
            {
                sn = Right.Split();
                if (sn != null)
                {
                    return(sn);
                }
            }
            return(null);
        }
Esempio n. 2
0
        public static SnailNumber Builder(string line)
        {
            using StringReader sreader = new StringReader(line);
            SnailNumber root = Parser(sreader, false);

            return(root);
        }
Esempio n. 3
0
        public SnailNumber FindExplode(int level)
        {
            if (level == 4)
            {
                return(this);
            }
            ++level;
            SnailNumber explode = null;

            if (Left != null)
            {
                explode = Left.FindExplode(level);
                if (explode != null)
                {
                    return(explode);
                }
            }
            if (Right != null)
            {
                explode = Right.FindExplode(level);
                if (explode != null)
                {
                    return(explode);
                }
            }
            return(null);
        }
Esempio n. 4
0
        public SnailNumber ExplodeRight(int val, SnailNumber explode)
        {
            if (Parent == null)
            {
                return(null);
            }
            SnailNumber sn;

            if (this == Parent.Right)
            {
                sn = Parent.ExplodeRight(val, explode);
                if (sn == null)
                {
                    if (this.Right == explode)
                    {
                        // not found set B to 0.
                        B = 0;
                        return(this);
                    }
                }
                return(sn);
            }
            else
            {
                sn = Parent.AddLeft(val, this);
                return(sn);
            }
        }
Esempio n. 5
0
        public SnailNumber MakeSplit(int val, SnailNumber parent)
        {
            SnailNumber splitSn = new SnailNumber();

            splitSn.Parent = parent;
            splitSn.A      = val / 2;
            splitSn.B      = (val / 2) + val % 2;
            return(splitSn);
        }
Esempio n. 6
0
        public SnailNumber Add(SnailNumber b)
        {
            SnailNumber sn = new SnailNumber();

            sn.Left         = this;
            this.Parent     = sn;
            sn.Right        = b;
            sn.Right.Parent = sn;
            return(sn);
        }
Esempio n. 7
0
        public SnailNumber Explode()
        {
            SnailNumber explode = FindExplode(0);

            if (explode != null)
            {
                explode.ExplodeLeft(explode.A, explode);
                explode.ExplodeRight(explode.B, explode);
                explode.RemoveMe();
            }
            return(explode);
        }
Esempio n. 8
0
        public void Reduce()
        {
            SnailNumber explode = null;
            SnailNumber split   = null;

            do
            {
                explode = Explode();
                if (explode == null)
                {
                    split = Split();
                }
            } while (explode != null || split != null);
        }
Esempio n. 9
0
 public SnailNumber AddLeft(int val, SnailNumber snr)
 {
     if (Left != null)
     {
         if (Left == snr)
         {
             if (Right == null)
             {
                 B += val;
                 return(this);
             }
             return(Right.AddLeft(val, snr));
         }
         return(Left.AddLeft(val, snr));
     }
     // Left is null found most Left most to the right of the exploder
     A += val;
     return(this);
 }
Esempio n. 10
0
 public SnailNumber AddRight(int val, SnailNumber snr)
 {
     if (Right != null)
     {
         if (Right == snr)
         {
             if (Left == null)
             {
                 A += val;
                 return(this);
             }
             return(Left.AddRight(val, snr));
         }
         return(Right.AddRight(val, snr));
     }
     // right is null found most right to the left of the exploder
     B += val;
     return(this);
 }
Esempio n. 11
0
        public static SnailNumber Parser(StringReader srdr, bool readLeftBrace)
        {
            SnailNumber sn   = new SnailNumber();
            bool        left = true;

            while (srdr.Peek() != -1)
            {
                var ch = (char)srdr.Read();
                switch (ch)
                {
                case '[':
                    if (readLeftBrace)
                    {
                        // start of a new snailnumber
                        if (left)
                        {
                            sn.Left        = Parser(srdr, true);
                            sn.Left.Parent = sn;
                            left           = false;
                        }
                        else
                        {
                            sn.Right        = Parser(srdr, true);
                            sn.Right.Parent = sn;
                        }
                    }
                    else
                    {
                        readLeftBrace = true;
                    }
                    break;

                case ']':
                    return(sn);

                case ',':
                    left = false;
                    break;

                case ' ':
                    break;

                default:
                    // digits?
                    if (char.IsDigit(ch))
                    {
                        int val = (int)ch - '0';
                        if ((srdr.Peek() != -1) && (char.IsDigit((char)srdr.Peek())))
                        {
                            // debugging tests
                            val = (val * 10) + (int)((char)srdr.Read() - '0');
                        }
                        if (left)
                        {
                            sn.A = val;
                            left = false;
                        }
                        else
                        {
                            sn.B = val;
                        }
                    }
                    else
                    {
                        throw new ArgumentException($"Char: {ch} is not expected");
                    }
                    break;
                }
            }
            return(sn);
        }