]> gitweb.factorcode.org Git - factor.git/blob - extra/project-euler/058/058.factor
Delete empty unit tests files, remove 1- and 1+, reorder IN: lines in a lot of places...
[factor.git] / extra / project-euler / 058 / 058.factor
1 ! Copyright (c) 2009 Aaron Schaefer.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: fry kernel math math.primes math.ranges project-euler.common sequences ;
4 IN: project-euler.058
5
6 ! http://projecteuler.net/index.php?section=problems&id=58
7
8 ! DESCRIPTION
9 ! -----------
10
11 ! Starting with 1 and solveling anticlockwise in the following way, a square
12 ! solve with side length 7 is formed.
13
14 !     37 36 35 34 33 32 31
15 !     38 17 16 15 14 13 30
16 !     39 18  5  4  3 12 29
17 !     40 19  6  1  2 11 28
18 !     41 20  7  8  9 10 27
19 !     42 21 22 23 24 25 26
20 !     43 44 45 46 47 48 49
21
22 ! It is interesting to note that the odd squares lie along the bottom right
23 ! diagonal, but what is more interesting is that 8 out of the 13 numbers lying
24 ! along both diagonals are prime; that is, a ratio of 8/13 ≈ 62%.
25
26 ! If one complete new layer is wrapped around the solve above, a square solve
27 ! with side length 9 will be formed. If this process is continued, what is the
28 ! side length of the square solve for which the ratio of primes along both
29 ! diagonals first falls below 10%?
30
31
32 ! SOLUTION
33 ! --------
34
35 <PRIVATE
36
37 CONSTANT: PERCENT_PRIME 0.1
38
39 ! The corners of a square of side length n are:
40 !    (n-2)² + 1(n-1)
41 !    (n-2)² + 2(n-1)
42 !    (n-2)² + 3(n-1)
43 !    (n-2)² + 4(n-1) = odd squares, no need to calculate
44
45 : prime-corners ( n -- m )
46     3 [1,b] swap '[ _ [ 1 - * ] keep 2 - sq + prime? ] count ;
47
48 : total-corners ( n -- m )
49     1 - 2 * ; foldable
50
51 : ratio-below? ( count length -- ? )
52     total-corners 1 + / PERCENT_PRIME < ;
53
54 : next-layer ( count length -- count' length' )
55     2 + [ prime-corners + ] keep ;
56
57 : solve ( count length -- length )
58     2dup ratio-below? [ nip ] [ next-layer solve ] if ;
59
60 PRIVATE>
61
62 : euler058 ( -- answer )
63     8 7 solve ;
64
65 ! [ euler058 ] 10 ave-time
66 ! 12974 ms ave run time - 284.46 SD (10 trials)
67
68 SOLUTION: euler058