rendered paste bodyon $*:TEXT:/^[!@.]Solve */Si:#: {
var %saystyle = $iif($left($1,1) == @,.msg $chan,.notice $nick)
%saystyle 07x=07 $+ $solve($2-)
}
alias solve {
var %eq = $1
if (= isin $1) %eq = $gettok(%eq,1,61) $+ -( $+ $gettok($1,2,61) $+ )
%eq = $trans(%eq)
return $multiple(%eq,$xsolve(%eq))
}
alias trans {
var %eq = $remove($1,$chr(32))
%eq = $regsubex(%eq,/(sin|asin|acos|atan|cos|tan|log|sqrt)(x+)/g,\1 $+ $regsubex(s,\2,/(x)/g,$+($chr(40),x,$chr(41))))
%eq = $regsubex(%eq,/(\x29|\d)\x28/g,\t* $+ $chr(40))
%eq = $regsubex(%eq,/(\d)x/g,\t*x)
%eq = $regsubex(%eq,/(\d[a-z])/g,$remove(\t,$regsubex(\t,\d+,\t)) $+ * $+ $regsubex(\t,\d+,\t))
return %eq
}
alias multiple {
var %x = $2
var %eq = $1
var %trig = $iif($regex(%eq,asin|acos|atan|sin|cos|tan),$true,$false)
var %solutions = $iif($abs($xcalculate(%eq,%x)) < 0.001,$+($chr(44),$2,$chr(44)),$false)
if (%trig) return $iif(%solutions,$right($left(%solutions,-1),-1),$false)
if (!%solutions) return $false
while ($abs($xcalculate(%eq,%x)) < 0.001) {
%eq = $+($chr(40),%eq,$chr(41),/,$chr(40),x,-,%x,$chr(41))
%x = $xsolve(%eq)
if ($redundant(%solutions,%x)) goto finish
if (($abs($xcalculate(%eq,%x)) < 0.001)) %solutions = %solutions $+ %x $+ ,
}
:finish
return $right($left(%solutions,-1),-1)
}
alias xsolve {
var %x = 20
var %a = 0
while (%a <= 30) {
%x = $calc(%x - $+($chr(40),$xcalculate($1,%x),/,$derivative($1,%x),$chr(41)))
inc %a
}
return $xcheck($1,%x)
}
alias derivative {
var %num2 = $xcalculate($1,$2 + 1)
var %num3 = $xcalculate($1,$2 - 1)
return $calc((%num2 - %num3) / 2)
}
alias xcheck {
if (!$xcalculate($1,$round($2,0))) return $round($2,0)
if (!$xcalculate($1,$floor($2))) return $floor($2)
if (!$xcalculate($1,$ceil($2))) return $ceil($2)
var %y = 5
while ((%y >= 0) && (!$xcalculate($1,$round($2,%y)))) dec %y
return $round($2,$calc(%y +1))
}
alias xcalculate return $calc($parser($replace($1,x,$calc($2))))
alias parser return $regsubex($regsubex($1,/(?<=sin|asin|acos|atan|cos|tan|log|sqrt)(\d+)/g,(\t)),/((?:sin|asin|acos|atan|cos|tan|log|sqrt).+?\051)/g,$($ $+ $stript(\t,1) $+ $chr(40) $+ $stript(\t) $+ $chr(41) $+ .deg,2))
alias stript {
var %temp = $regsubex($1,sin|asin|acos|atan|cos|tan|log|sqrt,\t)
if ($2) return $remove($1,%temp)
else return $calc(%temp)
}
alias redundant {
var %temp = $chr(44)
var %a = 1
while (%a <= $gettok($1,0,44)) {
%temp = $+(%temp,$round($gettok($1,%a,44),1),$chr(44))
inc %a
}
if ($+($chr(44),$round($2,1),$chr(44)) isin %temp) return $true
else return $false
}