В частности, Вы уже начали в своём примере писать какие-то операторы на естественном языке, не задумываясь над тем, что они должны быть сначала определены.
for (int i = 1; i <= 1000000; ++i)
out_file.WriteLine("1");
Если же Вы реально хотите получить численные оценки сложности каких-то строк, то более разумно взять какой-нибудь реальный алгоритм сжатия, например, LZW.
Нет, это не более разумно. Потому что "реальные" (читай - прикладные) алгоритмы сжатия создавались так, чтобы как можно лучше сжимать часто встречающиеся на практике последовательности, и разработчикам было плевать, что строка, которая никому никогда не встретится, при этом расширится. Задача, чтобы длина архива всегда была не больше длины исходника, не ставилась. Но такая задача разрешима, и ниже я привожу самый очевидный пример ее решения.
Отсюда следует, что если есть некое подмножество сжимаемых этим алгоритмом строк, то есть и не менее обширное подмножество строк, которые этим алгоритмом наоборот расширяются.
Вот алгоритм, записанный на C#, который по введенной последовательности sequence длины 100000 печатает текст программы (опять же на C#) выводящий эту последовательность. Пожалуйста, укажите последовательность, для которой количество строк в напечатанном тексте программы превзойдет длину последовательности.
int [] sequence = new int [100000];
//Опускаю заполнение массива из внешнего источника (файла, устройства, алгоритма)
int i = 0; //счетчик элементов массива
int element = sequence[0]; // запоминаем первый элемент массива
int rep = 1; //счетчик подряд идущих одинаковых элементов
while (i < sequence.Length )
{
while(i + rep < sequence.Length && sequence[i + rep] == element)
++rep; //посчитали, сколько раз подряд повторяется элемент
if (rep > 1)
{
Program_text.WriteLine("for (int i = 1; i <=" + rep + "; ++i)");
Program_text.WriteLine ( "out_file.WriteLine(" + element + ");" );
//если элемент повторяется rep > 1 раз, пишем в тексте программы "напечатать его rep раз"
}
else
Program_text.WriteLine("out_file.WriteLine(" + element + ");" ); // иначе просто пишем "напечатать этот элемент";
i = i + rep;
if (i < sequence.Length)
element = sequence[i];
rep = 1; //сбрасываем счетчик повторов
}
Примеры вывода программы (сократил длину массива до 10).
Для массива из одних нулей:
Код:
for (int i = 1; i <=10; ++i)
out_file.WriteLine(0);
Для массива из 5 единиц подряд, остальные нули:
Код:
for (int i = 1; i <=5; ++i)
out_file.WriteLine(1);
for (int i = 1; i <=5; ++i)
out_file.WriteLine(0);
Для массива, где 1 и 0 чередуются через один:
Код:
out_file.WriteLine(1);
out_file.WriteLine(0);
out_file.WriteLine(1);
out_file.WriteLine(0);
out_file.WriteLine(1);
out_file.WriteLine(0);
out_file.WriteLine(1);
out_file.WriteLine(0);
out_file.WriteLine(1);
out_file.WriteLine(0);
Понятно, что сжатие не оптимальное. Последовательность

можно сжать до двух строк, а мой алгоритм ее фактически не сжимает. Но любую последовательность, в которой есть хотя бы три одинаковых элемента подряд, он сжимает. И никакую не расширяет.