Добрый день!
Меня всегда интересовало не только ИТ, но и экзотерика и вот прочитав в очередной раз о 5-ти элементах (
http://ru.wikipedia.org/wiki/У-син#.D0.A2.D0.B0.D0.B1.D0.BB.D0.B8.D1.86.D0.B0_.D1.81.D0.BE.D0.BE.D1.82.D0.B2.D0.B5.D1.82.D1.81.D1.82.D0.B2.D0.B8.D0.B9_.D0.BF.D1.8F.D1.82.D0.B8_.D1.81.D1.82.D0.B8.D1.85.D0.B8.D0.B9_.D0.B4.D1.80.D1.83.D0.B3.D0.B8.D0.BC_.D0.BA.D0.B0.D1.82.D0.B5.D0.B3.D0.BE.D1.80.D0.B8.D1.8F.D0.BC_.D0.BA.D0.B8.D1.82.D0.B0.D0.B9.D1.81.D0.BA.D0.BE.D0.B9_.D1.84.D0.B8.D0.BB.D0.BE.D1.81.D0.BE.D1.84.D0.B8.D0.B8) меня заинтересовал такой вопрос: в этой системе есть как положительные связи, так и отрицательные, насколько она устойчива, легко ли вывести ее из равновесия? Если следовать указанной теории, то весь мир и любое явление можно представить как совокупность 5-ти элементов или систем состоящих из этих элементов. Для поиска ответа я решил написать программу, реализующую расчет.
#include <stdio.h>
#include <stdlib.h>
// описание структуры элементы
struct Element
{
char *name; // имя
int support; // поддерживает
int destroy; // разрушает
double mass; // кол-во элементов
};
int time=1;
struct Element elements[6], elements_copy[6]; // делаю массив на 6, чтобы сохранить традиционную нумерацию
int init ()
{
/* функция проводит предварительную инициализацию элементов,
* записывает их неихменные свойства, которые потом считаются
* констрантами. 5 элементов определы давно и менять их нельзя */
// элемент 1
elements[1].name="Металл";
elements[1].support=2;
elements[1].destroy=3;
// элемент 2
elements[2].name="Вода";
elements[2].support=3;
elements[2].destroy=4;
// элемент 3
elements[3].name="Дерево";
elements[3].support=4;
elements[3].destroy=5;
// элемент 4
elements[4].name="Огонь";
elements[4].support=5;
elements[4].destroy=1;
// элемент 5
elements[5].name="Земля";
elements[5].support=1;
elements[5].destroy=2;
return 0;
}
int print_element( struct Element *e, int a)
{
/* функция выдает на стандартный вывод информацию об элементах, ей передается
* указательна на их массив и аргумент=0, если писать кратко и =1 если полно */
int i;
for (i=1; i<6; i++) {
if (a==0) {
printf("%s, поддерживает %s, разрушает %s, кол-во %.2f", e.name, e[e.support].name, e[e.destroy].name, e.mass);
}
if (a==1) { printf ("%.2f ", e.mass);}
}
printf("\n");
return 0;
}
int copy()
{
// функция копирует элементы в структуру элементкопи
int i;
for (i=1;i<6;i++) {
elements_copy.name=elements.name;
elements_copy.support=elements.support;
elements_copy.destroy=elements.destroy;
elements_copy.mass=elements.mass;
}
return (0);
}
int life()
{
// реализуется взаимодействие между элементами
const int power=10; // в процентах
copy();
int i;
for (i=1;i<6;i++){
elements[elements_copy.destroy].mass=elements[elements_copy.destroy].mass - elements_copy.mass*power/100;
//printf("%s уменьшился на %.2f \n",elements_copy[elements_copy.destroy].name, elements_copy.mass*power/100);
elements[elements_copy.support].mass=elements[elements_copy.support].mass + elements_copy.mass*power/100;
//printf("%s увеличился на %.2f\n",elements_copy[elements_copy.support].name, elements_copy.mass*power/100);
if (elements[elements_copy.destroy].mass<0) { elements[elements_copy.destroy].mass=0;}
//printf("После обработки элемента №%d:",i);
//print_element(elements,1);
}
print_element(elements,1);
return (0);
}
int main (int argc, char * argv[])
{
if (argc<6) {
printf("Необходимо передать не менее 5 аргументов, разделяя их пробелами. Было передано %d \n", argc-1);
return(-1);
}
// предварительная инициализация элементов
init();
// инициализация структуры данными ввода
int i;
for (i=1; i<6; i++) {
elements.mass=atoi(argv);
}
// если время(кол-во циклов) передано аргументом, то получить,
// иначе остается значение по умолчанию=1
if (argc>6) { time=atoi(argv[6]);}
//print_element(elements,0);
print_element(elements,1);
for (i=0; i<time; i++) { life();}
return 0;
}
Работа с программой проста:
1) компилится командой gcc life.c (текст в файле life.c)
2) при запуске передается не менее 5-ти аргументов - кол-во металла, воды, дерева, огня, земли и можно передать 6-й - кол-во циклов взаимодействия, если не передано, то =1
3) программа выдает на консоль(в файл) изначальное кол-во элементов до взаимодействия и их кол-во после каждого цикла.
Пример использования:
$ ./a.out 8 10 10 10 10 5
8.00 10.00 10.00 10.00 10.00
8.00 9.80 10.20 10.00 10.00
8.00 9.60 10.38 10.04 9.98
7.99 9.40 10.54 10.12 9.95
7.98 9.21 10.68 10.23 9.90
7.94 9.01 10.80 10.38 9.86
Чтобы как визуализировать результаты я написал скрипт для gnuplot (файл plot.sc)
set terminal png font 'Verdana, 10'
set output '10.png'
set logscale x
set logscale y
plot 'result10.txt' using 1 with lines lw 2 lt rgb 'black' ti "Металл", '' using 2 with lines lw 2 lt rgb 'blue' ti "Вода", '' u 3 w lines lw 2 lt rgb 'green' ti "Дерево", '' u 4 w lines lw 2 lt rgb 'red' ti "Огонь", '' u 3 w lines lw 2 lt rgb 'brown' ti "Земля"
В итоге расчет и обработку результатов делаю так:
./a.out 8 10 10 10 10 100 > result10.txt
gnuplot "plot.sc"
И получаю график

К сожалению система совершенно не устойчива, более того - супер не стабильна... Зато это нетипичное и забавное применение linux программ.