use strict; use warnings; use POSIX; use constant kIntervals => 10.0; my @rawData; my $tmin; my $tmax; my $secPerDay = 60 * 60 * 24; for () { chomp; next unless m{^\s*([\d/]+)\s+([\d.]+)}; my ($m, $d, $y) = split /\//, $1; my $weight = $2; my $date = POSIX::mktime(0, 0, 0, $d, $m - 1, $y - 1900); $tmin = $date if ! $tmin; $date -= $tmin; $tmax = $date /= $secPerDay; push @rawData, [$date, $weight]; } my ($wmax, $wmin) = ($rawData[0][1], $rawData[-1][1]); my $interval = $tmax / kIntervals; my $wcalc = $wmax; my $wgone; my @data; for my $point (0 .. kIntervals) { my $epoch = $point * $interval; shift @rawData while @rawData > 1 && $rawData[1][0] < $epoch; last if ! @rawData; if (@rawData == 1) { push @data, [$epoch, $rawData[0][1]]; last; } my $m = $rawData[0][1]; my $s = ($rawData[1][1] - $rawData[0][1]) / ($rawData[1][0] - $rawData[0][0]); push @data, [$epoch, $m + $s * ($epoch - $rawData[0][0])]; } printf "%d\t%5.1f\n", $_->[0], $_->[1] for @data; __DATA__ 6/26/2010 334 8/12/2010 311.8 8/19/2010 308.4 9/5/2010 300.0 9/9/2010 298.6 9/14/2010 297.2 9/16/2010 293.6 #### 0 334.0 8 330.1 16 326.3 24 322.4 32 318.5 41 314.6 49 310.7 57 306.7 65 302.7 73 299.0 82 293.6