]> git.donarmstrong.com Git - infobot.git/blob - src/Modules/Math.pl
ws
[infobot.git] / src / Modules / Math.pl
1 #
2 # infobot copyright (C) kevin lenzo 1997-98
3 #
4
5 use strict;
6
7 use vars qw($message);
8
9 my %digits = (
10     'first', '1', 'second', '2',  'third',   '3', 'fourth', '4',
11     'fifth', '5', 'sixth',  '6',  'seventh', '7', 'eighth', '8',
12     'ninth', '9', 'tenth',  '10', 'one',     '1', 'two',    '2',
13     'three', '3', 'four',   '4',  'five',    '5', 'six',    '6',
14     'seven', '7', 'eight',  '8',  'nine',    '9', 'ten',    '10'
15 );
16
17 sub perlMath {
18     my ($locMsg) = $message;
19
20     if ( $message =~ /^\s*$/ ) {
21         return;
22     }
23
24     foreach ( keys %digits ) {
25         $locMsg =~ s/$_/$digits{$_}/g;
26     }
27
28     while ( $locMsg =~ /(exp ([\w\d]+))/ ) {
29         my ( $exp, $val ) = ( $1, exp $2 );
30         $locMsg =~ s/$exp/+$val/g;
31     }
32
33     while ( $locMsg =~ /(hex2dec\s*([0-9A-Fa-f]+))/ ) {
34         my ( $exp, $val ) = ( $1, hex $2 );
35         $locMsg =~ s/$exp/+$val/g;
36     }
37
38     if ( $locMsg =~ /^\s*(dec2hex\s*(\d+))\s*\?*/ ) {
39         my ( $exp, $val ) = ( $1, sprintf( "%x", "$2" ) );
40         $locMsg =~ s/$exp/+$val/g;
41     }
42
43     my $e = exp(1);
44     $locMsg =~ s/\be\b/$e/;
45
46     while ( $locMsg =~ /(log\s*((\d+\.?\d*)|\d*\.?\d+))\s*/ ) {
47         my ( $exp, $res ) = ( $1, $2 );
48         my $val = ($res) ? log($res) : 'Infinity';
49         $locMsg =~ s/$exp/+$val/g;
50     }
51
52     while ( $locMsg =~ /(bin2dec ([01]+))/ ) {
53         my $exp = $1;
54         my $val = join( '', unpack( 'B*', $2 ) );
55         $locMsg =~ s/$exp/+$val/g;
56     }
57
58     while ( $locMsg =~ /(dec2bin (\d+))/ ) {
59         my $exp = $1;
60         my $val = join( '', unpack( 'B*', pack( 'N', $2 ) ) );
61         $val    =~ s/^0+//;
62         $locMsg =~ s/$exp/+$val/g;
63     }
64
65     for ($locMsg) {
66         s/\bpi\b/3.14159265/g;
67         s/ to the / ** /g;
68         s/\btimes\b/\*/g;
69         s/\bdiv(ided by)? /\/ /g;
70         s/\bover /\/ /g;
71         s/\bsquared/\*\*2 /g;
72         s/\bcubed/\*\*3 /g;
73         s/\bto\s+(\d+)(r?st|nd|rd|th)?( power)?/\*\*$1 /ig;
74         s/\bpercent of/*0.01*/ig;
75         s/\bpercent/*0.01/ig;
76         s/\% of\b/*0.01*/g;
77         s/\%/*0.01/g;
78         s/\bsquare root of (\d+)/$1 ** 0.5 /ig;
79         s/\bcubed? root of (\d+)/$1 **(1.0\/3.0) /ig;
80         s/ of / * /;
81         s/(bit(-| )?)?xor(\'?e?d( with))?/\^/g;
82         s/(bit(-| )?)?or(\'?e?d( with))?/\|/g;
83         s/bit(-| )?and(\'?e?d( with))?/\& /g;
84         s/(plus|and)/+/ig;
85     }
86
87     # what the hell is this shit?
88     if (   ( $locMsg =~ /^\s*[-\d*+\s()\/^\.\|\&\*\!]+\s*$/ )
89         && ( $locMsg !~ /^\s*\(?\d+\.?\d*\)?\s*$/ )
90         && ( $locMsg !~ /^\s*$/ )
91         && ( $locMsg !~ /^\s*[( )]+\s*$/ )
92         && ( $locMsg =~ /\d+/ ) )
93     {
94         $locMsg =~ s/([0-9]+\.[0-9]+(\.[0-9]+)+)/"$1"/g;
95         $locMsg = eval($locMsg);
96
97         if ( defined $locMsg and $locMsg =~ /^[-+\de\.]+$/ ) {
98             $locMsg = sprintf( "%1.12f", $locMsg );
99             $locMsg =~ s/\.?0+$//;
100
101             if ( length $locMsg > 30 ) {
102                 $locMsg = "a number with quite a few digits...";
103             }
104         }
105         else {
106             if ( defined $locMsg ) {
107                 &FIXME("math: locMsg => '$locMsg'...");
108             }
109             else {
110                 &status("math: could not really compute.");
111                 $locMsg = '';
112             }
113         }
114     }
115     else {
116         $locMsg = '';
117     }
118
119     if ( defined $locMsg and $locMsg ne $message ) {
120
121         # success.
122         return $locMsg;
123     }
124     else {
125
126         # no match.
127         return '';
128     }
129 }
130
131 1;
132
133 # vim:ts=4:sw=4:expandtab:tw=80