How could I neaten this code up.

2 ビュー (過去 30 日間)
Scragmore 2011 年 10 月 24 日
Currently working through some of Project Eulers problems as mentioned in the forum discussion 'Best way(s) to master MATLAB'. I have created this code, it works but there is something about it I find messy. For a start I don't like all the declared variables.
function eusol2 = euler2(euin)
% for No's in fibonacci sequence < 4mil, sum all even No terms.
x = [1 2];
y = 1;
xout = 2;
fibMax = 0;
while fibMax < euin
fibMax = x(1) + x(2);
if fibMax < euin
if mod(fibMax, 2) == 0;
xout = xout + fibMax;
x(y) = fibMax;
y = 3 - y;
eusol2 = xout;
Any suggestions or remarks
  3 件のコメント
Jan 2011 年 10 月 26 日
You started the sequence with [1,2] accidently instead of [1,1]. Using xout=2 instead of 0 compensates this such that the correct answer is calculated.
A very nice example for a "stealth bug": No effect for standard usage, generalising the function for any Fibonacci sequence [a,b] fails.



Jan 2011 年 10 月 25 日
Your function looks fine already. Most of all it is very fast, e.g. twice as fast as Daniel's program.
The result is wrong, because you start with xout=2. The empty ELSE branch wastes time. The "if fibMax < euin" check can be omited, if fibMax is increased after adding the new term. I prefer meaningful names instead of x and y.
function out = euler2(limit)
accum = [1, 1]; % [EDITED], was [1,2] as in the original question
index = 1;
out = 0;
fibMax = 0;
while fibMax < limit
if mod(fibMax, 2) == 0
out = out + fibMax;
fibMax = accum(1) + accum(2);
accum(index) = fibMax;
index = 3 - index;
Of course Binet's formula would be more sophisticated. But calling this function 10'000 times with the input 4e6 needs 0.15438 seconds only.
The MOD(fibMax, 2) fails after 75 terms due to the limited precision. Exploiting the simple pattern of even terms might be interesting, but a further "improvement" of the function is of accademical interest only. For a practical use this function is eitehr fast enough, of a lookup table with the 75 values is faster brute-force approach.
  6 件のコメント
Scragmore 2011 年 10 月 26 日
Thanks for the answers and explanation. I don't blame matlab, my maths is not good enough to accurately go beyond the size of those numbers either.


その他の回答 (3 件)

bym 2011 年 10 月 24 日
Have a look at Binet's formula and look for a pattern in the distribution of even Fibonnaci numbers...I bet a one liner could be written

Daniel Shub
Daniel Shub 2011 年 10 月 25 日
x = [1 2];
eusol2 = 0;
while sum(x) < euin
if mod(sum(x), 2) == 0;
eusol2 = eusol2 + sum(x);
x = [x(2), sum(x)];
% k = sum(x);
This will likely be a little slower since it calculates the sum(x) 4 times per loop. If you add another declared variable (k) you can make it so sum(x) is calculated only once. I eliminated y, because it doesn't seem to do anything.
  1 件のコメント
Scragmore 2011 年 10 月 25 日
I didn't know you could sum a complete matrix like that. I presume as its matlap and matrices are native you can sum in a hole bunch of ingenious ways.
My y is a switch, it flips between 1 & 2, in this case cell positions of x(y), allowing me to alternate storing the latest number in the series.
From reading your code I can use my function output, in this case eusol2 as a declared variable. I was worried that every time I wrote to this variable it would return it from the function. I will test/try this.


bym 2011 年 10 月 26 日
just to let you know where I was headed:
phi = (1+sqrt(5))/2;
i = 1:11; % 11 even terms < 4e6
fib = (phi.^(i.*3)-(-1/phi).^(i.*3))/sqrt(5);
as Jan suspected, it runs slower than yours (about .8 msec vs .07 msec). +1 vote for the question



Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by