program analysis;
{
	This program calculates all available station derivatives each
	year and their average to estimate the global derivative.

	First the program reads in the lines of GYA.txt, the yearly
	averages for all station. It sorts these in order of station and
	year. It turns out that our data file was pre-sorted.

	We reject the last urbanization_period years of measurements from
	all stations that disappear from the record in an effort to remove
	the effect of urban heating from our trend.
}

const
	max_num_measurements=1000000;
	urbanization_period=20;{years before disappearance}
	urbanization_start=1950;
	urbanization_end=2008;
	first_year=1800;
	last_year=2008;

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;
	measurement_num,num_measurements,y,counter:integer;
	t,sum:real;
	sorted: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 measurement_num:=1 to num_measurements-1 do begin
			if (measurements[measurement_num].id > measurements[measurement_num+1].id)
										or
				((measurements[measurement_num].id = measurements[measurement_num+1].id)
										and
				(measurements[measurement_num].year > measurements[measurement_num+1].year) )
									then begin
					swap(measurement_num,measurement_num+1);
					sorted:=false;
			end;
		end;
	end;
	
	writeln('Mark measurements from the urbanization_period years.');
	measurement_num:=1;
	while measurement_num <= num_measurements do begin
		id:=measurements[measurement_num].id;
		num:=measurement_num;
		while measurements[num].id=id do begin
			last_available_year:=measurements[num].year;
			inc(num);
		end;

		first_available_year:=measurements[measurement_num].year;

		while (measurement_num <= num_measurements) 
				and (measurements[measurement_num].id=id) do begin
			measurements[measurement_num].include:=
				(first_available_year>urbanization_start)
								or
				(measurements[measurement_num].year<=last_available_year-urbanization_period);
			inc(measurement_num);
		end;
	end;

	writeln('Calculate and mark all valid derivatives...');	
	measurements[1].derivative_valid:=false;
	for measurement_num:=2 to num_measurements do begin
		if ((measurements[measurement_num].id = measurements[measurement_num-1].id)
										and
		(measurements[measurement_num].year - 1 = measurements[measurement_num-1].year) )
										and
					measurements[measurement_num].include
									then begin
			measurements[measurement_num].derivative_valid:=true;
			measurements[measurement_num].derivative:=
				measurements[measurement_num].temperature
				- measurements[measurement_num-1].temperature;
		end else begin
			measurements[measurement_num].derivative_valid:=false;
			measurements[measurement_num].derivative:=-999;
		end;
{		with measurements[measurement_num] do writeln(id:1,' ',year:1,' ',derivative:10:6);}
	end;

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