1 ! Copyright (c) 2007 Aaron Schaefer.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: combinators.short-circuit kernel make math math.functions
4 ranges sequences project-euler.common ;
7 ! https://projecteuler.net/problem=14
12 ! The following iterative sequence is defined for the set of
15 ! n -> n / 2 (n is even)
16 ! n -> 3n + 1 (n is odd)
18 ! Using the rule above and starting with 13, we generate the
21 ! 13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
23 ! It can be seen that this sequence (starting at 13 and
24 ! finishing at 1) contains 10 terms. Although it has not been
25 ! proved yet (Collatz Problem), it is thought that all starting
26 ! numbers finish at 1.
28 ! Which starting number, under one million, produces the longest
31 ! NOTE: Once the chain starts the terms are allowed to go above
42 : next-collatz ( n -- n )
43 dup even? [ 2 / ] [ 3 * 1 + ] if ;
47 : collatz ( n -- seq )
48 [ [ dup 1 > ] [ dup , next-collatz ] while , ] { } make ;
50 : euler014 ( -- answer )
51 1,000,000 [1..b] { } [ collatz longer ] reduce first ;
54 ! 52868 ms run / 483 ms GC time
62 : worth-calculating? ( n -- ? )
63 1 - 3 { [ divisor? ] [ / even? ] } 2&& ;
67 : euler014a ( -- answer )
68 500000 1000000 [a..b] { 1 } [
69 dup worth-calculating? [ collatz longer ] [ drop ] if
72 ! [ euler014a ] 10 ave-time
73 ! 4821 ms run / 41 ms GC time
75 ! TODO: try using memoization