]> gitweb.factorcode.org Git - factor.git/commitdiff
Solutions to Project Euler problem 69
authorAaron Schaefer <aaron@elasticdog.com>
Wed, 8 Apr 2009 06:41:02 +0000 (02:41 -0400)
committerAaron Schaefer <aaron@elasticdog.com>
Wed, 8 Apr 2009 06:41:02 +0000 (02:41 -0400)
extra/project-euler/007/007.factor
extra/project-euler/069/069-tests.factor [new file with mode: 0644]
extra/project-euler/069/069.factor [new file with mode: 0644]
extra/project-euler/071/071.factor
extra/project-euler/common/common.factor
extra/project-euler/project-euler.factor

index f9208e11b3a7fb3a613ceca976a9efe018cb3901..1827d0fa069709428ef0a2ebd0e75e0a97aee388 100644 (file)
@@ -17,9 +17,6 @@ IN: project-euler.007
 ! SOLUTION
 ! --------
 
-: nth-prime ( n -- n )
-    1- lprimes lnth ;
-
 : euler007 ( -- answer )
     10001 nth-prime ;
 
diff --git a/extra/project-euler/069/069-tests.factor b/extra/project-euler/069/069-tests.factor
new file mode 100644 (file)
index 0000000..97741c0
--- /dev/null
@@ -0,0 +1,4 @@
+USING: project-euler.069 tools.test ;
+
+{ 510510 } [ euler069 ] unit-test
+{ 510510 } [ euler069a ] unit-test
diff --git a/extra/project-euler/069/069.factor b/extra/project-euler/069/069.factor
new file mode 100644 (file)
index 0000000..eae1d82
--- /dev/null
@@ -0,0 +1,87 @@
+! Copyright (c) 2009 Aaron Schaefer.
+! See http://factorcode.org/license.txt for BSD license.
+USING: combinators fry kernel math math.primes math.primes.factors math.ranges
+    project-euler.common sequences ;
+IN: project-euler.069
+
+! http://projecteuler.net/index.php?section=problems&id=69
+
+! DESCRIPTION
+! -----------
+
+! Euler's Totient function, φ(n) [sometimes called the phi function], is used
+! to determine the number of numbers less than n which are relatively prime to
+! n. For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and
+! relatively prime to nine, φ(9)=6.
+
+!     +----+------------------+------+-----------+
+!     | n  | Relatively Prime | φ(n) | n / φ(n)  |
+!     +----+------------------+------+-----------+
+!     | 2  | 1                | 1    | 2         |
+!     | 3  | 1,2              | 2    | 1.5       |
+!     | 4  | 1,3              | 2    | 2         |
+!     | 5  | 1,2,3,4          | 4    | 1.25      |
+!     | 6  | 1,5              | 2    | 3         |
+!     | 7  | 1,2,3,4,5,6      | 6    | 1.1666... |
+!     | 8  | 1,3,5,7          | 4    | 2         |
+!     | 9  | 1,2,4,5,7,8      | 6    | 1.5       |
+!     | 10 | 1,3,7,9          | 4    | 2.5       |
+!     +----+------------------+------+-----------+
+
+! It can be seen that n = 6 produces a maximum n / φ(n) for n ≤ 10.
+
+! Find the value of n ≤ 1,000,000 for which n / φ(n) is a maximum.
+
+
+! SOLUTION
+! --------
+
+! Brute force
+
+<PRIVATE
+
+: totient-ratio ( n -- m )
+    dup totient / ;
+
+PRIVATE>
+
+: euler069 ( -- answer )
+    2 1000000 [a,b] [ totient-ratio ] map
+    [ supremum ] keep index 2 + ;
+
+! [ euler069 ] 10 ave-time
+! 25210 ms ave run time - 115.37 SD (10 trials)
+
+
+! ALTERNATE SOLUTIONS
+! -------------------
+
+! In order to obtain maximum n / φ(n), φ(n) needs to be low and n needs to be
+! high. Hence we need a number that has the most factors. A number with the
+! most unique factors would have fewer relatively prime.
+
+<PRIVATE
+
+: primorial ( n -- m )
+    {
+        { [ dup 0 = ] [ drop V{ 1 } ] }
+        { [ dup 1 = ] [ drop V{ 2 } ] }
+        [ nth-prime primes-upto ]
+    } cond product ;
+
+: (primorial-upto) ( count limit -- m )
+    '[ dup primorial _ <= ] [ 1+ dup primorial ] produce
+    nip penultimate ;
+
+: primorial-upto ( limit -- m )
+    1 swap (primorial-upto) ;
+
+PRIVATE>
+
+: euler069a ( -- answer )
+    1000000 primorial-upto ;
+
+! [ euler069a ] 100 ave-time
+! 0 ms ave run time - 0.01 SD (100 trials)
+
+SOLUTION: euler069a
index cccf6bf708d75735c750d85e4b5d7d2014261a5f..0fd93a8f2d0fb9afa4b226374c0409f3f1d54f4a 100644 (file)
@@ -32,13 +32,6 @@ IN: project-euler.071
 ! repeatedly until the denominator is as close to 1000000 as possible without
 ! going over.
 
