rendered paste bodyusing 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);
}
}
}