Created
October 18, 2025 05:32
-
-
Save StartAutomating/db3c6f2f05aef061b1b9e61e2941774d to your computer and use it in GitHub Desktop.
Gist a fast Fibonacci
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| filter Get-Fibonacci { | |
| <# | |
| .SYNOPSIS | |
| Gets the fibonacci sequence | |
| .DESCRIPTION | |
| Gets the fibonacci sequence or ratio sequence using a bit of function state magic. | |
| .NOTES | |
| Stores the fibonacci sequence in the function definition. | |
| By keeping state between calls, we perform a very fast iterative implementation of the fibonacci sequence. | |
| This was inspired by the advanced generator example for JavaScript on MDN. | |
| Since PowerShell yields values rather than returns them, all PowerShell functions are effectively generators. | |
| .EXAMPLE | |
| # Get the next 3 fibonacci numbers | |
| fibonacci | |
| fibonacci | |
| fibonacci | |
| .EXAMPLE | |
| # See how long it takes to get the first 1kb of fibonacci numbers | |
| Measure-Command { fibonacci 1kb } | |
| .EXAMPLE | |
| # Get the fibonacci sequence so far | |
| fibonacci -Sequence | |
| .LINK | |
| https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_generators#advanced_generators | |
| #> | |
| [alias('Fibonacci')] | |
| param( | |
| # If we want, we can ask for the Nth number. | |
| [int] | |
| $N = -1, | |
| # If set, will output all numbers in the sequence | |
| [Alias('Sequence')] | |
| [switch] | |
| $All, | |
| # If set, will get the ratio between numbers | |
| [switch] | |
| $Ratio | |
| ) | |
| # If we are piped in a number greater than zero, use it | |
| if ($_ -is [int] -and $_ -ge 0) { | |
| $n = $_ | |
| } | |
| # Get myself | |
| $my = $MyInvocation.MyCommand | |
| # Initialize my state | |
| if (-not $my.Current) { | |
| $my | | |
| Add-Member NoteProperty Current (0) -Force -PassThru | | |
| Add-Member NoteProperty Next (1) -Force -PassThru | | |
| Add-Member NoteProperty Sequence @() -Force | |
| } | |
| # If we ask for the Nth number | |
| if ($n -ge 0) { | |
| # we just make sure we have called ourself that many times. | |
| while ($my.Sequence.Length -le $n) { | |
| $null = & $my | |
| } | |
| # If we want the ratio | |
| if ($ratio) { | |
| # divide by the previous number if there is one. | |
| if ($my.Sequence[$n - 1]) { | |
| return $my.Sequence[$n] / $my.Sequence[$n -1] | |
| } else { | |
| return $my.Sequence[$n] | |
| } | |
| } | |
| # otherwise, return the Nth number in the sequence. | |
| return $my.Sequence[$n] | |
| } | |
| # If we want all of the sequence | |
| if ($all) { | |
| # and don't want the ratio | |
| if (-not $ratio) { | |
| # return the sequence | |
| return $my.Sequence | |
| } else { | |
| # otherwise return all the ratios | |
| for ($n = 2; $n -lt $my.Sequence.Length; $n++) { | |
| $my.Sequence[$n]/$my.Sequence[$n-1] | |
| } | |
| return | |
| } | |
| } | |
| # add the current number to the sequence | |
| $my.Sequence += $my.Current | |
| # If we want the ratio, get current over next | |
| if ($Ratio) { | |
| $my.Current/$my.Next | |
| } else { | |
| $my.Current | |
| } | |
| # Set current and next to next and next + current | |
| $my.Current, $my.Next = $my.Next, ($my.Next + $my.Current) | |
| } | |
| Measure-Command { Fibonacci 2kb } | |
| $goldenRatio = (1 + [Math]::Sqrt(5))/2 | |
| (Fibonacci 42) / (Fibonacci 41) -eq $goldenRatio |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment