#!/usr/bin/perl -w

use strict;

our(@e12) = qw(10 12 15 18 22 27 33 39 47 56 68 82);
our(@ex24) = qw(11 13 16 20 24 30 36 43 51 62 75 91);
our(@e24)= sort @e12, @ex24;

our ($tlin,$tlog,@byrat);

sub thead ($$) {
    my ($t,$h) = @_;
    $$t = sprintf "%-12s |", $h;
}
sub chead ($$) {
    my ($t,$h) = @_;
    $$t .= sprintf " %5s", $h;
}
sub theadend ($) {
    my ($t) = @_;
    $$t .= "\n".('-'x(12+1)).'+'.('-'x(24*6))."\n";
}
sub rhead ($$) {
    my ($t,$h) = @_;
    $$t .= sprintf "%12s |", $h;
}
sub cell ($$) {
    my ($t,$v) = @_;
    $$t .= sprintf " %5s", $v;
}
sub rend ($$) {
    my ($t,$n) = @_;
    $$t .= "\n";
    $$t .= "\n" if (($n+1) % 6) == 0;
}
sub tend ($) {
    my ($t) = @_;
}

sub mul10fit ($$) {
    my ($v,$len) = @_;
    while (length(sprintf "%d", $v) < $len) { $v *= 10.0; }
    return sprintf "%d", $v;
}
sub fracfit ($$) {
    my ($v,$len) = @_;
    $v= sprintf "%".($len+2).".${len}f", $v;
    $v =~ s/^\d\.//;
    return $v;
}

sub scan () {
    my ($row,$col,$lin,$log,$rownum);
    @byrat = ();
    thead(\$tlin,'X/Y [*10^k]');
    thead(\$tlog,'frac(L(X/Y))');
    for $col (@e24) {
	chead(\$tlin,$col);
	chead(\$tlog,$col);
    }
    theadend(\$tlin);
    theadend(\$tlog);
    $rownum= 0;
    for $row (@e24) {
	rhead(\$tlin,$row);
	rhead(\$tlog,$row);
	for $col (@e24) {
	    $lin= $col*1.0 / $row;
	    $log= log($lin)/log(10) + 1.0;

	    cell(\$tlin, mul10fit($lin,5));
	    cell(\$tlog, fracfit($log,5));

	    if ($col < $row) { $lin *= 10; }
	    next if $row==$col;
	    push @byrat, { Num => $col,
			   Den => $row,
			   Lin => $lin,
			   Log => $log };
	}
	rend(\$tlin,$rownum);
	rend(\$tlog,$rownum);
	$rownum++;
    }
    tend(\$tlin);
    tend(\$tlog);
    push @byrat, { Num => '*',
		   Den => '*',
		   Lin => 1.0,
		   Log => 1.0 };
}

sub ptable ($) {
    my ($tt) = @_;
    print $tt or die $!;
}

sub sortbyrat () {
    @byrat= sort {
	$a->{Lin} <=> $b->{Lin}
    } @byrat;
}

sub byratcol ($$$) {
    my ($or,$cwr,$colnum) = @_;
    $$or .= '  ' if $colnum;
    $$cwr = ($colnum<6 ? 6 : 5);
}

sub printbyrat () {
    use integer;
    my ($brcols) = 8;
    my ($brrows) = (@byrat+$brcols-1) / $brcols;
    my ($byrat,$o,$colnum,$rownum,$cw);
    $o= ''; 
    for ($colnum=0; $colnum<$brcols; $colnum++) {
	byratcol(\$o,\$cw,$colnum);
	$o .= sprintf("N/D %".($cw+1)."s %s",
		      'Q*10^k','fc(Lg)');
    }
    $o .= "\n";
    for ($colnum=0; $colnum<$brcols; $colnum++) {
	byratcol(\$o,\$cw,$colnum);
	$o .= '-' x (5+1+$cw+1+5);
    }
    $o .= "\n";
    for ($rownum=0; $rownum<$brrows; $rownum++) { 
	for ($colnum=0; $colnum<$brcols; $colnum++) {
	    $byrat= $byrat[$colnum*$brrows + $rownum];
	    next unless defined $byrat;
	    byratcol(\$o,\$cw,$colnum);
	    $o .= sprintf("%2s/%-2s %${cw}s %s",
			  $byrat->{Num}, $byrat->{Den},
			  mul10fit($byrat->{Lin}, $cw),
			  fracfit($byrat->{Log}, 5));
	}
	$o .= "\n";
    }
    print $o or die $!;
}

print "\n" or die $!;
scan();
ptable($tlin);
ptable($tlog);

sortbyrat();
printbyrat();
