I have the following Haskell code to generate the the values of the Fibonacci sequence which are even as an infinite list:
z=zipWith(+)
g=z((*2)<$>0:0:g)$z(0:g)$(*2)<$>scanl(+)1g
This works by starting with 0,2 and then defining every following term to be the sum of:
- twice all prior terms
- the previous term
- twice the term before that
- 2
I'd like to make it shorter, however I want to preserve a few properties of it.
- It must produce the same list.
- The solution mustn't calculate intermediate terms of the Fibonacci sequence. The above code calculates each term purely in terms of previous terms of the sequence, and improved versions should as well.
- The solution can't use any helper functions, other than point-free aliases like
z
.
I really feel like this can be done with only 1 zip, however I can't get anything to work.
How can I shorten this.
1 Answer 1
Haskell, 27 bytes
g=2:zipWith((+).(*4))g(0:g)
Uses the recursive relationship \$g_n = 4 g_{n-1} + g_{n-2}\$.
-
2\$\begingroup\$ Here's it in 21:
g=2:scanl((+).(*4))8g
\$\endgroup\$2023年08月18日 03:51:57 +00:00Commented Aug 18, 2023 at 3:51 -
\$\begingroup\$ @WheatWizard TIL that you can just convert to the
scanl
form with any function, I thought it was something special for the original Fibonacci series. \$\endgroup\$xnor– xnor2023年08月18日 07:21:12 +00:00Commented Aug 18, 2023 at 7:21
g!!3 == 140
which should be 144. \$\endgroup\$