Anonymous avatar Anonymous committed b1e01da

Added the nostalgia programs.

Comments (0)

Files changed (40)

lib/Shlomif/Homepage/SectionMenu/Sects/Software.pm

                     'title' => "Against using the qmail SMTP Server",
                 },
             ],
-        },        
+        },
+        {
+            'text' => "Nostalgia",
+            'url' => "open-source/nostalgia/",
+            'title' => "Software I wrote for DOS back in the prehistoric days",
+        },
     ],
 };
 

t2/open-source/index.html.wml

 bad programs. 
 </p>
 
+<h2><a href="./nostalgia/">Nostalgia - Some Ancient Software of Mine</a></h2>
+
+<p>
+These are old programs I wrote for DOS for high school, mostly in
+<a href="http://en.wikipedia.org/wiki/Turbo_C++">Turbo C++</a>.
+</p>
+

t2/open-source/nostalgia/index.html.wml

+#include '../template.wml'
+<latemp_subject "Shlomi Fish' Ancient Code" />
+
+<p>
+I found a zip file lying around on the hard disk, containing some code I wrote 
+back in my DOS days for Turbo C++. It can be downloaded from 
+<a href="./progs/">this directory</a>. The licence for all this code is 
+MIT X11 licence, but I don't think it's worth much, because it's 16-bit and
+may only run on DOS, and there are probably much more superior alternatives
+<a href="http://freshmeat.net/">available somewhere</a>.
+</p>
+
+<p>
+But if you wish to be impressed (or unimpressed) by my programming skills
+at high school, free to check this code out. Here's a short description of 
+them:
+</p>
+
+<define-tag file>
+<preserve name />
+<set-var %attributes />
+<a href="progs/<get-var name />"><b><get-var name /></b></a>
+<restore name />
+</define-tag>
+
+<ul>
+<li id="csee">
+<p>
+<file name="csee.h" />, <file name="csee.cpp" /> -
+C-See - a library of various graphical routines.
+</p>
+</li>
+<li id="ccalc">
+<p>
+<file name="ccalc.cpp" /> - C-Calc - a library of mathematical and
+number theory routines.
+</p>
+</li>
+<li id="gregorian_to_jewish">
+<p>
+<file name="gtoj.c" />, <file name="gtoj2.cpp" />, <file name="gtoj.h" /> -
+some routines to convert dates of 
+<a href="http://en.wikipedia.org/wiki/Gregorian_calendar">the 
+Gregorian Calendar</a> to the 
+<a href="http://en.wikipedia.org/wiki/Hebrew_calendar">Hebrew Calendar</a>.
+I wrote it for a friend's school project, in which he wrote a
+schedule-management program for schools.
+</p>
+<p>
+I implemented it entirely based on what I read about it in the Hebrew
+Encyclopedia. I first used some C++ paradigms, but then converted it entirely
+to ANSI C.
+</p>
+</li>
+<li id="bezier">
+<p>
+<file name="bezier.cpp" /> - a program to generate Bezier Curves.
+</p>
+</li>
+<li id="mandelbroot">
+<p>
+<file name="mandelbr.cpp" /> - a program to generate the Manelbrot set. (Who
+didn't write something like that?)
+</p>
+</li>
+<li id="cdd">
+<p>
+<file name="cdd.cpp" /> - a program to change a drive and a directory at 
+once. Like <tt>cdd d:\progs\tcc</tt>.
+</p>
+</li>
+</ul>
+

t2/open-source/nostalgia/progs/3dimage.cpp

+#include <graphics.h>
+#include <stdlib.h>
+
+#define WIDTH 500 // width of picture - in pixels
+#define HEIGHT 300
+//#define EYES 180 // eye seperation (assuming a 72 dpi screen)
+#define EYES 108
+
+
+int randomBlackWhite()
+{
+	return random(2) * EGA_WHITE;
+}
+
+void draw3D (int (*z)(int,int))
+{
+	int x, y, same[WIDTH], color[WIDTH], sep, i, j, s;
+	for(y=0;y<HEIGHT;y++)
+	{
+		for(x=0;x<WIDTH;x++) same[x] = x;
+		for(x=0;x<WIDTH;x++)
+		{
+			sep = z(x,y); i = x-(sep+(sep&y&1))/2; j = i+sep;
+			if ((0 <= i) && (j<WIDTH))
+			{
+				for (s=same[i]; (s!=i)&&(s!=j); s=same[i])
+					if (s>j) {same[i] = j;i=j;j=s;}
+					else i = s;
+				same[i] = j;
+			}
+		}
+		for (x=WIDTH-1;x>=0;x--)
+		{
+			if (same[x]==x) color[x] = randomBlackWhite();
+			else color[x] = color[same[x]];
+			putpixel(x,y,color[x]);
+		}
+	}
+}
+
+#define GROUND (EYES/2) // a dot seperation for distanat object
+#define HAT (GROUND-1) // objects near background are easier to see
+
+int topHat(int x, int y)
+{
+	int brimRadius = 70, headRadius = 30, brimHeight = 25;
+	if (y>=HEIGHT/2-brimRadius)
+	{
+		if ((y<HEIGHT/2+brimRadius-brimHeight) && (x >= WIDTH/2-headRadius) && (x<WIDTH/2+headRadius))
+			return HAT;
+		else if (y < HEIGHT/2+brimRadius)
+			if ((x>=WIDTH/2-brimRadius)&&(x<WIDTH/2+brimRadius))
+				return HAT;
+	}
+	return GROUND;
+}
+
+int main()
+{
+	randomize();
+	int a= DETECT, b;
+	initgraph(&a,&b,"c:\\tc\\bgi");
+	cleardevice();
+	draw3D(topHat);
+	_AX = 1; asm int 0x16;
+	_AX = 1; asm int 0x16;
+	_AX = 1; asm int 0x16;
+	_AX = 1; asm int 0x16;
+	return 0;
+}

t2/open-source/nostalgia/progs/adventre.cpp

+
+const unsigned BindiNum = 10000;
+const unsigned NindiNum = 100;
+const unsigned SindiNum = 30;
+const unsigned MaxOrdersNum = 500;
+
+char B_indicators[BindiNum];  // Binary indicators
+char N_indicators[NindiNum];  // Numeral indicators
+char S_indicators[SindiNum][30]; // String indicators
+
+struct order_index
+{
+	numorder no;
+	void * ptr;
+}
+
+class Screen
+{
+	protected:
+	unsigned orders_num;
+	order_index indexes[MaxOrdersNum];
+	char order_data[MaxOrdersNum * 15];
+	void * picture;
+}

t2/open-source/nostalgia/progs/annoi.cpp

+#include <constrea.h>
+#include <dos.h>
+
+unsigned WINDOW_HEIGHT = 20;
+constream AnnoiCon;
+
+struct Annoi_move
+{
+	unsigned from : 4;
+	unsigned to : 4;
+};
+
+const unsigned MAX_DISKS_NUM = 10;
+
+
+
+class Annoi_Towers
+{
+	protected:
+	unsigned disks_num;
+	char towers[3][MAX_DISKS_NUM];
+	Annoi_move moves[1023];
+	unsigned move_num;
+	void(*present_move)(unsigned,unsigned,unsigned);
+	public:
+	Annoi_Towers(unsigned,void(*)(unsigned,unsigned,unsigned));
+	void move_disk(unsigned,unsigned);
+	void creat_1p_tower(unsigned);
+	void move_all_disks();
+};
+
+Annoi_Towers::Annoi_Towers(unsigned new_disks_num, void(*new_pm)(unsigned,unsigned,unsigned))
+{
+	disks_num=new_disks_num;
+	present_move = new_pm;               //   The direction is upwards:
+	for(unsigned a=0;a<disks_num;a++)    //                /^\ 5
+	{                                    //                 |  4   (cells, not
+		towers[0][a]=disks_num-a;         //                 |  3    disks!)
+		towers[1][a]=towers[2][a]=0;      //                 |  2
+		(*present_move)(0,a,disks_num-a); //                 |  1
+	}                                    //                 |  0
+	move_num=0;
+}
+
+void Annoi_Towers::move_disk(unsigned from,unsigned to)
+{
+	unsigned from_high,to_high;
+	for(from_high=0;from_high<disks_num;from_high++)
+	{
+		if(towers[from][from_high]==0)
+			break;
+	}
+	from_high--;
+	for(to_high=0;towers[to][to_high]!=0;to_high++) ;
+	delay(200); //getch();
+	towers[to][to_high]=towers[from][from_high];
+	(*present_move)(to,to_high,towers[from][from_high]);
+	towers[from][from_high]=0;
+	(*present_move)(from,from_high,0);
+	moves[move_num].from=from;
+	moves[move_num].to=to;
+	move_num++;
+}
+
+/*
+	if a n-disks tower was already constructed it will be on
+	tower 2-n%2. thus for the moves recorded so far:
+	Origin == 0; Target = 2-n%2;Third=n%2+1;
+	After the nth stone was put, the object is to move the stones
+	from the 2-n%2 tower to the 1+n%2 tower.Thus:
+	Origin == 2-n%2;Target=1+n%2;Third==0;
+*/
+
+
+void Annoi_Towers::creat_1p_tower(unsigned num)
+{
+	unsigned t_aliases[3],a;
+	// The n%2 numbers are reversed since num refers to the next number;
+	t_aliases[0] = 1+num%2; // Origin
+	t_aliases[1+num%2] = 2-num%2; // Target
+	t_aliases[2-num%2] = 0; // Third
+	move_disk(0,2-num%2);
+	for(a=0;a<((1<<(num-1))-1);a++)
+		move_disk(t_aliases[moves[a].from],t_aliases[moves[a].to]);
+}
+
+void Annoi_Towers::move_all_disks()
+{
+	for(unsigned a = 1;a<=disks_num;a++)
+		creat_1p_tower(a);
+}
+
+void AnnoiConMove(unsigned tower,unsigned place,unsigned new_disk)
+{
+	(AnnoiCon.rdbuf())->gotoxy(tower*2+1,WINDOW_HEIGHT-place);
+	if (new_disk)
+	{
+		(AnnoiCon.rdbuf())->textcolor(new_disk);
+		AnnoiCon << (char)('0'+new_disk);
+	}
+	else AnnoiCon << ' ';
+}
+
+int main()
+{
+	AnnoiCon.window(1,1,80,25);AnnoiCon.clrscr();
+	AnnoiCon.window(1,1,8,WINDOW_HEIGHT);
+	Annoi_Towers annoi(9,&AnnoiConMove);
+	annoi.move_all_disks();
+	getch();
+	return 0;
+}

t2/open-source/nostalgia/progs/annoi2.cpp

+#include <constrea.h>
+#include <dos.h>
+
+unsigned WINDOW_HEIGHT = 20;
+constream AnnoiCon;
+
+const unsigned MAX_DISKS_NUM = 10;
+
+
+
+class Annoi_Towers
+{
+	protected:
+	unsigned disks_num;
+	char towers[3][MAX_DISKS_NUM];
+	unsigned long move_num;
+	void(*present_move)(unsigned,unsigned,unsigned);
+	public:
+	Annoi_Towers(unsigned,void(*)(unsigned,unsigned,unsigned));
+	void move_disk();
+	void creat_1p_tower(unsigned);
+	void move_all_disks();
+};
+
+Annoi_Towers::Annoi_Towers(unsigned new_disks_num, void(*new_pm)(unsigned,unsigned,unsigned))
+{
+	disks_num=new_disks_num;
+	present_move = new_pm;               //   The direction is upwards:
+	for(unsigned a=0;a<disks_num;a++)    //                /^\ 5
+	{                                    //                 |  4   (cells, not
+		towers[0][a]=disks_num-a;         //                 |  3    disks!)
+		towers[1][a]=towers[2][a]=0;      //                 |  2
+		(*present_move)(0,a,disks_num-a); //                 |  1
+	}                                    //                 |  0
+	move_num=1;
+}
+
+/*
+	if a n-disks tower was already constructed it will be on
+	tower 2-n%2. thus for the moves recorded so far:
+	Origin == 0; Target = 2-n%2;Third=n%2+1;
+	After the nth stone was put, the object is to move the stones
+	from the 2-n%2 tower to the 1+n%2 tower.Thus:
+	Origin == 2-n%2;Target=1+n%2;Third==0;
+*/
+
+void Annoi_Towers::move_disk()
+{
+	int from=0, to, n=1;
+	unsigned from_high,to_high;
+	unsigned long _movenum = move_num;
+	while(_movenum%2==0)
+	{
+		_movenum>>=1;
+		n++;
+	}
+	to = 2-n%2;
+	_movenum>>=1;n++;
+	while(_movenum)
+	{
+		if (n%2)
+		{
+			to-=_movenum%2;from-=_movenum%2;
+		}
+		else {
+			to+=_movenum%2;from+=_movenum%2;
+		}
+		_movenum>>=1;n++;
+	}
+	to=(to+3000)%3;from=(from+3000)%3; // In case from or to are negative.
+	for(from_high=0;from_high<disks_num;from_high++)
+	{
+		if(towers[from][from_high]==0)
+			break;
+	}
+	from_high--;
+	for(to_high=0;towers[to][to_high]!=0;to_high++) ;
+	getch();
+	towers[to][to_high]=towers[from][from_high];
+	(*present_move)(to,to_high,towers[from][from_high]);
+	towers[from][from_high]=0;
+	(*present_move)(from,from_high,0);
+	move_num++;
+}
+
+/*
+	if a n-disks tower was already constructed it will be on
+	tower 2-n%2. thus for the moves recorded so far:
+	Origin == 0; Target = 2-n%2;Third=n%2+1;
+	After the nth stone was put, the object is to move the stones
+	from the 2-n%2 tower to the 1+n%2 tower.Thus:
+	Origin == 2-n%2;Target=1+n%2;Third==0;
+*/
+
+
+void Annoi_Towers::creat_1p_tower(unsigned num)
+{
+	if (move_num == (1<<(num-1)))
+	{
+		for(move_num=move_num;move_num<=(1<<num)-1;move_disk()) ;
+	}
+}
+
+void Annoi_Towers::move_all_disks()
+{
+	for(unsigned a = 1;a<=disks_num;a++)
+		creat_1p_tower(a);
+}
+
+void AnnoiConMove(unsigned tower,unsigned place,unsigned new_disk)
+{
+	(AnnoiCon.rdbuf())->gotoxy(tower*2+1,WINDOW_HEIGHT-place);
+	if (new_disk)
+	{
+		(AnnoiCon.rdbuf())->textcolor(new_disk);
+		AnnoiCon << (char)('0'+new_disk);
+	}
+	else AnnoiCon << ' ';
+}
+
+int main()
+{
+	AnnoiCon.window(1,1,80,25);AnnoiCon.clrscr();
+	AnnoiCon.window(1,1,8,WINDOW_HEIGHT);
+	Annoi_Towers annoi(9,&AnnoiConMove);
+	annoi.move_all_disks();
+	getch();
+	return 0;
+}

t2/open-source/nostalgia/progs/assoc.cpp

+/* ASSOC.CPP - a program to make wild associations.
+switches - '?' - help
+			  'h' - in hebrew
+
+*/
+#include <conio.h>
+#include <stdlib.h>
+#include <time.h>
+enum yes_no {yes, no};
+
+int main(int argc, char * argv[])
+{
+	randomize();
+	char c='j',l;
+	yes_no heb = no;
+	if (argc > 2)
+	{
+		cprintf("\n\rToo many or unknown arguments.\n\rType \"ASSOC ?\" for help");
+		goto end;
+	}
+	if (argv[1][0] == '?')
+	{
+		cprintf("\n\rWelcome to ASSOCiation - the useful program to bring you fast realy wild associations. \
+		\n\rIn order to use it type \"ASSOC\" or \"ASSOC h\" for associations in hebrew. The program will then type \
+		one letter. If you want to type more letters one by one press any key except the following: RETURN that ends \
+		the program or backspace that replaces the last letter.\n\rHave fun!!!\n\n\r");
+		goto end;
+	}
+	else if (argv[1][0] == 'h')
+	{
+		heb = yes;
+	}
+	cputs("\n\n\rYour association is: ");
+	while (c != 13)
+	{
+		l = (random(25) + 65) * (heb == no) + (random(26)+128) * (heb == yes);
+		if ((l == '�') || (l == '�') || (l == '�') || (l == '�') || (l == '�')) {l++;}
+		putch(l);
+		c = getch();
+		if (c == 8) { gotoxy(wherex()-1,wherey()); putch(' '); gotoxy(wherex()-1,wherey());}
+	}
+	end: return 0;
+}

t2/open-source/nostalgia/progs/bezier.cpp

+#include <graphics.h>
+#include <time.h>
+#include <stdlib.h>
+#include <math.h>
+
+unsigned accuracy = 1000;
+
+enum bez_num {S=0, L=1, R=2, E=3};
+
+void bezier(int * x, int * y)
+{
+	unsigned pf, color = getcolor();
+	int xp[4] = {x[S], 3*(x[L]-x[S]), 3*(x[R]+x[S]-2*x[L]), 3*(x[L]-x[R])+x[E]-x[S]};
+	int yp[4] = {y[S], 3*(y[L]-y[S]), 3*(y[R]+y[S]-2*y[L]), 3*(y[L]-y[R])+y[E]-y[S]};
+	double p, p1 = 1/(double)accuracy;
+	for (pf=0;pf<=accuracy;pf++)
+	{
+		p = p1*pf;
+		putpixel(xp[0]+p*(xp[1]+p*(xp[2]+p*xp[3])), yp[0]+p*(yp[1]+p*(yp[2]+p*yp[3])), color);
+	}
+}
+
+double angle_type_n = 1;
+
+void angle_bezier(double * data)
+{
+	int x[4], y[4];
+	x[0] = (int)data[0];
+	y[0] = (int)data[1];
+	x[3] = (int)data[6];
+	y[3] = (int)data[7];
+	x[1] = (int)(x[0]+data[2]*cos(data[3]*angle_type_n));
+	y[1] = (int)(y[0]-data[2]*sin(data[3]*angle_type_n));
+	x[2] = (int)(x[3]+data[4]*cos(data[5]*angle_type_n));
+	y[2] = (int)(y[3]-data[4]*sin(data[5]*angle_type_n));
+	bezier(x,y);
+}
+// The argument is the data field of the positions of the start point and end
+// point and the angles and lengthes of the "guide lines".
+
+
+int main()
+{
+	angle_type_n = M_PI / 180;
+	randomize();
+	int a = DETECT,b, x[4] = {10,100,500,600}, y[4] = {10,20,280,300};
+//	double d[8] = {10.0,10.0,45.0,280.0,40.0,140.0,300.0,200.0};
+	double d[8] = {10,10,40,135,200,90,600,300};
+	initgraph(&a,&b,"c:\\tc\\bgi");
+	setcolor(2);
+	_AX = 1;asm int 0x16;
+	angle_bezier(d);
+	_AX = 1;asm int 0x16;
+	return 0;
+}
+
+/*#define prop(x1, x2) (x1+(x2-x1)*a/300)
+void bezier(int sx, int sy, int ex, int ey,
+				int s_x, int s_y, int e_x, int e_y)
+{
+	double px[7], py[7];
+	for (int a=0;a<300;a++)
+	{
+		px[1] = prop(sx,s_x);
+		py[1] = prop(sy,s_y);
+		px[2] = prop(s_x,e_x);
+		py[2] = prop(s_y,e_y);
+		px[3] = prop(e_x,ex);
+		py[3] = prop(e_y,ey);
+		px[4] = prop(px[1],px[2]);
+		py[4] = prop(py[1],py[2]);
+		px[5] = prop(px[2],px[3]);
+		py[5] = prop(py[2],py[3]);
+		px[6] = prop(px[4],px[5]);
+		py[6] = prop(py[4],py[5]);
+		putpixel((int)px[6],(int)py[6],getcolor());
+	}
+}*/

t2/open-source/nostalgia/progs/ccalc.cpp

+#ifndef __CCALC_H
+#define __CCALC_H
+
+#ifndef __cplusplus
+#error CCALC.H requires C++
+#endif
+
+#ifndef __MATH_H
+#include <math.h>
+#endif
+
+#ifndef __STRSTREA_H
+#include <strstream.h>
+#endif
+
+#ifndef __STDLIB_H
+#include <stdlib.h>
+#endif
+
+#define num_ numerator
+#define denom_ denominator
+
+//finds the greatest common dividor of two numbers (Euclid's algorithm)
+unsigned int gcd (unsigned int number1, unsigned int number2);
+unsigned long lgcd (unsigned long number1, unsigned long number2);
+
+unsigned long factorial(unsigned int Number);
+unsigned long nPr(unsigned int Base, unsigned int secondary);
+unsigned long nCr(unsigned int Base, unsigned int secondary);
+double prob_appear(unsigned int, unsigned int, unsigned int );
+char * roman(unsigned int number);
+void mix(int * Place, unsigned int maxnum);
+void getmultipliers(unsigned, unsigned *, int);
+void lgetmultipliers(unsigned long, unsigned long *, int);
+inline double blog(double x, double base) {return (log(x)/log(base));}
+inline long double blogl(long double x, long double base) {return (logl(x)/logl(base));}
+int IsPrime (unsigned long);
+int IsPrimef (unsigned);
+int IsPrimefl (unsigned long);
+
+template <class N> void swap(N * x, N * y)
+{
+	N temp;
+	temp = *x;
+	*x = *y;
+	*y = temp;
+}
+
+template <class N> long double average(N * place, unsigned itemsnumber)
+{
+	long double aver;
+	for(unsigned a=0;a<itemsnumber;a++)
+		aver += *(place+itemsnumber)
+	return (aver/itemsnumber);
+}
+
+void bwrite(void * c, unsigned int place, unsigned int value)
+{
+	if (value) *((unsigned char*)c+place/8) |= 1 << place%8;
+	else *((unsigned char*)c+place/8) &= 255 - (1 << place%8);
+}
+
+unsigned int bread(void *c, unsigned int place)
+{
+	return (*((unsigned char*)c+place/8) % (1 << place%8+1)) / (1 << place%8);
+}
+
+struct fract
+{
+	long numerator;
+	unsigned int denominator;
+	fract(long newnumer, unsigned int newdenom);
+	fract(int whole, unsigned int newnumer, unsigned int newdenom);
+	fract(void);
+	void ins(long newnumer, unsigned int newdenom);
+	void optimize();
+	fract operator= (fract newfract);
+	fract operator= (int);
+	float ToFloat();
+	double ToDouble();
+};
+
+ostream & operator<<(ostream & os, fract & f);
+
+int operator==(fract f1, fract f2);
+int operator==(fract f1, double other);
+int operator==(double other, fract f1);
+int operator<(fract f1, fract f2);
+int operator>(fract f1, fract f2);
+int operator!=(fract f1, fract f2);
+int operator<=(fract f1, fract f2);
+int operator>=(fract f1, fract f2);
+fract operator*(fract f1, fract f2);
+fract operator/(fract f1, fract f2);
+fract operator+(fract f1, fract f2);
+fract operator-(fract f1, fract f2);
+void operator*=(fract original, fract newfract);
+void operator/=(fract original, fract newfract);
+void operator+=(fract original, fract newfract);
+void operator-=(fract original, fract newfract);
+int operator!(fract AFract) {return !AFract.num_;}
+double abs(fract f1);
+double sin(fract f1);
+double cos(fract f1);
+double tan(fract f1);
+double atan(fract f1);
+double asin(fract f1);
+double acos(fract f1);
+double atan2(fract f1, fract f2);
+double cosh(fract f1);
+double sinh(fract f1);
+double tanh(fract f1);
+double sqrt(fract f1);
+fract pow(fract f1, unsigned int a);
+
+fract::fract(long newnumer, unsigned int newdenom)
+{
+	num_ = newnumer;
+	denom_ = newdenom;
+	optimize();
+}
+
+fract::fract(int whole, unsigned int newnumer, unsigned int newdenom)
+{
+	num_ = whole * newdenom + newnumer - 2 * newnumer * (whole < 0);
+	denom_ = newdenom;
+	optimize();
+}
+
+fract::fract(void)
+{
+	num_ = 0; denom_ = 1;
+}
+
+void fract::ins(long newnumer, unsigned int newdenom)
+{
+	num_ = newnumer;
+	denom_ = newdenom;
+}
+
+void fract::optimize()
+{
+	unsigned long t = lgcd(labs(num_), denom_);
+	num_ /= t;
+	denom_ /= (t % 32768l);
+}
+
+fract fract::operator= (fract newfract)
+{
+	num_ = newfract.num_; denom_ = newfract.denom_;
+	return newfract;
+}
+
+fract fract::operator= (int intval)
+{
+	fract newfract(intval,1);
+	num_  =newfract.num_; denom_ = newfract.denom_;
+	return newfract;
+}
+float fract::ToFloat()
+{
+	float a = num_, b = denom_;
+	return a/b;
+}
+
+double fract::ToDouble()
+{
+	double a = num_, b = denom_;
+	return a/b;
+}
+
+ostream & operator<<(ostream & os, fract & f)
+{
+	if (labs(f.num_ / f.denom_) > 0) os << f.num_ / f.denom_ << " ";
+	if (labs(f.num_ % f.denom_) > 0) {
+		if (f.num_ / f.denom_ > 0) os << labs(f.num_% f.denom_);
+		else os << f.num_ % f.denom_;
+		os << "/" << f.denom_;
+	}
+	return os;
+}
+
+int operator==(fract f1, fract f2)
+{
+	f1.optimize();f2.optimize();
+	return ((f1.num_ == f2.num_) || (f1.denom_ == f2.denom_));
+}
+
+int operator==(fract f1, double other)
+{
+	return (f1.ToDouble() == other);
+}
+
+int operator==(double other, fract f1)
+{	return (f1 == other);}
+
+int operator<(fract f1, fract f2)
+{  return (f1.ToDouble() < f2.ToDouble());}
+
+int operator>(fract f1, fract f2)
+{  return (f2 < f1);}
+
+int operator!=(fract f1, fract f2)
+{  return (!(f1 == f2));}
+
+int operator<=(fract f1, fract f2)
+{	return (!(f1 > f2));}
+
+int operator>=(fract f1, fract f2)
+{	return (!(f1 < f2));}
+
+fract operator*(fract f1, fract f2)
+{
+	f1.optimize();f2.optimize();
+	fract f3(f1.num_ * f2.num_, f1.denom_ * f2.denom_);
+	f3.optimize();
+	return f3;
+}
+
+fract operator/(fract f1, fract f2)
+{
+	fract f3;
+	f1.optimize();f2.optimize();
+	if (f1.denom_ * f2.num_ < 32768l)
+	{
+		f3.ins(f1.num_ * f2.denom_, (f1.denom_ * f2.num_) % 32768l);
+		f3.optimize();
+	} else {cerr << "The two fractions are too complex to be divided!\n";}
+	return f3;
+}
+
+fract operator+(fract f1, fract f2)
+{
+	f1.optimize();
+	f2.optimize();
+	fract f3((f1.num_ * f2.denom_) + (f1.denom_ * f2.num_), f1.denom_ * f2.denom_);
+	return f3;
+}
+
+fract operator-(fract f1, fract f2)
+{
+	f2.num_ = f2.num_ * -1;
+	return (f1 + f2);
+}
+
+void operator*=(fract original, fract newfract) {original = newfract * original;}
+void operator/=(fract original, fract newfract) {original = original / newfract;}
+void operator+=(fract original, fract newfract) {original = newfract + original;}
+void operator-=(fract original, fract newfract) {original = original - newfract;}
+
+double sin(fract f1) {return sin(f1.ToDouble());}
+double cos(fract f1) {return cos(f1.ToDouble());}
+double tan(fract f1) {return tan(f1.ToDouble());}
+double atan(fract f1) {return atan(f1.ToDouble());}
+double asin(fract f1) {return asin(f1.ToDouble());}
+double acos(fract f1) {return acos(f1.ToDouble());}
+double atan2(fract f1, fract f2) {return atan2(f1.ToDouble(), f2.ToDouble());}
+double cosh(fract f1) {return cosh(f1.ToDouble());}
+double sinh(fract f1) {return sinh(f1.ToDouble());}
+double tanh(fract f1) {return tanh(f1.ToDouble());}
+double sqrt(fract f1) {return sqrt(f1.ToDouble());}
+fract frprob_appear(unsigned int , unsigned int , unsigned int );
+
+struct exp_t
+{
+	char mpandexp[3];
+	int getmp();
+	int getexp();
+};
+
+int exp_t::getmp()
+{return *((unsigned *)&mpandexp[0]);}
+
+int exp_t::getexp()
+{return *((unsigned char *)&mpandexp[2]);}
+
+struct lexp_t
+{
+	char mpandexp[5];
+	unsigned long getmp();
+	int getexp();
+};
+
+unsigned long lexp_t::getmp()
+{return *((unsigned long *)&mpandexp[0]);}
+
+int lexp_t::getexp()
+{return *((unsigned char *)&mpandexp[4]);}
+
+void cgetmultipliers(unsigned , exp_t * );
+void lcgetmultipliers(unsigned long, lexp_t * mps);
+
+
+fract pow(fract f1, unsigned int a)
+{
+	f1.num_ = (long)pow(f1.num_, a);
+	f1.denom_ = (unsigned int)pow(f1.denom_, a);
+	return f1;
+}
+
+unsigned int gcd(unsigned int number1, unsigned int number2)
+{
+	unsigned int temp;
+	if (number1 < number2)
+	{
+		temp = number1;
+		number1 = number2;
+		number2 = temp;
+	}
+	while (number1 % number2 != 0)
+	{
+		temp = number1 % number2;
+		number1 = number2;
+		number2 = temp;
+	}
+	return number2;
+}
+
+unsigned long lgcd(unsigned long number1, unsigned long number2)
+{
+	unsigned long temp;
+	if (number1 < number2)
+	{
+		temp = number1 ;
+		number1 = number2;
+		number2 = temp;
+	}
+	while (number1 % number2 != 0)
+	{
+		temp = number1 % number2;
+		number1 = number2;
+		number2 = temp;
+	}
+	return number2;
+}
+
+unsigned long factorial(unsigned int Number)
+{
+	unsigned long Result = 1;
+	for(int a=1;a<=Number;a++) Result *= a;
+	return Result;
+}
+
+unsigned long nPr(unsigned int Base, unsigned int secondary)
+{
+	unsigned long Result = 1;
+	if (Base >= secondary) {
+		for (int a = 0;a<secondary;a++) Result *= Base - a;
+		return Result;
+	} else return 0;
+}
+
+unsigned long nCr(unsigned int Base, unsigned int secondary)
+{
+	return (nPr(Base,secondary) / factorial(secondary));
+}
+
+char * roman(unsigned int number)
+{
+	char * Roman = "";
+	ostrstream os;
+	if (number > 3999) cerr << "The number given to roman() is too big";
+	else
+	{
+		switch(number / 1000) {
+			case 0 : break;
+			case 1 : os << "M";break;
+			case 2 : os << "MM";break;
+			case 3 : os << "MMM";
+		}
+		switch((number % 1000) / 100) {
+			case 0 : break;
+			case 3 : os << "C";
+			case 2 : os << "C";
+			case 1 : os << "C";break;
+			case 4 : os << "C";
+			case 5 : os << "D";break;
+			case 6 : os << "DC"; break;
+			case 7 : os << "DCC"; break;
+			case 8 : os << "DCCC"; break;
+			case 9 : os << "CM";
+		}
+		switch((number % 100) / 10) {
+			case 0 : break;
+			case 3 : os << "X";
+			case 2 : os << "X";
+			case 1 : os << "X";break;
+			case 4 : os << "X";
+			case 5 : os << "L";break;
+			case 6 : os << "LX"; break;
+			case 7 : os << "LXX"; break;
+			case 8 : os << "LXXX"; break;
+			case 9 : os << "XC";
+		}
+		switch(number % 10) {
+			case 0 : break;
+			case 3 : os << "I";
+			case 2 : os << "I";
+			case 1 : os << "I";break;
+			case 4 : os << "I";
+			case 5 : os << "V";break;
+			case 6 : os << "VI"; break;
+			case 7 : os << "VII"; break;
+			case 8 : os << "VIII"; break;
+			case 9 : os << "IX";
+		}
+	}
+	Roman = os.str();
+	*(Roman+os.pcount()) = '\0';
+	return Roman;
+}
+
+void mix(int * Place, unsigned int maxnum)
+{
+	int T = -1;
+	for (int a = 0;a<maxnum;a++) *(Place+a) = 0;
+	randomize();
+	for (a = 1;a<=maxnum;a++)
+	{
+		for (int b = 0;b<=random(maxnum-a+1);b++)
+		{
+			T++;
+			while(*(Place+T) != 0) T++;
+		}
+		*(Place+T) = a;
+		T=-1;
+	}
+}
+
+double get1stroot(double a, double b, double c)
+{
+	double d;
+	if ((a != 0) && (b*b-4*a*c>=0))
+	{
+		d = (-b + sqrt(b*b-4*a*c)) / (2*a);
+	} else {
+		cerr << "There is an error in the parameters of function get1stroot()!";
+		d = 0;
+	}
+	return d;
+}
+
+double get2ndroot(double a, double b, double c)
+{
+	double d;
+	if ((a != 0) && (b*b-4*a*c>=0))
+	{
+		d = (-b - sqrt(b*b-4*a*c)) / (2*a);
+	} else {
+		cerr << "There is an error in the parameters of function get1stroot()!";
+		d=0;
+	}
+	return d;
+}
+
+double prob_appear(unsigned int range, unsigned int Dnumber, unsigned int lowest)
+{
+	double Return;
+	if (!range || !Dnumber || !lowest || (lowest > range))
+	{
+		cerr << "Bad parameters in function prob_appear()";
+		Return = 0;
+	} else
+	{
+		Return = 1 - pow(lowest-1, Dnumber)/pow(range,Dnumber);
+	}
+	return Return;
+}
+
+fract frprob_appear(unsigned int range, unsigned int number, unsigned int lowest)
+{
+	fract Return;
+	if (!range || !number || !lowest || (lowest > range))
+	{
+		cerr << "Bad parameters in function frprob_appear()";
+	} else
+	{
+		Return.ins((long)pow(lowest-1, number),(unsigned int)pow(range,number));
+		Return.ins(labs(Return.denom_-Return.num_),Return.denom_);
+		Return.optimize();
+	}
+	return Return;
+}
+
+void getmultipliers(unsigned number, unsigned * mps, int with_exp = 0)
+{
+	unsigned a, exp;
+	if (with_exp)
+	{
+		for (a=2; a<=number; a++)
+		{
+			if (number%a == 0)
+			{
+				*mps = a;
+				mps++;
+				exp = 0;
+				while (number%a == 0)
+				{
+					number/= a;
+					exp++;
+				}
+				*mps=exp;
+				mps++;
+	}	}	}
+	else {
+		for (a=2; a<=number; a++)
+		{
+			while (number%a == 0)
+			{
+				*mps = a;
+				mps++;
+				number/= a;
+	}	}	}
+	*mps = 0;
+}
+
+void lgetmultipliers(unsigned long number, unsigned long * mps, int with_exp = 0)
+{
+	unsigned long a, exp;
+	if (with_exp)
+	{
+		for (a=2; a<=number; a++)
+		{
+			if (number%a == 0)
+			{
+				*mps = a;
+				mps++;
+				exp = 0;
+				while (number%a == 0)
+				{
+					number/= a;
+					exp++;
+				}
+				*mps=exp;
+				mps++;
+	}	}	}
+	else {
+		for (a=2; a<=number; a++)
+		{
+			while (number%a == 0)
+			{
+				*mps = a;
+				mps++;
+				number/= a;
+	}	}	}
+	*mps = 0;
+}
+
+void cgetmultipliers(unsigned number, exp_t * mps)
+{
+	unsigned a;
+	unsigned char exp;
+	for (a=2; a<=number; a++)
+	{
+		if (number%a == 0)
+		{
+			*((unsigned int * )mps) = a;
+			exp = 0;
+			while (number%a == 0)
+			{
+				number/= a;
+				exp++;
+			}
+			mps->mpandexp[2]=exp;
+			mps++;
+	}	}
+	*((unsigned int * )mps) = 0;
+}
+
+void lcgetmultipliers(unsigned long number, lexp_t * mps)
+{
+	unsigned long a;
+	unsigned char exp;
+	for (a=2; a<=number; a++)
+	{
+		if (number%a == 0)
+		{
+			*((unsigned long * )mps) = a;
+			exp = 0;
+			while (number%a == 0)
+			{
+				number/= a;
+				exp++;
+			}
+			mps->mpandexp[4]=exp;
+			mps++;
+	}	}
+	*((unsigned long * )mps) = 0;
+}
+
+int IsPrime(unsigned long number)
+{
+	unsigned long a, max = (unsigned long)sqrt(number);
+	for (a=2;a<=max;a++)
+		if (number%a == 0)
+		{
+			return 0;
+		}
+	return 1;
+}
+
+int IsPrimef(unsigned number)
+{
+	unsigned long remains[32], total_rem=1, temp1=number;
+	long temp2;
+	unsigned a;
+	if (number<3)
+		return 1;
+	else
+	{
+		remains[0]=2;
+		for (a=1;a<=blogl(number,2);a++)
+			remains[a] = (remains[a-1]*remains[a-1])%number;
+		for (a=(unsigned)blogl(number,2);temp1>0;a--)
+		{
+			temp2 = (unsigned long)pow(2,a);
+			if ((long)(temp1-temp2)>=0)
+			{
+				total_rem = (total_rem * remains[a]) % number;
+				temp1 -= temp2;
+			}
+		}
+		return (total_rem == 2);
+	}
+}
+
+int IsPrimefl (unsigned long number)
+{
+	unsigned long exps[100], mods[100], temp_mod, temp_exp, mod_base,a,ptr=1;
+	if(number<4) return 1;
+	else
+	{
+		temp_mod = (1l << (temp_exp = (unsigned)blogl(number,2)+1)) % number;
+		while (temp_mod>65535l)
+		{
+			temp_mod = (temp_mod << 1) % number;
+			temp_exp+=1;
+		}
+		mods[0] = temp_mod; exps[0] = temp_exp;
+		while(temp_exp<number>>1)
+		{
+			if (temp_mod == 1)
+			{
+				number %= temp_exp;
+				break;
+			}
+			a = (unsigned long)blogl(4294967295l, temp_mod);
+			temp_mod = (unsigned long)pow(temp_mod,a) % number;
+			temp_exp *= a;
+			while (temp_mod>65535l)
+			{
+				temp_mod = (temp_mod << 1) % number;
+				temp_exp+=1;
+			}
+			mods[ptr] = temp_mod; exps[ptr] = temp_exp;
+			//cout << exps[ptr] << ":" << mods[ptr] << "\n";
+			ptr++;
+		}
+		temp_mod = 1; temp_exp = number;
+		for(a=ptr-1;a!=0;a--)
+		{
+			while (temp_exp>=exps[a])
+			{
+				temp_mod = (temp_mod * mods[a]) % number;
+				temp_exp -= exps[a];
+			}
+			while ((temp_mod>65535l) && temp_exp)
+			{
+				temp_mod = (temp_mod << 1) % number;
+				temp_exp -=1;
+			}
+		}
+		for(a=0;a<temp_exp;a++)
+			temp_mod = (temp_mod << 1) % number;
+	}
+	return (temp_mod == 2);
+}
+
+void PrimeMap(unsigned int n, void * mp)
+{
+	unsigned int pr;
+	unsigned long muls;
+	for(pr=2;pr<n;pr++)
+		bwrite(mp,pr,1);
+	for(pr=2;pr<=(unsigned int)sqrt(n);pr++)
+		if (bread(mp,pr))
+			for (muls=pr*pr;muls<n;muls+=pr)
+				bwrite(mp,muls,0);
+}
+
+int a_d_v(unsigned n, unsigned max_,unsigned char * ea, unsigned long * max)
+{
+	if (n>=max_) return 0;
+	(*ea)++;
+	if ((*ea)>(*max))
+	{
+		*ea = 0;
+		return a_d_v (n+1,max_,ea+1,max+2);
+	}
+	return 1;
+}
+
+void getdividors(unsigned long number, unsigned long * diva)
+{
+	unsigned long mps[50], mnum=0,a,tot;
+	unsigned char which[35];
+	lgetmultipliers(number,mps,1);
+	while	(mps[mnum*2]) mnum++;
+	for (a=0;a<35;a++) which[a]=0;
+	do
+	{
+		tot=1;
+		for (a=0;a<mnum;a++)
+			tot *= (unsigned long)pow(mps[a*2],which[a]);
+		*diva = tot;
+		diva++;
+	} while (a_d_v(0,mnum,&(which[0]),&(mps[1])));
+	*diva=0;
+}
+
+int Npoly(unsigned int terms,unsigned exp,unsigned * combi)
+{
+	unsigned long sum=0;
+	for(unsigned a=0;a<terms;sum+=*(combi+a),a++) ;
+	if ((sum != exp) || (sum > 12))
+		return 0;
+	sum = factorial(exp);
+	for(a=0;a<terms;sum/=factorial(*(combi+a)),a++) ;
+	return sum;
+}
+
+#endif // CCALC_H
+
+// Stastical functions, templates and classes
+struct Stat_Info
+{
+	unsigned n;
+	double Sx, Sx2;
+	double mean, SD_entire, SD;
+};
+
+template <class T> void add_data(Stat_Info & stat, T * data, unsigned n)
+{
+	for(unsigned a=0;a<n;a++)
+	{
+		stat.Sx += (double)(*data);
+		stat.Sx2 += (double)(*data)*(double)(*data);
+		data++;
+	}
+	n = (stat.n+=n);
+	stat.mean = stat.Sx/n;
+	stat.SD_entire = sqrt((stat.Sx2-n*stat.mean*stat.mean)/n);
+	stat.SD = sqrt((stat.Sx2-n*stat.mean*stat.mean)/(n-1));
+}
+
+template <class T> void rem_data(Stat_Info & stat, T * data, unsigned n)
+{
+	for(unsigned a=0;a<n;a++)
+	{
+		stat.Sx -= (double)(*data);
+		stat.Sx2 -= (double)(*data)*(double)(*data);
+		data++;
+	}
+	n = (stat.n-=n);
+	stat.mean = stat.Sx/n;
+	stat.SD_entire = sqrt((stat.Sx2-n*stat.mean*stat.mean)/n);
+	stat.SD = sqrt((stat.Sx2-n*stat.mean*stat.mean)/(n-1));
+}
+
+template <class T> Stat_Info getStat(T * data, unsigned n)
+{
+	Stat_Info stat;
+	stat.n = 0;
+	stat.Sx = 0;stat.Sx2 = 0;
+	add_data(stat, data, n);
+	return stat;
+}
+
+struct Stat_InfoXY
+{
+	unsigned n;
+	double Sx, Sx2;
+	double meanx, SD_entirex, SDx;
+	double Sy, Sy2;
+	double meany, SD_entirey, SDy;
+	double Sxy;
+};
+
+template <class T> void add_dataXY(Stat_InfoXY & stat, T * data, unsigned n)
+{
+	for(unsigned a=0;a<n;a++)
+	{
+		stat.Sx += (double)(*data);
+		stat.Sx2 += (double)(*data)*(double)(*data);
+		data++;
+		stat.Sy += (double)(*data);
+		stat.Sy2 += (double)(*data)*(double)(*data);
+		stat.Sxy += (double)(*data)*(double)(*(data-1));
+		data++;
+	}
+	n = (stat.n+=n);
+	stat.meanx = stat.Sx/n;
+	stat.SD_entirex = sqrt((stat.Sx2-n*stat.meanx*stat.meanx)/n);
+	stat.SDx = sqrt((stat.Sx2-n*stat.meanx*stat.meanx)/(n-1));
+	stat.meany = stat.Sy/n;
+	stat.SD_entirey = sqrt((stat.Sy2-n*stat.meany*stat.meany)/n);
+	stat.SDy = sqrt((stat.Sy2-n*stat.meany*stat.meany)/(n-1));
+}
+
+template <class T> Stat_InfoXY getStatXY(T * data, unsigned n)
+{
+	Stat_InfoXY stat;
+	stat.n = 0;
+	stat.Sx = 0;stat.Sx2 = 0;stat.Sy = 0;stat.Sy2 = 0;stat.Sxy = 0;
+	add_dataXY(stat, data, n);
+	return stat;
+}
+
+template <class T> void rem_dataXY(Stat_InfoXY & stat, T * data, unsigned n)
+{
+	for(unsigned a=0;a<n;a++)
+	{
+		stat.Sx -= (double)(*data);
+		stat.Sx2 -= (double)(*data)*(double)(*data);
+		data++;
+		stat.Sy -= (double)(*data);
+		stat.Sy2 -= (double)(*data)*(double)(*data);
+		stat.Sxy -= (double)(*data)*(double)(*(data-1));
+		data++;
+	}
+	n = (stat.n-=n);
+	stat.meanx = stat.Sx/n;
+	stat.SD_entirex = sqrt((stat.Sx2-n*stat.meanx*stat.meanx)/n);
+	stat.SDx = sqrt((stat.Sx2-n*stat.meanx*stat.meanx)/(n-1));
+	stat.meany = stat.Sy/n;
+	stat.SD_entirey = sqrt((stat.Sy2-n*stat.meany*stat.meany)/n);
+	stat.SDy = sqrt((stat.Sy2-n*stat.meany*stat.meany)/(n-1));
+}
+
+void Fadd_dataXY(unsigned n, unsigned size, Stat_InfoXY * stat, void * vdata, double (*fX)(void *), double (*fY)(void *))
+{
+	double x, y; char * data = (char*)vdata;
+	for(unsigned a=0;a<n;a++)
+	{
+		x = (*fX)(data); y = (*fY)(data+size);
+		stat->Sx += x;
+		stat->Sx2 += x*x;
+		stat->Sy += y;
+		stat->Sy2 += y*y;
+		stat->Sxy += x*y;
+		data += size*2;
+	}
+	n = (stat->n+=n);
+	stat->meanx = stat->Sx/n;
+	stat->SD_entirex = sqrt((stat->Sx2-n*stat->meanx*stat->meanx)/n);
+	stat->SDx = sqrt((stat->Sx2-n*stat->meanx*stat->meanx)/(n-1));
+	stat->meany = stat->Sy/n;
+	stat->SD_entirey = sqrt((stat->Sy2-n*stat->meany*stat->meany)/n);
+	stat->SDy = sqrt((stat->Sy2-n*stat->meany*stat->meany)/(n-1));
+}
+
+Stat_InfoXY FgetStatXY(unsigned n, unsigned size, void * data, double (*fX)(void *), double (*fY)(void *))
+{
+	Stat_InfoXY stat;
+	stat.n = 0;
+	stat.Sx = 0;stat.Sx2 = 0;stat.Sy = 0;stat.Sy2 = 0;stat.Sxy = 0;
+	Fadd_dataXY(n,size,&stat,data,fX,fY);
+	return stat;
+}
+
+void Frem_dataXY(unsigned n, unsigned size, Stat_InfoXY * stat, void * vdata, double (*fX)(void *), double (*fY)(void *))
+{
+	double x, y; char * data = (char*)vdata;
+	for(unsigned a=0;a<n;a++)
+	{
+		x = (*fX)(data); y = (*fY)(data+size);
+		stat->Sx -= x;
+		stat->Sx2 -= x*x;
+		stat->Sy -= y;
+		stat->Sy2 -= y*y;
+		stat->Sxy -= x*y;
+		data += size*2;
+	}
+	n = (stat->n-=n);
+	stat->meanx = stat->Sx/n;
+	stat->SD_entirex = sqrt((stat->Sx2-n*stat->meanx*stat->meanx)/n);
+	stat->SDx = sqrt((stat->Sx2-n*stat->meanx*stat->meanx)/(n-1));
+	stat->meany = stat->Sy/n;
+	stat->SD_entirey = sqrt((stat->Sy2-n*stat->meany*stat->meany)/n);
+	stat->SDy = sqrt((stat->Sy2-n*stat->meany*stat->meany)/(n-1));
+}
+
+struct RgrsInfo
+{
+	double a, b, r;
+	double estY(double X) {return a+b*X;}
+	double estX(double Y) {return (Y-a)/b;}
+	double devi_perc(double X, double Y) {return abs((Y-estY(X))/estY(X))*100;}
+};
+
+RgrsInfo regress(Stat_InfoXY i)
+{
+	RgrsInfo rgrs;
+	rgrs.a = (i.Sy*i.Sx2-i.Sx*i.Sxy)/(i.n*i.Sx2-i.Sx*i.Sx);
+	rgrs.b = (i.n*i.Sxy-i.Sx*i.Sy)/(i.n*i.Sx2-i.Sx*i.Sx);
+	rgrs.r = (i.n*i.Sxy-i.Sx*i.Sy)/sqrt((i.n*i.Sx2-i.Sx*i.Sx)*(i.n*i.Sy2-i.Sy*i.Sy));
+	return rgrs;
+}
+
+typedef double tt;
+double LMS_nochange(void * p) {return (double)(*(tt*)p);}
+double LMS_ln(void * p) {return log((*(tt*)p));}
+double LMS_reci(void * p) {return 1/(double)(*(tt*)p);}
+#define LINEAR_LMS 	&LMS_nochange, &LMS_nochange
+#define EXPO_LMS 		&LMS_nochange, &LMS_ln
+#define LOG_LMS 		&LMS_ln, &LMS_nochange
+#define POWER_LMS 	&LMS_ln, &LMS_ln
+#define INVERSE_LMS 	&LMS_reci, &LMS_nochange
+
+template <class N> double getgeomean(N * data, unsigned n)
+{
+	double logtot=0;
+	for(unsigned a=0;a<n;a++)
+	{
+		if (data[a]==0)
+			return 0;
+		else
+			logtot+=log(fabs(data[a]));
+	}
+	return exp(logtot/n);
+}
+
+
+/*int main()
+{
+	long double data[200], inx, iny;
+	unsigned n, NMAX = 7;
+	cout << "Enter the values x,y (one by one) - ";
+	for(n=0;n<NMAX;n++)
+	{
+		cin >> inx;
+		data[n] = inx;
+	}
+	cout.precision(13);
+	cout << "The geometric mean of the numbers is " << getgeomean(data,n);
+	_AX = 1; asm int 0x16;
+	return 0;
+}
+
+/*unsigned long s[500],a=0,number;
+	while (_exit != 'n')
+	{
+	cout << "Please enter a number- ";
+	cin >> number;
+	getdividors(number,s);a=0;
+	while (s[a])
+{		cout<<s[a]<<" ";a++;}
+	cout << "\nWould you like to do it again? ";
+	cin >> _exit;
+	}*/

t2/open-source/nostalgia/progs/cdd.cpp

+#include <dir.h>
+#include <stdio.h>
+
+int main(int argc, char * argv[])
+{
+	if (argc != 2) // wrong number of arguments
+		puts("Wrong number of arguments for CDD!\nType CDD h for help on how to use CDD.");
+	else if (((*argv[1] == 'h') || (*argv[1] == 'H') || (*argv[1] == '?')))// || ((*argv[1] == '/') && ((*argv[1]+1 == 'h') || (*argv[1]+1 == 'H') || (*argv[1]+1 == '?')))
+	{
+		puts("CDD (Change Drive And/Or Directory).\n"
+		"Syntex: CDD <directory name>\n"
+		"<directory name> - the name of the directory (may include drive name in the beginning)\n\n"
+		"Uncopyrighted, 1993 - MCMLXIII, Shlomi Fish.");
+	}
+	else // Directory/Drive change
+	{
+		if (*(argv[1]+1) == ':')   //drive change
+			setdisk(*argv[1]-((*argv[1]<93) ? 65 : 97)); //letter to number
+		if (*(argv[1]+2) && chdir(argv[1])) // directory change (in chdir);
+			puts("Invalid directory!");
+	}
+	return 0;
+}

t2/open-source/nostalgia/progs/cpcx.cpp

+#include <graphics.h>
+#include <stdio.h>
+#include <iostream.h>
+#include <vgapalet.c>
+#include <math.h>
+#include <dos.h>
+
+int return0() {return 0;}
+
+struct PCX_FILE
+{
+	FILE * file_ptr;
+	int Type;
+	unsigned Xlen, Ylen, BytesPerLine;
+	char * pallete;
+};
+
+enum Graphics_File_Type {
+	G_2 = 0,
+	G_BandW = G_2,
+	G_BlackandWhite = G_2,
+	G_4 = 1,
+	G_CGA = G_4,
+	G_16 = 2,
+	G_EGA = G_16,
+	G_256 = 3,
+	G_VGA = G_256,
+	G_24Bit = 4,
+	G_TrueColor = G_24Bit,
+	G_UNKNOWN = 100,
+	G_ERROR = 200
+};
+
+/*int TypeHeader (char * name)
+{
+	char header[128];
+	int handle = open(name,O_RDONLY|O_BINARY);
+	read(handle,(void*)header,128);
+	cout << "\n" << name << ": \n";
+	if(header[0] == 10) cout << "Is a PCX file.\n";
+	else cout << "Is not a PCX file.\n";
+	if(header[2] != 1) cout << "The file is encoded!\n";
+	cout << "Version: ";
+	switch(header[1])
+	{
+		case 0 : cout << "2.5\n";break;
+		case 2 : cout << "2.8 (with pallete)\n";break;
+		case 3 : cout << "2.8 (without pallete)\n";break;
+		case 5 : cout << "3.0\n";break;
+		default : cout << "Unknown Version!\n";
+	};
+	cout << "There are " << (int)header[3] << " bits per pixel.\n";
+	cout << "Size :" << *((int*)(&header[8]))-*((int*)(&header[4]))+1 << "*" << *((int*)(&header[10]))-*((int*)(&header[6]))+1 << '\n';
+	cout << "There are " << *((int*)(&header[66])) << "Bytes per Line.\n";
+	cout << "There are " << (int)header[65] << " planes.\n";
+	if (header[68]==1) cout << "The image is color or black&white.\n";
+	else cout << "This is a grayscale image.\n";
+	close(handle);
+	return 0;
+}*/
+
+PCX_FILE PCX_ReadHeader (FILE * f, char * palette)
+{
+	PCX_FILE pcx;
+	char header[128];
+	int a, ver, bits_per_pix, nplanes;
+	pcx.file_ptr = f;
+	fseek(f,0,SEEK_SET);
+	fread((void*)header,128,1,f);
+	if ((header[0] != 10)||(header[2]!=1))
+	{
+		pcx.Type = G_ERROR;
+	}
+	else
+	{
+		ver = header[1];
+		bits_per_pix = (int)header[3];
+		pcx.Xlen = *((unsigned*)(&header[8]))-*((unsigned*)(&header[4]))+1;
+		pcx.Ylen = *((unsigned*)(&header[10]))-*((unsigned*)(&header[6]))+1;
+		pcx.BytesPerLine = *((unsigned*)(&header[66]));
+		nplanes = (int)header[65];
+		switch(bits_per_pix)
+		{
+			case 1 :
+			switch(nplanes)
+			{
+				case 1 : pcx.Type = G_BlackandWhite;break;
+				case 4 : pcx.Type = G_EGA;
+				for(a=0;a<48;a++)
+					palette[a] = header[16+a]>>2;
+				break;
+				default : pcx.Type = G_UNKNOWN;
+			}
+			break;
+			case 2 :
+			if (nplanes == 1)
+			{
+				pcx.Type = G_CGA;
+				palette[0] = header[19]>>5;
+				palette[1] = header[16]>>4;
+			}
+			else
+				pcx.Type = G_UNKNOWN;
+			break;
+			case 8 :
+			switch(nplanes)
+			{
+				case 1 : pcx.Type = G_VGA;
+				fseek(f,-769,SEEK_END);
+				if ((getc(f) != 12)||(ver!=5))
+					pcx.Type = G_UNKNOWN;
+				else
+					for(a=0;a<768;a++)
+						palette[a] = getc(f)>>2;
+				break;
+				case 3 : pcx.Type = G_24Bit;break;
+				default : pcx.Type = G_UNKNOWN;
+			}
+			break;
+			default:
+			pcx.Type = G_UNKNOWN;
+		}
+	}
+	return pcx;
+}
+
+/* Functions to read and write bits or byte-quarters (two bit chunks)
+
+*/
+
+void bwrite(unsigned char * c, unsigned place, unsigned value)
+{
+	if (value) *c |= 1 << place;
+	else *c &= 255 - (1 << place);
+}
+
+unsigned int bread(unsigned char c, unsigned int place)
+{
+	return (c & (1<<place))>>place;
+}
+
+void qwrite(unsigned char * c, unsigned place, unsigned value)
+{
+	bwrite(c,place<<1,value-(value>>2)*2);
+	bwrite(c,place<<1+1,value>>2);
+}
+
+unsigned int qread(unsigned char c, unsigned int place)
+{
+	return (c & (3<<(place<<1)))>>(place<<1);
+}
+
+void put24bit(int x, int y, int r, int g, int b)
+{
+	x+=y;r+=g;b++;
+}
+
+char palinfo[256][3];
+#define G_PIXEL_2(x, y, col)			putpixel(x,y,col)
+#define G_PIXEL_4(x, y, col)			putpixel(x,y,col)
+#define G_PIXEL_16(x, y, col)			putpixel(x,y,col)
+#define G_PIXEL_256(x, y, col)		putpixel(x,y,col)
+#define G_PIXEL_24Bit(x,y,r,g,b)		rgbput(x,y,r>>2,g>>2,b>>2)
+
+void rgbput(int x, int y, int r, int g, int b)
+{
+	unsigned dmin=800, clos_col,d;
+	for(unsigned a=0;a<256;a++)
+	{
+		d=abs(palinfo[a][0]-r)+abs(palinfo[a][1]-g)+abs(palinfo[a][2]-b);
+		if (d<dmin)
+		{
+			clos_col = a;dmin = d;
+		}
+	}
+	putpixel(x,y,clos_col);
+}
+
+
+enum Graphics_Target {
+	G_Screen = 0,
+	G_Buffer = 1,
+	G_Both = 2
+};
+
+
+
+int PCX_GetImage(PCX_FILE pcx, int xpos, int ypos, char * buf, int target, int whole_bytes)
+{
+	unsigned x=0, y=0, bytesnum=0, pcnt, pbyt, a,b, col, p;
+	int i;
+	FILE * f = pcx.file_ptr;
+	fseek(f,128,SEEK_SET);
+	switch(pcx.Type)
+	{
+		case G_BlackandWhite :
+		for(y=0;y<pcx.Ylen;y++)
+		{
+			while (bytesnum<pcx.BytesPerLine)
+			{
+				pcnt = 1;     /* safety play */
+				if(EOF==(i=getc(f)))
+					break;
+				if(0xc0 == (0xc0 & i))
+				{
+					pcnt = 0x3f&i;
+					if(EOF == (i=getc(f)))
+						return(EOF);
+				}
+				pbyt = i;
+				for(a=0;a<pcnt;a++)
+					buf[bytesnum++] = pbyt;
+			}
+			if (target%2==0)
+				for(x=0;x<pcx.Xlen;x++)
+					G_PIXEL_2(x+xpos,y+ypos,bread(buf[x>>3],7-x%8)*30);
+			if (target>1)
+				buf += x>>3+(x%8!=0);
+			bytesnum = 0;//x=0;
+		}
+		break;
+		case G_CGA :
+		for(y=0;y<pcx.Ylen;y++)
+		{
+			while (bytesnum<pcx.BytesPerLine)
+			{
+				pcnt = 1;     /* safety play */
+				if(EOF==(i=getc(f)))
+					break;
+				if(0xc0 == (0xc0 & i))
+				{
+					pcnt = 0x3f&i;
+					if(EOF == (i=getc(f)))
+						return(EOF);
+				}
+				pbyt = i;
+				for(a=0;a<pcnt;a++)
+					buf[bytesnum++] = pbyt;
+			}
+			if (target%2==0)
+				for(x=0;x<pcx.Xlen;x++)
+					G_PIXEL_4(x+xpos,y+ypos,qread(buf[x>>2],3-x%4));
+			if (target > 1)
+				buf += x>>2 + (x%4!=0);
+			bytesnum = 0;//x=0;
+		}
+		break;
+		case G_EGA:
+		for(y=0;y<pcx.Ylen;y++)
+		{
+			for(p=0;p<4;p++)
+			{
+				while (bytesnum<pcx.BytesPerLine*4)
+				{
+					pcnt = 1;     /* safety play */
+					if(EOF==(i=getc(f)))
+						break;
+					if(0xc0 == (0xc0 & i))
+					{
+						pcnt = 0x3f&i;
+						if(EOF == (i=getc(f)))
+							return(EOF);
+					}
+					pbyt = i;
+					for(a=0;a<pcnt;a++)
+						for(b=0;b<8;b++)
+						{
+							bwrite(buf+bytesnum,4*(b%2)+p,bread(pbyt,7-b));
+							if (b%2) bytesnum++;
+						}
+				}
+				bytesnum=0;
+			}
+			if (target%2==0)
+				for(x=0;x<pcx.Xlen;x++)
+					G_PIXEL_16(x+xpos,y+ypos,(x%2)?((buf[x>>1]&240)>>4):(buf[x>>1]&15));
+			if (target>1)
+				buf += x>>1+(x%2==1);
+			bytesnum = 0;//x=0;
+		}
+		break;
+		case G_VGA:
+		for(y=0;y<pcx.Ylen;y++)
+		{
+			while (bytesnum<pcx.BytesPerLine)
+			{
+				pcnt = 1;     /* safety play */
+				if(EOF==(i=getc(f)))
+					break;
+				if(0xc0 == (0xc0 & i))
+				{
+					pcnt = 0x3f&i;
+					if(EOF == (i=getc(f)))
+						return(EOF);
+				}
+				pbyt = i;
+				for(a=0;a<pcnt;a++)
+					buf[bytesnum++] = pbyt;
+			}
+			if (pcnt==1)
+			{
+				sound(440);delay(100);nosound();
+			}
+			getch();
+			if(target%2==0)
+				for(x=0;x<pcx.Xlen;x++)
+					G_PIXEL_256(x+xpos,y+ypos,buf[x]);
+			if(target>1)
+				buf+=x;
+			bytesnum = 0;//x=0;
+		}
+		break;
+		case G_24Bit:
+		for(y=0;y<pcx.Ylen;y++)
+		{
+			for(p=0;p<3;p++)
+			{
+				bytesnum=p;
+				while (bytesnum<pcx.BytesPerLine)
+				{
+					pcnt = 1;     /* safety play */
+					if(EOF==(i=getc(f)))
+						break;
+					if(0xc0 == (0xc0 & i))
+					{
+						pcnt = 0x3f&i;
+						if(EOF == (i=getc(f)))
+							return(EOF);
+					}
+					pbyt = i;
+					for(a=0;a<pcnt;a++)
+						buf[(bytesnum+=3)-3] = pbyt;
+				}
+			}
+			if(target%2==0)
+				for(x=0;x<pcx.Xlen;x++)
+					G_PIXEL_24Bit(x+xpos,y+ypos,buf[x*3],buf[x*3+1],buf[x*3+2]);
+			if(target>1)
+				buf+=x*3;
+			bytesnum = 0;//x=0;
+		}
+		default:
+		return 0;
+	}
+	return 1;
+}
+
+void pcx_reverse(PCX_FILE pcx, unsigned char * buf)
+{
+	unsigned byte,line,part,width;
+	unsigned char temp;
+	switch(pcx.Type)
+	{
+		case G_BlackandWhite:
+		width = pcx.Xlen>>3+(pcx.Xlen%8!=0);
+		for(line=0;line<pcx.Ylen;line++)
+			for(byte=0;byte<width;byte++)
+				for(part=0;part<4;part++)
+				{
+					temp = bread(buf[line*width+byte],part);
+					bwrite(*buf+(line*width+byte),part,bread(buf[line*width+byte],7-part));
+					bwrite(*buf+(line*width+byte),7-part,temp);
+				}
+		break;
+		case G_CGA:
+		width = pcx.Xlen>>2+(pcx.Xlen%4!=0);
+		for(line=0;line<pcx.Ylen;line++)
+			for(byte=0;byte<width;byte++)
+				for(part=0;part<2;part++)
+				{
+					temp = qread(buf[line*width+byte],part);
+					qwrite(*buf+(line*width+byte),part,bread(buf[line*width+byte],3-part));
+					qwrite(*buf+(line*width+byte),3-part,temp);
+				}
+		break;
+		case G_EGA:
+		width = pcx.Xlen>>1+pcx.Xlen%2;
+		for(line=0;line<pcx.Ylen;line++)
+			for(byte=0;byte<width;byte++)
+				buf[line*width+byte]= (buf[line*width+byte]&0xf)>>4+(buf[line*width+byte]&0xf0)<<4;
+}
+
+int main()
+{
+	FILE * f;
+	PCX_FILE pcx;
+	char name[30], buf[1000];
+	int gi=installuserdriver("Svga256",return0), gm = SVGA640x400x256,a,b,c;
+	do {
+		cin >> name;
+		f = fopen(name,"rb");
+		pcx = PCX_ReadHeader(f, &palinfo[0][0]);
+		initgraph(&gi,&gm,"c:\\tc\\bgi");
+		setvgapalette256(&palinfo);
+		PCX_GetImage(pcx,0,0,buf,G_Screen,0);
+		_AX = 1; asm int 0x16;
+		closegraph();
+	} while (name[0]!='~');
+	return 0;
+}

t2/open-source/nostalgia/progs/cpcx.h

+/*
+	CPCX.H
+		This header along with CPCX.LIB enables the programmer to put PCX
+		images on screen and/or store them in memory.
+	Programmed By Shlomi Fish, Tel-Aviv, Israel.
+	Finishing Date:
+		July 19th, 1994 - �"���� ��� '��
+
+	Note:
+	Due to technical problems I was not able to check if the 24 bit image
+	presentation works properly. If you find any bugs in it please contact
+	me at: 03-6424668 (Israel) or ila2027@datasrv.co.il (Internet address) and
+	I will try to fix it.
+
+	Coming Soon (Hopefully):
+	CBMP, CGIF, CTIFF.
+	And following - headers to encode into those popular graphics formats!
+	Stay tuned...
+*/
+
+#ifndef __CPCX_H
+#define __CPCX_H
+#endif
+#idndef __STDIO_H
+#include <stdio.h>
+#endif
+
+/*
+	A structure containing the information about the pcx file:
+	file_ptr - pointer to the file stream.
+	Type - The type of the image (monochrome, 16 colors, 256 colors, etc.).
+	Xlen - The width (in pixels) ; Ylen - The height (in pixels).
+	BytesPerLine - The bytes required to store one line of image in one plane.
+	pallete - pointer to the palette information. (Isn't used by the function PCX_GetImage)
+*/
+struct PCX_FILE
+{
+	FILE * file_ptr;
+	int Type;
+	unsigned Xlen, Ylen, BytesPerLine;
+	unsigned char * palette;
+};
+
+/*
+	Enumeration for PCX_FILE.Type:
+	Monochrome - G_2 or G_BandW or G_BlackandWhite
+	4 colors CGA - G_4 or G_CGA
+	16 colors EGA - G_16 or G_EGA
+	256 colors VGA - G_256 or G_VGA
+	24 Bit Image (16.8 Million colors) - G_24Bit or G_TrueColor
+	an Unknown Image type - G_UNKNOWN
+	Error reading image - G_ERROR
+*/
+
+enum Graphics_File_Type {
+	G_2 = 0,
+	G_BandW = G_2,
+	G_BlackandWhite = G_2,
+	G_4 = 1,
+	G_CGA = G_4,
+	G_16 = 2,
+	G_EGA = G_16,
+	G_256 = 3,
+	G_VGA = G_256,
+	G_24Bit = 4,
+	G_TrueColor = G_24Bit,
+	G_UNKNOWN = 100,
+	G_ERROR = 200
+};
+
+/*
+  Enumeration for the graphics target wanted(screen, memory buffer or both)
+*/
+enum Graphics_Target {
+	G_Screen = 0,
+	G_Buffer = 1,
+	G_Both = 2
+};
+
+/*
+	Enumeration for the variables EGA_RGB_CON and VGA_RGB_CON:
+	G_EGA_Reg_CON - Regular EGA 2 bit values.
+	G_Borland_CON - For use with setrgbpalette - 4 bit values.
+	G_BIOS_CON - The BIOS form which has 6 bit values, used to define VGA colors.
+	G_TrueColor_CON - For 24 Bit scrrens that present EGA or VGA bitmaps.
+*/
+enum RGB_CON_TYPE {
+	G_EGA_Reg_CON = 6,
+	G_Borland_CON = 4,
+	G_BIOS_CON = 2,
+	G_TrueColor_CON = 0
+}
+
+unsigned EGA_RGB_CON=G_BIOS_CON;
+unsigned VGA_RGB_CON=G_BIOS_CON;
+
+
+
+/* The main functions */
+
+struct PCX_FILE PCX_ReadHeader (FILE * f, unsigned char * palette);
+int PCX_GetImage(struct PCX_FILE pcx, int xpos, int ypos, unsigned char * buf, int target);
+
+/*
+	User-defined macros for presenting the image on screen
+*/
+#define G_PIXEL_2(x, y, col)        putpixel(x,y,col)
+#define G_PIXEL_4(x, y, col)        putpixel(x,y,col)
+#define G_PIXEL_16(x, y, col)       putpixel(x,y,col)
+#define G_PIXEL_256(x, y, col)      putpixel(x,y,col)
+#define G_PIXEL_24Bit(x,y,r,g,b)    putpixel(x,y,r+g+b)
+
+/*
+	Assistant functions for reading and writing bits or quarters of a byte (two bits chunks).
+*/
+
+void bwrite(unsigned char * c, unsigned place, unsigned value);
+unsigned int bread(unsigned char c, unsigned int place);
+void qwrite(unsigned char * c, unsigned place, unsigned value);
+unsigned int qread(unsigned char c, unsigned int place);