All pastes #2045425 Raw Edit

editor

public text v1 · immutable
#2045425 ·published 2011-04-12 12:00 UTC
rendered paste body
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XenoGears.Assertions;
using XenoGears.Functional;
using XenoGears.Logging.Formatters;

namespace Editor
{
    public static class Program
    {
        #region Utils
        
        private static void Dump(this Object o)
        {
            if (Equals(o, String.Empty)) Console.WriteLine();
            else Console.WriteLine(o.ToLog());
        }

        static Program()
        {
            for (var i = 0; i < top; ++i)
            {
                fs[i] = int.MinValue;
                fpn[i] = int.MinValue;
                fpm[i] = int.MinValue;
                fpd[i] = "?";

                for (var j = 0; j < top; ++j)
                {
                    gs[i, j] = int.MinValue;
                    gpn[i, j] = int.MinValue;
                    gpm[i, j] = int.MinValue;
                    gpd[i, j] = "?";
                }
            }
        }

        static void print(int[] a)
        {
            var ss = new string[a.Width()];
            for (var i = 0; i < a.Width(); ++i)
            {
                ss[i] =
                    a[i] == int.MaxValue ? "*" :
                    a[i] == int.MinValue ? "?" :
                    a[i].ToString();
            }

            print(ss);
        }

        static void print(int[,] a)
        {
            var ss = new string[a.Height(), a.Width()];
            for (var i = 0; i < a.Height(); ++i)
            {
                for (var j = 0; j < a.Width(); ++j)
                {
                    ss[i, j] =
                        a[i, j] == int.MaxValue ? "*" :
                        a[i, j] == int.MinValue ? "?" :
                        a[i, j].ToString();
                }
            }

            print(ss);
        }

        static void print(string[] a)
        {
            Console.WriteLine(a.StringJoin());
        }

        static void print(string[,] a)
        {
            var cols = new int[a.Width()];
            for (var j = 0; j < a.Width(); j++)
            {
                cols[j] = j.ToString().Length;
            }

            for (var i = 0; i < a.Height(); i++)
            {
                for (var j = 0; j < a.Width(); j++)
                {
                    var len = a[i, j].Length;
                    if (cols[j] < len) cols[j] = len;
                }
            }

//            var max_col = cols.Max();
            var all_col = cols.Sum();
            var max_row = a.Height().ToString().Length;

            var buf = new StringBuilder();
//            buf.Append("".PadRight(max_row) + "   ");
//            0.UpTo(a.Width() - 1).ForEach(j =>
//            {
//                buf.Append(j.ToString().PadRight(cols[j]));
//                buf.Append(j.ToString().PadRight(max_col));
//                if (j < a.Width() - 1) buf.Append(" ");
//            });
//            buf.Append(Environment.NewLine);

//            buf.Append("".PadRight(max_row) + "   ");
//            buf.Append(new String('-', all_col + a.Width() - 1));
//            buf.Append(new String('-', a.Width() * (max_col + 1) - 1));
//            buf.Append(Environment.NewLine);

            for (var i = 0; i < a.Height(); i++)
            {
//                buf.Append(i.ToString().PadRight(max_row) + " | ");

                for (var j = 0; j < a.Width(); j++)
                {
                    buf.Append(a[i, j].PadRight(cols[j]));
//                    buf.Append(a[i, j].PadRight(max_col));
                    if (j < a.Width() - 1) buf.Append(" ");
                }
                if (i < a.Height() - 1) buf.Append(Environment.NewLine);
            }

            Console.WriteLine(buf.ToString());
        }

        static void printctx()
        {
            print(fs);
            print(fpn);
            print(fpm);
            "".Dump();
            print(gs);
            "".Dump();
            print(gpn);
            "".Dump();
            print(gpm);
            "".Dump();
            print(gpd);
        }
        
        #endregion

        private static int[] fs = new int[top];
        private static int[] fpn = new int[top];
        private static int[] fpm = new int[top];
        private static String[] fpd = new String[top];

        private static int f(int n)
        {
            if (n < 0 || n >= top) return int.MaxValue;

            if (fs[n] == int.MinValue)
            {
                if (n == 0)
                {
                    fs[n] = 0;
                    fpn[n] = int.MaxValue;
                    fpm[n] = int.MaxValue;
                }
                else
                {
                    int a_value = int.MaxValue, a_index = int.MaxValue;
                    for (var k = 0; k <= n; ++k)
                    {
                        var g_value = g(n - 1, k);
                        if (g_value < a_value)
                        {
                            a_value = g_value;
                            a_index = k;
                        }
                    }

                    a_value = a_value == int.MaxValue ? int.MaxValue : a_value + 1;

                    int ctrlv_value = int.MaxValue, ctrlv_index = int.MaxValue;
                    for (var k = 0; k <= n; ++k)
                    {
                        var g_value = g(n - k, k);
                        if (g_value < ctrlv_value)
                        {
                            ctrlv_value = g_value;
                            ctrlv_index = k;
                        }
                    }

                    ctrlv_value = ctrlv_value == int.MaxValue ? int.MaxValue : ctrlv_value + 1;

                    var min_value = Math.Min(a_value, ctrlv_value);
                    fs[n] = min_value;

                    if (min_value == int.MaxValue)
                    {
                        fpn[n] = int.MaxValue;
                        fpm[n] = int.MaxValue;
                        fpd[n] = "*";
                    }
                    else if (min_value == a_value)
                    {
                        fpn[n] = n - 1;
                        fpm[n] = a_index;
                        fpd[n] = "a";
                    }
                    else
                    {
                        fpn[n] = n - ctrlv_index;
                        fpm[n] = ctrlv_index;
                        fpd[n] = "p";
                    }
                }
            }

            return fs[n];
        }