-<PRIVATE
-
-: penultimate ( seq -- elt )
-    dup length 2 - swap nth ;
-
-PRIVATE>
-
 : euler071 ( -- answer )
     2/5 [ dup denominator 1000000 <= ] [ 3/7 mediant dup ] produce
     nip penultimate numerator ;
index ba8c81fbf4f90ab0d008ac197e8b91a9f7bb66fe..c2ffe26d949cbdbeefaf594651d0a4966d7f4d61 100644 (file)
@@ -1,9 +1,10 @@
-! Copyright (c) 2007-2008 Aaron Schaefer.
+! Copyright (c) 2007-2009 Aaron Schaefer.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: arrays kernel make math math.functions math.matrices math.miller-rabin
-    math.order math.parser math.primes.factors math.ranges math.ratios
-    sequences sorting strings unicode.case parser accessors vocabs.parser
-    namespaces vocabs words quotations prettyprint ;
+USING: accessors arrays kernel lists make math math.functions math.matrices
+    math.miller-rabin math.order math.parser math.primes.factors
+    math.primes.lists math.ranges math.ratios namespaces parser prettyprint
+    quotations sequences sorting strings unicode.case vocabs vocabs.parser
+    words ;
 IN: project-euler.common
 
 ! A collection of words used by more than one Project Euler solution
@@ -16,11 +17,13 @@ IN: project-euler.common
 ! log10 - #25, #134
 ! max-path - #18, #67
 ! mediant - #71, #73
+! nth-prime - #7, #69
 ! nth-triangle - #12, #42
 ! number>digits - #16, #20, #30, #34, #35, #38, #43, #52, #55, #56, #92
 ! palindrome? - #4, #36, #55
 ! pandigital? - #32, #38
 ! pentagonal? - #44, #45
+! penultimate - #69, #71
 ! propagate-all - #18, #67
 ! sum-proper-divisors - #21
 ! tau* - #12
@@ -78,6 +81,9 @@ PRIVATE>
 : number-length ( n -- m )
     log10 floor 1+ >integer ;
 
+: nth-prime ( n -- n )
+    1- lprimes lnth ;
+
 : nth-triangle ( n -- n )
     dup 1+ * 2 / ;
 
@@ -90,6 +96,9 @@ PRIVATE>
 : pentagonal? ( n -- ? )
     dup 0 > [ 24 * 1+ sqrt 1+ 6 / 1 mod zero? ] [ drop f ] if ;
 
+: penultimate ( seq -- elt )
+    dup length 2 - swap nth ;
+
 ! Not strictly needed, but it is nice to be able to dump the triangle after the
 ! propagation
 : propagate-all ( triangle -- new-triangle )
index 5d46d7f1fd61f6fd3c257b396ad5dde69920b5e9..95d364421500c6c50c315db2c6180d2256040e10 100644 (file)
@@ -1,4 +1,4 @@
-! Copyright (c) 2007, 2008, 2009 Aaron Schaefer, Samuel Tardieu.
+! Copyright (c) 2007-2009 Aaron Schaefer, Samuel Tardieu.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: definitions io io.files io.pathnames kernel math math.parser
     prettyprint project-euler.ave-time sequences vocabs vocabs.loader
@@ -16,13 +16,13 @@ USING: definitions io io.files io.pathnames kernel math math.parser
     project-euler.045 project-euler.046 project-euler.047 project-euler.048
     project-euler.049 project-euler.052 project-euler.053 project-euler.054
     project-euler.055 project-euler.056 project-euler.057 project-euler.058
-    project-euler.059 project-euler.063 project-euler.067 project-euler.071
-    project-euler.073 project-euler.075 project-euler.076 project-euler.079
-    project-euler.092 project-euler.097 project-euler.099 project-euler.100
-    project-euler.116 project-euler.117 project-euler.134 project-euler.148
-    project-euler.150 project-euler.151 project-euler.164 project-euler.169
-    project-euler.173 project-euler.175 project-euler.186 project-euler.190
-    project-euler.203 project-euler.215 ;
+    project-euler.059 project-euler.063 project-euler.067 project-euler.069
+    project-euler.071 project-euler.073 project-euler.075 project-euler.076
+    project-euler.079 project-euler.092 project-euler.097 project-euler.099
+    project-euler.100 project-euler.116 project-euler.117 project-euler.134
+    project-euler.148 project-euler.150 project-euler.151 project-euler.164
+    project-euler.169 project-euler.173 project-euler.175 project-euler.186
+    project-euler.190 project-euler.203 project-euler.215 ;
 IN: project-euler
 
 <PRIVATE