PageRenderTime 36ms CodeModel.GetById 30ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/extra/project-euler/002/002.factor

http://github.com/abeaumont/factor
Unknown | 80 lines | 52 code | 28 blank | 0 comment | 0 complexity | 7d901ca8bf11c10c62887454d505e4e3 MD5 | raw file
 1! Copyright (c) 2007, 2008 Aaron Schaefer, Alexander Solovyov, Vishal Talwar.
 2! See http://factorcode.org/license.txt for BSD license.
 3USING: kernel math sequences project-euler.common ;
 4IN: project-euler.002
 5
 6! http://projecteuler.net/index.php?section=problems&id=2
 7
 8! DESCRIPTION
 9! -----------
10
11! Each new term in the Fibonacci sequence is generated by adding the previous
12! two terms. By starting with 1 and 2, the first 10 terms will be:
13
14!     1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
15
16! Find the sum of all the even-valued terms in the sequence which do not exceed
17! four million.
18
19
20! SOLUTION
21! --------
22
23<PRIVATE
24
25: (fib-upto) ( seq n limit -- seq )
26    2dup <= [ [ over push dup 2 tail* sum ] dip (fib-upto) ] [ 2drop ] if ;
27
28PRIVATE>
29
30: fib-upto ( n -- seq )
31    V{ 0 } clone 1 rot (fib-upto) ;
32
33: euler002 ( -- answer )
34    4,000,000 fib-upto [ even? ] filter sum ;
35
36! [ euler002 ] 100 ave-time
37! 0 ms ave run time - 0.22 SD (100 trials)
38
39
40! ALTERNATE SOLUTIONS
41! -------------------
42
43: fib-upto* ( n -- seq )
44    0 1 [ pick over >= ] [ [ nip ] 2keep + dup ] produce [ 3drop ] dip
45    but-last-slice { 0 1 } prepend ;
46
47: euler002a ( -- answer )
48    4,000,000 fib-upto* [ even? ] filter sum ;
49
50! [ euler002a ] 100 ave-time
51! 0 ms ave run time - 0.2 SD (100 trials)
52
53
54<PRIVATE
55
56: next-fibs ( x y -- y x+y )
57    [ nip ] [ + ] 2bi ;
58
59: ?retotal ( total fib- fib+ -- retotal fib- fib+ )
60    dup even? [ [ nip + ] 2keep ] when ;
61
62: (sum-even-fibs-below) ( partial fib- fib+ max -- total )
63    2dup > [
64        3drop
65    ] [
66        [ ?retotal next-fibs ] dip (sum-even-fibs-below)
67    ] if ;
68
69PRIVATE>
70
71: sum-even-fibs-below ( max -- sum )
72    [ 0 0 1 ] dip (sum-even-fibs-below) ;
73
74: euler002b ( -- answer )
75    4000000 sum-even-fibs-below ;
76
77! [ euler002b ] 100 ave-time
78! 0 ms ave run time - 0.0 SD (100 trials)
79
80SOLUTION: euler002b