        private static int[,] gs = new int[top, top];
        private static int[,] gpn = new int[top, top];
        private static int[,] gpm = new int[top, top];
        private static String[,] gpd = new String[top, top];

        private static int g(int n, int m)
        {
            if (n < 0 || n >= top) return int.MaxValue;
            if (m < 0 || m >= top) return int.MaxValue;

            if (gs[n, m] == int.MinValue)
            {
                if (m > n)
                {
                    gs[n, m] = int.MaxValue;
                    gpn[n, m] = int.MaxValue;
                    gpm[n, m] = int.MaxValue;
                    gpd[n, m] = "*";
                }
                else if (n == 0)
                {
                    gs[n, m] = 0;
                    gpn[n, m] = int.MaxValue;
                    gpm[n, m] = int.MaxValue;
                    gpd[n, m] = "*";
                }
                else
                {
                    var a_value = g(n - 1, m) == int.MaxValue ? int.MaxValue : g(n - 1, m) + 1;

                    var ctrlv_value = int.MaxValue;
                    if (m != 0) ctrlv_value = g(n - m, m) == int.MaxValue ? int.MaxValue : g(n - m, m) + 1;

                    int ctrlac_value = int.MaxValue, ctrlac_index = int.MaxValue;
                    if (m == n)
                    {
                        for (var k = 0; k < m; ++k)
                        {
                            var g_value = g(n, k);
                            if (g_value < ctrlac_value)
                            {
                                ctrlac_value = g_value;
                                ctrlac_index = k;
                            }
                        }
                    }

                    ctrlac_value = ctrlac_value == int.MaxValue ? int.MaxValue : ctrlac_value + 2;

                    var min_value = Math.Min(a_value, Math.Min(ctrlv_value, ctrlac_value));
                    gs[n, m] = min_value;

                    if (min_value == int.MaxValue)
                    {
                        gpn[n, m] = int.MaxValue;
                        gpm[n, m] = int.MaxValue;
                        gpd[n, m] = "*";
                    }
                    else if (min_value == a_value)
                    {
                        gpn[n, m] = n - 1;
                        gpm[n, m] = m;
                        gpd[n, m] = "a";
                    }
                    else if (min_value == ctrlv_value)
                    {
                        gpn[n, m] = n - m;
                        gpm[n, m] = m;
                        gpd[n, m] = "p";
                    }
                    else
                    {
                        gpn[n, m] = n;
                        gpm[n, m] = ctrlac_index;
                        gpd[n, m] = "c";
                    }
                }
            }

            return gs[n, m];
        }

        private static String path(int i)
        {
            var length = f(i);
            var steps = new List<String>();
            if (length == int.MaxValue) return "path does not exist";

            int n = i, m = fpm[i];
            int pn = fpn[i], pm = fpm[i]; var pd = fpd[i];
            steps.Insert(0, pd);
//            String.Format("pn = {0}, pm = {1}, pd = {2}",
//                pn == int.MinValue ? "?" : pn == int.MaxValue ? "*" : pn.ToString(),
//                pm == int.MinValue ? "?" : pm == int.MaxValue ? "*" : pm.ToString(),
//                pd).Dump();
            n = pn; m = pm;

            while (n != int.MaxValue && m != int.MaxValue)
            {
                pn = gpn[n, m];
                pm = gpm[n, m];
                pd = gpd[n, m];

                steps.Insert(0, pd);
//                String.Format("pn = {0}, pm = {1}, pd = {2}",
//                    pn == int.MinValue ? "?" : pn == int.MaxValue ? "*" : pn.ToString(),
//                    pm == int.MinValue ? "?" : pm == int.MaxValue ? "*" : pm.ToString(),
//                    pd).Dump();

                n = pn;
                m = pm;
            }

            steps = steps.Where(step => step != "*").ToList();
            (steps.Count() + steps.Count(step => step == "c") == length).AssertTrue();
            if (steps.Count() == 0) return "path is empty";
            return steps.StringJoin(", ");
        }

        private const int from = 100;
        private const int to = 150;
        private const int top = to + 1;

        static void Main(string[] args)
        {
            var data = new String[to - from + 1, 5];
            from.UpTo(to).ForEach(i =>
            {
                data[i - from, 0] = i.ToString();
                data[i - from, 1] = "=>";
                data[i - from, 2] = f(i).ToString();
                data[i - from, 3] = ":";
                data[i - from, 4] = path(i).ToString();
            });

            print(data);
        }
    }
}