Created
December 31, 2020 02:28
-
-
Save IISResetMe/3b678370b0eda217f472cb4789f9ed5a to your computer and use it in GitHub Desktop.
Nega-fibonacci with (non-optimal) caching
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
| # Z-fibonacci (or nega-fibonacci, see https://en.wikipedia.org/wiki/Fibonacci_number#Sequence_properties): | |
| # F(n-2) = F(n) - F(n-1) | |
| $function:fib = & { | |
| $cache = [System.Collections.Generic.Dictionary[int,bigint]]::new() | |
| -1..1 |Foreach-Object { | |
| $cache.Add($_, $_) | |
| } | |
| return { | |
| param( | |
| [Parameter(Mandatory,ValueFromPipeline)] | |
| [int]$n | |
| ) | |
| process { | |
| # This generalization of Fibonacci can be expressed as a | |
| # Jacobstahl binomial (https://www.fq.math.ca/Scanned/35-2/horadam.pdf). | |
| # Fortunately, we don't actually need to know how to calculate | |
| # such an expression - instead, we can use this observation | |
| # to "predict" that negative $n-values results in alternating | |
| # sequence like | |
| # | |
| # [ ..., -1*fib(Abs(-4)), fib(Abs(-3)), -1*fib(Abs(-2)), fib(Abs(-1)) ] | |
| # | |
| # So all we need to know is what fib(Abs($n)) is, and whether | |
| # $n is negative and odd: | |
| Write-Verbose "Fib($n)" | |
| $odd = $n % 2 -ne 0 | |
| $negative = $n -lt 0 | |
| $n = [Math]::Abs($n) | |
| # always return cached fib($n) values | |
| if($cache.ContainsKey($n)){ | |
| Write-Verbose "Cache hit: $n ($($cache[$n]))" | |
| $head = $cache[$n] | |
| } | |
| else { | |
| Write-Verbose "Cache miss: $n" | |
| Write-Verbose "Counting values for `$n = 0..$n" | |
| $tail,$head = 0,1 -as [bigint[]] | |
| $i = 1 | |
| while($i++ -lt $n){ | |
| $tail,$head = $head,($tail+$head) | |
| $cache.Item($i) = $head | |
| } | |
| } | |
| return $head * (1,-1)[$odd -and $negative] | |
| } | |
| }.GetNewClosure() | |
| } | |
| # | |
| @( | |
| -5..5 |fib -Verbose | |
| ) | |
| -10..10 |ForEach-Object { | |
| [PSCustomObject]@{ | |
| N = $_ | |
| Fib = $_ |fib -Verbose | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment