Exemple #1
0
            private c_snailfish_number parse_pair_element(
                string input,
                int start_index,
                out int end_index)
            {
                c_snailfish_number result;

                if (input[start_index] == '[')
                {
                    int left_bracket_depth = 1;
                    for (end_index = start_index; left_bracket_depth > 0; end_index++)
                    {
                        switch (input[end_index + 1])
                        {
                        case '[': left_bracket_depth++; break;

                        case ']': left_bracket_depth--; break;
                        }
                    }

                    result = new c_snailfish_number(this, input.Substring(start_index, end_index - start_index + 1));
                }
                else
                {
                    end_index = start_index;
                    while (input[end_index + 1] != ',' && input[end_index + 1] != ']')
                    {
                        end_index++;
                    }

                    result = new c_snailfish_number(this, input.Substring(start_index, end_index - start_index + 1));
                }

                return(result);
            }
Exemple #2
0
            private c_snailfish_number(
                c_snailfish_number p,
                string input)
            {
                parent = p;

                if (input[0] == '[')
                {
                    type = e_snailfish_number_type.pair;

                    int left_start_index = 1;
                    int left_end_index;

                    left = parse_pair_element(input, left_start_index, out left_end_index);

                    int right_start_index = left_end_index + 2;
                    int right_end_index;

                    right = parse_pair_element(input, right_start_index, out right_end_index);
                }
                else
                {
                    type = e_snailfish_number_type.raw_number;

                    value = UInt64.Parse(input);
                }
            }
Exemple #3
0
            private c_snailfish_number(
                UInt64 v,
                c_snailfish_number p)
            {
                type   = e_snailfish_number_type.raw_number;
                parent = p;

                value = v;
            }
Exemple #4
0
            public c_snailfish_number plus(
                bool pretty,
                c_snailfish_number other)
            {
                if (pretty)
                {
                    Console.WriteLine();
                    Console.WriteLine("adding these:");
                    display(pretty);
                    Console.WriteLine();
                    other.display(pretty);
                    Console.WriteLine();
                }

                validate(this);
                validate(other);

                c_snailfish_number result = new c_snailfish_number(this, other, null);

                validate(result);

                if (pretty)
                {
                    Console.WriteLine("equals:");
                    result.display(pretty);
                    Console.WriteLine();
                }

                bool reduced;

                do
                {
                    reduced = result.try_explode(pretty);

                    if (!reduced)
                    {
                        reduced = result.try_split(pretty);
                    }

                    if (pretty && reduced)
                    {
                        Console.WriteLine("reduced to:");
                        result.display(pretty);
                        Console.WriteLine();
                    }

                    validate(result);
                } while (reduced);

                return(result);
            }
Exemple #5
0
            static void validate(c_snailfish_number number, c_snailfish_number parent = null)
            {
                Debug.Assert(number.parent == parent);

                if (number.left != null)
                {
                    validate(number.left, number);
                }

                if (number.right != null)
                {
                    validate(number.right, number);
                }
            }
Exemple #6
0
            private c_snailfish_number(
                c_snailfish_number l,
                c_snailfish_number r,
                c_snailfish_number p)
            {
                type   = e_snailfish_number_type.pair;
                parent = p;

                left        = l.clone();
                left.parent = this;

                right        = r.clone();
                right.parent = this;
            }
Exemple #7
0
            private bool try_explode(
                bool pretty,
                int num_parents)
            {
                bool result = false;

                if (type == e_snailfish_number_type.pair)
                {
                    result = left.try_explode(pretty, num_parents + 1);

                    if (!result &&
                        num_parents >= 4)
                    {
                        if (pretty)
                        {
                            Console.WriteLine("exploding:");
                            display(pretty);
                            Console.WriteLine();
                        }

                        explode_left_value(pretty);
                        explode_right_value(pretty);

                        type  = e_snailfish_number_type.raw_number;
                        left  = null;
                        right = null;
                        value = 0;

                        if (pretty)
                        {
                            Console.WriteLine("into:");
                            display(pretty);
                            Console.WriteLine();
                        }

                        result = true;
                    }

                    if (!result)
                    {
                        result = right.try_explode(pretty, num_parents + 1);
                    }
                }

                return(result);
            }
Exemple #8
0
            private void explode_right_value(
                bool pretty)
            {
                Debug.Assert(type == e_snailfish_number_type.pair);
                Debug.Assert(right.type == e_snailfish_number_type.raw_number);

                UInt64 exploding_value = right.value;

                c_snailfish_number current = this;
                bool searching_up          = true;

                while (searching_up)
                {
                    searching_up = (current.parent != null && current.parent.right == current);
                    current      = current.parent;
                }

                if (current != null)
                {
                    current = current.right;

                    while (current.type == e_snailfish_number_type.pair)
                    {
                        current = current.left;
                    }

                    UInt64 exploding_result = exploding_value + current.value;

                    if (pretty)
                    {
                        Console.WriteLine("    {0} + {1} = {2}", exploding_value, current.value, exploding_result);
                    }

                    current.value = exploding_result;
                }
                else
                {
                    if (pretty)
                    {
                        Console.WriteLine("    Discarding {0}", exploding_value);
                    }
                }
            }
Exemple #9
0
            public bool try_split(
                bool pretty)
            {
                bool result = false;

                if (type == e_snailfish_number_type.pair)
                {
                    result = left.try_split(pretty);

                    if (!result)
                    {
                        result = right.try_split(pretty);
                    }
                }
                else if (type == e_snailfish_number_type.raw_number &&
                         value >= 10)
                {
                    if (pretty)
                    {
                        Console.WriteLine("splitting:");
                        display(pretty);
                        Console.WriteLine();
                    }

                    type  = e_snailfish_number_type.pair;
                    left  = new c_snailfish_number(value / 2, this);
                    right = new c_snailfish_number(value / 2 + value % 2, this);
                    value = 0;

                    if (pretty)
                    {
                        Console.WriteLine("into:");
                        display(pretty);
                        Console.WriteLine();
                    }

                    result = true;
                }

                return(result);
            }
Exemple #10
0
        public static void Part_1(
            string input,
            bool pretty)
        {
            c_snailfish_number[] numbers = parse_input(input, pretty);

            c_snailfish_number sum = numbers[0];

            for (int i = 1; i < numbers.Length; i++)
            {
                sum = sum.plus(pretty, numbers[i]);
            }

            Console.WriteLine();
            Console.WriteLine("final sum:");
            sum.display(true);
            Console.WriteLine();

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine();
            Console.WriteLine("Magnitude = {0}", sum.magnitude());
            Console.ResetColor();
        }
Exemple #11
0
        public static void Part_2(
            string input,
            bool pretty)
        {
            c_snailfish_number[] numbers = parse_input(input, pretty);

            UInt64 max_magnitude = UInt64.MinValue;

            for (int i = 0; i < numbers.Length; i++)
            {
                for (int j = 0; j < numbers.Length; j++)
                {
                    if (i != j)
                    {
                        c_snailfish_number sum = numbers[i].plus(pretty, numbers[j]);

                        UInt64 magnitude = sum.magnitude();

                        if (pretty)
                        {
                            Console.ForegroundColor = ConsoleColor.Blue;
                            Console.WriteLine();
                            Console.WriteLine("Magnitude = {0}", magnitude);
                            Console.ResetColor();
                        }

                        max_magnitude = Math.Max(max_magnitude, magnitude);
                    }
                }
            }

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine();
            Console.WriteLine("Max Magnitude = {0}", max_magnitude);
            Console.ResetColor();
        }