#### /extra/project-euler/014/014.factor

http://github.com/abeaumont/factor
Unknown | 76 lines | 48 code | 28 blank | 0 comment | 0 complexity | 0bf115eac65d433bad0ef471a8dfe277 MD5 | raw file
``` 1! Copyright (c) 2007 Aaron Schaefer.
3USING: combinators.short-circuit kernel make math math.functions math.ranges
4    sequences project-euler.common ;
5IN: project-euler.014
6
7! http://projecteuler.net/index.php?section=problems&id=14
8
9! DESCRIPTION
10! -----------
11
12! The following iterative sequence is defined for the set of positive integers:
13
14!     n -> n / 2  (n is even)
15!     n -> 3n + 1 (n is odd)
16
17! Using the rule above and starting with 13, we generate the following
18! sequence:
19
20!     13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
21
22! It can be seen that this sequence (starting at 13 and finishing at 1)
23! contains 10 terms. Although it has not been proved yet (Collatz Problem), it
24! is thought that all starting numbers finish at 1.
25
26! Which starting number, under one million, produces the longest chain?
27
28! NOTE: Once the chain starts the terms are allowed to go above one million.
29
30
31! SOLUTION
32! --------
33
34! Brute force
35
36<PRIVATE
37
38: next-collatz ( n -- n )
39    dup even? [ 2 / ] [ 3 * 1 + ] if ;
40
41: longest ( seq seq -- seq )
42    2dup [ length ] bi@ > [ drop ] [ nip ] if ;
43
44PRIVATE>
45
46: collatz ( n -- seq )
47    [ [ dup 1 > ] [ dup , next-collatz ] while , ] { } make ;
48
49: euler014 ( -- answer )
50    1000000 [1,b] { } [ collatz longest ] reduce first ;
51
52! [ euler014 ] time
53! 52868 ms run / 483 ms GC time
54
55
56! ALTERNATE SOLUTIONS
57! -------------------
58
59<PRIVATE
60
61: worth-calculating? ( n -- ? )
62    1 - 3 { [ divisor? ] [ / even? ] } 2&& ;
63
64PRIVATE>
65
66: euler014a ( -- answer )
67    500000 1000000 [a,b] { 1 } [
68        dup worth-calculating? [ collatz longest ] [ drop ] if
69    ] reduce first ;
70
71! [ euler014a ] 10 ave-time
72! 4821 ms run / 41 ms GC time
73
74! TODO: try using memoization
75
76SOLUTION: euler014a
```