Skip to content

Instantly share code, notes, and snippets.

@Xainey
Created March 24, 2016 14:19
Show Gist options
  • Save Xainey/f5db0cbc136bd6c7b646 to your computer and use it in GitHub Desktop.
Save Xainey/f5db0cbc136bd6c7b646 to your computer and use it in GitHub Desktop.
Powershell Concept for Reverse Polish Notation
#Powershell concept for Revese Polish Notation
#Based on ealier JS and Java variants: http://codepen.io/xainey/pen/ojbZdj
function Solve-RPN
{
[CmdletBinding()]
[OutputType([System.Double])]
param
(
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $expression,
[parameter(Mandatory = $false)]
[string] $delimeter = ' '
)
$biOps = "+-*/^"
$pieces = $expression.ToLower() -split $delimeter
$s = new-object System.Collections.Stack
foreach ($e in $pieces)
{
if (isNumeric -str $e)
{
$s.Push([double] $e)
continue
}
if ($s.Count -eq 0)
{
throw "Error"
}
if ( $biOps.Contains($e) )
{
$s.Push((biOperation -e $e -b $s.pop() -a $s.pop()))
continue
}
$s.Push((singleOperation -e $e -a $s.pop()));
}
return $s.pop()
}
function singleOperation
{
[CmdletBinding()]
[OutputType([System.Double])]
param
(
[ValidateSet("sqrt", "exp", "sin", "cos", "tan", "asin", "acos", "atan")]
[string] $e,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[double] $a
)
if ($e.Equals("sqrt")){return [math]::Sqrt($a)}
if ($e.Equals("exp") ){return [math]::Exp($a) }
if ($e.Equals("sin") ){return [math]::Sin($a) }
if ($e.Equals("cos") ){return [math]::Cos($a) }
if ($e.Equals("tan") ){return [math]::Tan($a) }
if ($e.Equals("asin")){return [math]::Asin($a)}
if ($e.Equals("acos")){return [math]::Acos($a)}
if ($e.Equals("atan")){return [math]::Atan($a)}
return 0;
}
function biOperation
{
[CmdletBinding()]
[OutputType([System.Double])]
param
(
[ValidateSet("+", "-", "*", "/", "^")]
[string] $e,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[double] $a,
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[double] $b
)
if ($e.equals("+")){return $a + $b}
if ($e.equals("-")){return $a - $b}
if ($e.equals("*")){return $a * $b}
if ($e.equals("/")){return $a / $b}
if ($e.equals("^")){return [math]::Pow($a, $b)}
return 0;
}
function isNumeric
{
[CmdletBinding()]
[OutputType([System.Boolean])]
param
(
[parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $str
)
try
{
[double] $str
}
catch
{
return $false
}
return $true
}
Solve-RPN -expression "2 5 *"
Solve-RPN -delimeter ', ' -expression '1.52, 1, 1.52, /, -, 0.5, *, 3.14285, 90, /, -1.66, *, SIN, 4.29125, *, *, ATAN, 180.0, 3.14285, /, *'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment