#!/usr/bin/perl -w
use strict;
use v5.10;
use threads;
use threads::shared;
use Fcntl "SEEK_SET";
use Math::BigFloat qw();
$| = 1;
my $off = tell DATA;
my $a :shared;
my $b :shared;
while (<DATA>) {
s/[\r\n]//g;
($a, $b) = ($_, $_ + 1);
last if (eof DATA);
$off = tell DATA;
seek DATA, $off, SEEK_SET;
my $c = Math::BigFloat->new($a * $a + $b * $b)->bsqrt->dparts();
say "a: $a, b: $b, c: $c, Δ: " . (100 / $c) . "%";
}
say "resuming from a: $a, b: $b...";
close DATA;
sub progress () {
$SIG{TERM} = $SIG{INT} = sub { threads->exit(); };
for (;;) {
select '', '', '', 0.5;
print "a: $a, b: $b\e[K\r";
}
}
my $thread = async \&progress;
open my $data, '+<', $0;
$SIG{TERM} = $SIG{INT} = $SIG{__DIE__} = sub {
say "\nreaping progress reporting thread";
$thread->kill('INT');
$thread->join();
say "saving resume point $a";
$off = tell $data;
say $data "$a";
close $data;
say "goodbye.";
exit;
};
seek $data, $off, SEEK_SET if ($off);
for (;; $a++, $b++) {
my ($c, $frac) = Math::BigFloat->new($a * $a + $b * $b)->bsqrt()->dparts();
if ($frac eq "0") {
say "a: $a, b: $b, c: $c, Δ: " . (100 / $c) . "%\e[K";
say $data "$a";
}
}
$thread->kill('INT');
$thread->join();
__DATA__
3
20
119
696
4059
23660
137903
803760
4684659
27304196
159140519
163810330