]> gitweb.factorcode.org Git - factor.git/blob - extra/project-euler/014/014.factor
Delete empty unit tests files, remove 1- and 1+, reorder IN: lines in a lot of places...
[factor.git] / extra / project-euler / 014 / 014.factor
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.functions math.ranges
4     sequences project-euler.common ;
5 IN: 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
44 PRIVATE>
45
46 : collatz ( n -- seq )
47     [ [ dup 1 > ] [ dup , next-collatz ] while , ] { } make ;
48
49 : euler014 ( -- answer )
50     1000000 [1,b] 0 [ 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
64 PRIVATE>
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
76 SOLUTION: euler014a