Averages/Mean time of day: Difference between revisions

→‎{{header|Perl}}: replaced algorithm that only gave approximate answer
No edit summary
(→‎{{header|Perl}}: replaced algorithm that only gave approximate answer)
Line 1,327:
 
=={{header|Perl}}==
Using the core module <code>Math::Complex</code> to enable use of complex numbers. The <code>POSIX</code> CPAN module provides the <code>fmod</code> routine for non-integer modulus calculations.
<lang Perl>use Const::Fast;
{{trans|Perl 6}}
const my $SECONDS_IN_HOUR => 60 * 60;
<lang Perl>use Const::FastPOSIX 'fmod';
const my $SECONDS_IN_MINUTE => 60;
use Math::Complex;
use List::Util qw(sum);
use utf8;
 
use constant τ => 2 * 3.1415926535;
sub hms_2_seconds {
 
my ( $hms ) = @_;
# time-of-day to radians
my ( $h, $m, $s ) = split /:/, $hms;
sub tod2rad {
$h += 24 if $h < 12;
my ( $h, $m, $s ) = split /:/, $hms@_[0];
return $s + $m * $SECONDS_IN_MINUTE + $h * $SECONDS_IN_HOUR;
(3600*$h + 60*$m + $s) * τ / 86400;
}
sub seconds_2_hms {
my ( $seconds ) = @_;
 
# radians to time-of-day
my ( $h, $m );
sub rad2tod {
my $x = $_[0] * 86400 / τ;
sprintf '%02d:%02d:%02d', fm($x/3600,24), fm($x/60,60), fm($x,60);
 
# float modulus, normalized to positive values
$h = int( $seconds / $SECONDS_IN_HOUR );
sub fm {
$seconds = $seconds % $SECONDS_IN_HOUR;
my ( $hms n,$b) = @_;
 
$mx = intfmod( $seconds / n,$SECONDS_IN_MINUTE b);
$secondsx += $secondsb %if $SECONDS_IN_MINUTEx < 0;
 
return sprintf "%02s:%02s:%02s", $h, $m, $seconds;
}
 
sub phase { arg($_[0]) } # aka theta
my @hms = split /,\s+/, scalar <STDIN>;
sub cis { cos($_[0]) + i*sin($_[0]) }
 
sub mean_time { rad2tod phase sum map { cis tod2rad $_ } @_ }
my ($sum, $count);
for my $time ( @hms) {
$sum += hms_2_seconds $time;
$count++;
say seconds_2_hms int( $sum / $count );</lang>
 
$@times echo= ("23:00:17", "23:40:20", "00:12:45", "00:17:19 | mean_time.pl");
print mean_time(@times) . " is the mean time of " . join(' ', @times) . "\n";</lang>
{{out}}
<pre>23:47:43 is the mean time of 23:00:17 23:40:20 00:12:45 00:17:19</pre>
<pre>
$ echo 23:00:17, 23:40:20, 00:12:45, 00:17:19 | mean_time.pl
23:47:40
</pre>
 
=={{header|Perl 6}}==
2,392

edits