chiark / gitweb /
new workable OFF behaviour implemented and it compiles but is not tested
[trains.git] / misc / divider-table.pl
1 #!/usr/bin/perl -w
2
3 use strict;
4
5 our(@e12) = qw(10 12 15 18 22 27 33 39 47 56 68 82);
6 our(@ex24) = qw(11 13 16 20 24 30 36 43 51 62 75 91);
7 our(@e24)= sort @e12, @ex24;
8
9 our ($tlin,$tlog,@byrat);
10
11 sub thead ($$) {
12     my ($t,$h) = @_;
13     $$t = sprintf "%-12s |", $h;
14 }
15 sub chead ($$) {
16     my ($t,$h) = @_;
17     $$t .= sprintf " %5s", $h;
18 }
19 sub theadend ($) {
20     my ($t) = @_;
21     $$t .= "\n".('-'x(12+1)).'+'.('-'x(24*6))."\n";
22 }
23 sub rhead ($$) {
24     my ($t,$h) = @_;
25     $$t .= sprintf "%12s |", $h;
26 }
27 sub cell ($$) {
28     my ($t,$v) = @_;
29     $$t .= sprintf " %5s", $v;
30 }
31 sub rend ($$) {
32     my ($t,$n) = @_;
33     $$t .= "\n";
34     $$t .= "\n" if (($n+1) % 6) == 0;
35 }
36 sub tend ($) {
37     my ($t) = @_;
38 }
39
40 sub mul10fit ($$) {
41     my ($v,$len) = @_;
42     while (length(sprintf "%d", $v) < $len) { $v *= 10.0; }
43     return sprintf "%d", $v;
44 }
45 sub fracfit ($$) {
46     my ($v,$len) = @_;
47     $v= sprintf "%".($len+2).".${len}f", $v;
48     $v =~ s/^\d\.//;
49     return $v;
50 }
51
52 sub scan () {
53     my ($row,$col,$lin,$log,$rownum);
54     @byrat = ();
55     thead(\$tlin,'X/Y [*10^k]');
56     thead(\$tlog,'frac(L(X/Y))');
57     for $col (@e24) {
58         chead(\$tlin,$col);
59         chead(\$tlog,$col);
60     }
61     theadend(\$tlin);
62     theadend(\$tlog);
63     $rownum= 0;
64     for $row (@e24) {
65         rhead(\$tlin,$row);
66         rhead(\$tlog,$row);
67         for $col (@e24) {
68             $lin= $col*1.0 / $row;
69             $log= log($lin)/log(10) + 1.0;
70
71             cell(\$tlin, mul10fit($lin,5));
72             cell(\$tlog, fracfit($log,5));
73
74             if ($col < $row) { $lin *= 10; }
75             next if $row==$col;
76             push @byrat, { Num => $col,
77                            Den => $row,
78                            Lin => $lin,
79                            Log => $log };
80         }
81         rend(\$tlin,$rownum);
82         rend(\$tlog,$rownum);
83         $rownum++;
84     }
85     tend(\$tlin);
86     tend(\$tlog);
87     push @byrat, { Num => '*',
88                    Den => '*',
89                    Lin => 1.0,
90                    Log => 1.0 };
91 }
92
93 sub ptable ($) {
94     my ($tt) = @_;
95     print $tt or die $!;
96 }
97
98 sub sortbyrat () {
99     @byrat= sort {
100         $a->{Lin} <=> $b->{Lin}
101     } @byrat;
102 }
103
104 sub byratcol ($$$) {
105     my ($or,$cwr,$colnum) = @_;
106     $$or .= '  ' if $colnum;
107     $$cwr = ($colnum<6 ? 6 : 5);
108 }
109
110 sub printbyrat () {
111     use integer;
112     my ($brcols) = 8;
113     my ($brrows) = (@byrat+$brcols-1) / $brcols;
114     my ($byrat,$o,$colnum,$rownum,$cw);
115     $o= ''; 
116     for ($colnum=0; $colnum<$brcols; $colnum++) {
117         byratcol(\$o,\$cw,$colnum);
118         $o .= sprintf("N/D %".($cw+1)."s %s",
119                       'Q*10^k','fc(Lg)');
120     }
121     $o .= "\n";
122     for ($colnum=0; $colnum<$brcols; $colnum++) {
123         byratcol(\$o,\$cw,$colnum);
124         $o .= '-' x (5+1+$cw+1+5);
125     }
126     $o .= "\n";
127     for ($rownum=0; $rownum<$brrows; $rownum++) { 
128         for ($colnum=0; $colnum<$brcols; $colnum++) {
129             $byrat= $byrat[$colnum*$brrows + $rownum];
130             next unless defined $byrat;
131             byratcol(\$o,\$cw,$colnum);
132             $o .= sprintf("%2s/%-2s %${cw}s %s",
133                           $byrat->{Num}, $byrat->{Den},
134                           mul10fit($byrat->{Lin}, $cw),
135                           fracfit($byrat->{Log}, 5));
136         }
137         $o .= "\n";
138     }
139     print $o or die $!;
140 }
141
142 print "\n" or die $!;
143 scan();
144 ptable($tlin);
145 ptable($tlog);
146
147 sortbyrat();
148 printbyrat();