1 ! Copyright (c) 2007 Aaron Schaefer.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: combinators.short-circuit kernel make math math.ranges sequences ;
6 ! http://projecteuler.net/index.php?section=problems&id=14
11 ! The following iterative sequence is defined for the set of positive integers:
13 ! n -> n / 2 (n is even)
14 ! n -> 3n + 1 (n is odd)
16 ! Using the rule above and starting with 13, we generate the following
19 ! 13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
21 ! It can be seen that this sequence (starting at 13 and finishing at 1)
22 ! contains 10 terms. Although it has not been proved yet (Collatz Problem), it
23 ! is thought that all starting numbers finish at 1.
25 ! Which starting number, under one million, produces the longest chain?
27 ! NOTE: Once the chain starts the terms are allowed to go above one million.
37 : next-collatz ( n -- n )
38 dup even? [ 2 / ] [ 3 * 1+ ] if ;
40 : longest ( seq seq -- seq )
41 2dup [ length ] bi@ > [ drop ] [ nip ] if ;
45 : collatz ( n -- seq )
46 [ [ dup 1 > ] [ dup , next-collatz ] [ ] while , ] { } make ;
48 : euler014 ( -- answer )
49 1000000 [1,b] 0 [ collatz longest ] reduce first ;
52 ! 52868 ms run / 483 ms GC time
60 : worth-calculating? ( n -- ? )
61 1- 3 { [ mod 0 = ] [ / even? ] } 2&& ;
65 : euler014a ( -- answer )
66 500000 1000000 [a,b] 1 [
67 dup worth-calculating? [ collatz longest ] [ drop ] if
70 ! [ euler014a ] 10 ave-time
71 ! 4821 ms run / 41 ms GC time
73 ! TODO: try using memoization