} elsif (m/^want$/) {
parse_info(1,0,0, @want, 'want');
} elsif (m/^price$/) {
- parse_info(0,1e6,0, @price, 'price');
+ parse_info(0,1e7,0, @price, 'price');
} else {
badusage("unknown information argument \`$_'");
}
sub valid ($) {
my ($x) = @_;
- defined $x and $x>0 and $x<1e4;
+ defined $x and $x and $x<1e5;
}
sub prvff ($$\@$) {
my ($k,$v) = @_;
printf "%-20s %s\n", "$k:", $v;
}
+sub fmt_stock_index ($) {
+ my ($si) = @_;
+ @have==1 ? '' : ' #'.$si;
+}
+sub rum_total (\@) {
+ my ($rums) = @_;
+ my $total= 0;
+ foreach my $i (qw(0 1 2)) {
+ $total += $rums->[$i] * $proofs[$i] / 100;
+ }
+ return $total;
+}
our @norm_price;
our ($best, $best_norm_price);
print "\n\n";
pr('prices', @price, 'poe ea.') if valid(@price);
pr('target stocks', @want, 'units') if valid(@want);
- my $i=0; for my $stocks (@have) {
- pr('actual stocks'.(@have==1 ? '' : ' #'.++$i),
+ my $si=0; for my $stocks (@have) {
+ pr('actual stocks'.fmt_stock_index(++$si),
@$stocks, 'units');
}
print "\n";
prf('equiv. ordering price', @perorder, 'poe/order');
$best= undef;
- my $best_norm_price= 1e5;
+ $best_norm_price= 1e6;
for my $i (qw(0 1 2)) {
next unless $price[$i];
$norm_price[$i] = $price[$i] * 100 / $proofs[$i];
print "\n";
}
+sub pr1s ($) {
+ my ($x) = @_;
+ if (valid($x)) {
+ printf ' %9.1f', $x;
+ } else {
+ printf " ";
+ }
+}
+
+sub compute_stock_values() {
+ return unless @have;
+ print <<END
+ Rum Rum Shot Shot total Profit Profit
+ equiv. value stocks value value this leg total
+END
+;
+
+ my $initial_value;
+ my $last_value;
+ my $si=0; for my $stocks (@have) {
+ my $stock_rum = rum_total(@$stocks);
+ my $rum_value= defined($best) ? $stock_rum * $best_norm_price : 0;
+ my $shot_value= valid($price[3]) ? $stocks->[3] * $price[3] : 0;
+ my $total_value= $rum_value + $shot_value;
+
+ printf "%-10s ", 'stocks'.fmt_stock_index(++$si).':';
+ pr1s($stock_rum);
+ pr1s($rum_value);
+ printf "%6d", $stocks->[3];
+ pr1s($shot_value);
+ pr1s($total_value);
+
+ if (defined $last_value) {
+ printf(" %10.1f %10.1f",
+ $total_value - $last_value,
+ $total_value - $initial_value);
+ }
+ $initial_value= $total_value unless defined $initial_value;
+ $last_value= $total_value;
+ print "\n";
+ }
+ print <<END
+ fine poe units poe poe delta-poe poe
+
+END
+;
+}
+
+sub pr2 ($$$) {
+ my ($k,$v1,$v2) = @_;
+ printf "%-20s %-23s %s\n", "$k:", $v1, $v2;
+}
+
+sub pr3 ($$$$) {
+ my ($k,$v1,$v2,$v3) = @_;
+ printf "%-20s %-23s %-20s %s\n", "$k:", $v1, $v2, $v3;
+}
+
+sub pr2rs ($$$) {
+ my ($k,$rum,$shot) = @_;
+ pr2($k,
+ valid($rum) ? sprintf("%12.1f fine equiv", $rum) : '',
+ valid($shot) ? sprintf("%10d shot", $shot) : '');
+}
+
+sub compute_restock_requirements () {
+ return unless @want;
+
+ my $rum_want= rum_total(@want);
+
+ my $stocks= @have ? $have[-1] : [qw(0 0 0 0)];
+ my $rum_have= rum_total(@$stocks);
+
+ pr2rs('desired stock level', $rum_want, $want[3]);
+
+ my $rum_need = $rum_want - $rum_have;
+ my $shot_need = $want[3] - $stocks->[3];
+
+ if (@have) {
+ pr2rs('current stock', $rum_have, $stocks->[3]);
+ pr2rs('restock requirement', $rum_need, $shot_need);
+ print "\n";
+ }
+
+ if (@price) {
+ my ($rum_buy,$shot_buy) = ('','');
+ my ($rum_bill,$shot_bill) = qw(0 0);
+ if (defined $best and $rum_need > 0) {
+ my $rum_qty= $rum_need * 100 / $proofs[$best];
+ $rum_qty= ceil($rum_qty);
+ $rum_buy= sprintf('%12s %-11s ',"** $rum_qty","$kinds[$best] **");
+ $rum_bill= $rum_qty * $price[$best];
+ }
+ if ($shot_need > 0 and valid($price[3])) {
+ $shot_buy= sprintf('%7s shot **', "** $shot_need");
+ $shot_bill= $shot_need * $price[3];
+ }
+ if (length($rum_buy) or length($shot_buy)) {
+ pr3('for',
+ $rum_bill ? sprintf("%12d poe ", $rum_bill) : '',
+ $shot_bill ? sprintf("%10d poe", $shot_bill) : '',
+ sprintf("%7d total", $rum_bill + $shot_bill));
+ pr2('BUY', $rum_buy, $shot_buy);
+ } else {
+ print "stocks are sufficient.\n";
+ }
+ print "\n";
+ }
+}
+
parse_args();
print_inputs();
compute_cheapest_rum();
+compute_stock_values();
+compute_restock_requirements();
__DATA__
our $have_proof;
our ($need_proof, %need, %buy);
-
-sub compute_restock_requirements () {
- if ($ship =~ m/^\d+/) {
- $need{Fine} = $ship;
- } else {
- $ship =~ y/_/ /;
- open F, "/home/ian/private/puzzle-pirates" or die $!;
- my $this_ship= 0;
- my $the_ship;
- while (<F>) {
- if (!m/\S/ || m/^\s*\#/) {
- $this_ship= 0;
- next;
- }
- if (!m/^\@/) {
- next;
- }
- if (m/^\@(( [A-Z][-a-z]+){2,})\s*$/) {
- $this_ship= (uc $1 eq uc " $ship" or
- uc $+ eq uc " $ship");
- $the_ship= $1;
- next;
- }
- next unless $this_ship;
- if (m/^\@\s+(\d+)\s+fine\s*/) {
- $need{Fine} = $1;
- last;
- }
- }
- die $! if F->error;
- die "unknown ship $ship" unless defined $need{Fine};
- if (defined $ship) {
- pr1("vessel",$the_ship);
- }
- }
- pr1('desired stock level', sprintf("%4d fine rum", $need{Fine}));
- $need_proof= $need{Fine} * $proof{Fine} - $have_proof;
- map {
- $buy{$_} = $need_proof / $proof{$_};
- } @rums;
- pr1("stock equivalent", sprintf "$ff fine rum", $have_proof / $proof{Fine});
- pr1("restock equivalent", sprintf "$ff fine rum", $need_proof / $proof{Fine});
- prf('would need', %buy, 'rum');
-}
+
sub compute_restock_cheapest_rum() {
my %bill;