program analysis;
{
	Generate an surface temperature trend from a subset of the available
	weather stations. We calculate the trend using our method of integerate
	derivatives, which is to take the average change in temperature across all
	selected stations each year, and take this as the change in global 
	temperature for that year. The trend is the integral of these changes.

	The program reads in the lines of GYA.txt, which contains the yearly
	averages for all station. It sorts these in order of station and
	year using an bubble sort, which is inefficient, but the table is pre-
	sorted anyway.
	
	Each line in the station datbase contains three fields: station identifier,
	year, and average temperature.
	
	The code supports various selection criteria. In this version, we select
	only those stations that provide continuous records from 1960 to 2000.
}

const
	max_num_measurements=1000000;
	period_start=1960;
	period_end=2000;
	first_year=1800;
	last_year=2007;

type
	measurement_type=record
		id:longint;{station identifier}
		year:integer;{year of the measurement}
		temperature:real;{year-long average}
		derivative_valid:boolean;{valid if last year's measurement exists}
		derivative:real;{change from last year}
		include:boolean;
	end;
	
var
	data:text;{the data file}
	measurements:array [1..max_num_measurements] of measurement_type;
	m,mm,num_measurements,y,counter:integer;
	t,sum:real;
	sorted,include:boolean;
	first_available_year,last_available_year:integer;
	id:longint;
	num:integer;
	
procedure swap(p,q:integer);

var
	m:measurement_type;
	
begin
	m:=measurements[p];
	measurements[p]:=measurements[q];
	measurements[q]:=m;
end;

begin
	writeln('Read GYA.txt...');
	reset(data,'GYA.txt');
	num_measurements:=0;
	while not eof(data) do begin
		inc(num_measurements);
		with measurements[num_measurements] do begin
			readln(data,id,year,temperature);
		end;
	end;
	close(data);

	writeln('Sort measurements by station and year...');
	sorted:=false;
	while not sorted do begin
		sorted:=true;
		for m:=1 to num_measurements-1 do begin
			if (measurements[m].id > measurements[m+1].id)
										or
				((measurements[m].id = measurements[m+1].id)
										and
				(measurements[m].year > measurements[m+1].year) )
									then begin
					swap(m,m+1);
					sorted:=false;
			end;
		end;
	end;
	
	writeln('Select stations continuous from ',period_start:1,' to ',period_end:1,'...');
	m:=1;
	while m<=num_measurements do begin
		include:=true;
		id:=measurements[m].id;
		first_available_year:=measurements[m].year;
		last_available_year:=measurements[m].year;
		measurements[m].derivative_valid:=false;

		if first_available_year>period_start then 
			include:=false
		else begin	
			mm:=m;
			while (mm+1<=num_measurements) and (measurements[mm+1].id=id) do begin
				inc(mm);
				if (measurements[mm].year<>measurements[mm-1].year+1) then begin
					include:=false;
					measurements[mm].derivative_valid:=false;
				end else begin
					measurements[mm].derivative_valid:=true;
					measurements[mm].derivative:=
						measurements[mm].temperature-measurements[mm-1].temperature;
				end;
				last_available_year:=measurements[mm].year;
			end;
			if last_available_year<period_end then include:=false;
		end;
		
		while (m<=num_measurements) and (measurements[m].id=id) do begin
			measurements[m].include:=include;
			inc(m);
		end;
	end;

	writeln('Calculate average derivative for each year...');
	for y:=first_year to last_year do begin
		sum:=0;
		counter:=0;
		for m:=1 to num_measurements do
			with measurements[m] do
				if (year=y) and derivative_valid and include then begin
					sum:=sum+derivative;
					inc(counter);
				end;
		if counter>0 then 
			writeln(y:1,' ',sum/counter:10:6,' ',counter:1)
		else
			writeln(y:1,' 0 0');
	end;
end.
