using System;
namespace Symbolic
{
class Program
{
static char Char(int d)
{
return (char)(d + (int)'0');
}
static int Digit(char c)
{
return (int)(c - '0');
}
static string Multiply(string a, string b)
{
int[] acc = new int[a.Length + b.Length];
for (int i = a.Length - 1; i >= 0; i--)
{
int rest = 0;
for (int j = b.Length - 1; j >= 0; j--)
{
int temp = acc[i + j + 1] + (Digit(a[i]) * Digit(b[j])) + rest;
acc[i + j + 1] = temp % 10;
rest = temp / 10;
}
acc[i] = acc[i] + rest;
}
int start = 0;
while (acc[start] == 0)
{
start++;
}
char[] result = new char[acc.Length - start];
for (int i = start; i < acc.Length; i++)
{
result[i - start] = Char(acc[i]);
}
return new string(result);
}
static string Previous(char c)
{
return Char(Digit(c) - 1).ToString();
}
static string Decrement(string a)
{
string prev = Previous(a[0]);
if (a.Length == 1)
{
return prev;
}
if (a[a.Length - 1] != '0')
{
var rest = a.Substring(0, a.Length - 1);
return rest + Previous(a[1]);
}
else
{
var rest = a.Substring(0, a.Length - 2);
if ((rest == "") && (prev == "0"))
prev = "";
return rest + prev + '9';
}
}
static string Fact(string value)
{
string result = "1";
while (value != "0")
{
result = Multiply(result, value);
value = Decrement(value);
}
return result;
}
static void Main(string[] args)
{
Console.WriteLine(Fact("30"));
}
}
}