diff --git a/extra/project-euler/092/092.factor b/extra/project-euler/092/092.factor new file mode 100644 index 0000000000..da7b38c62c --- /dev/null +++ b/extra/project-euler/092/092.factor @@ -0,0 +1,55 @@ +! Copyright (c) 2008 Aaron Schaefer. +! See http://factorcode.org/license.txt for BSD license. +USING: combinators.lib kernel math math.ranges namespaces project-euler.common + sequences ; +IN: project-euler.092 + +! http://projecteuler.net/index.php?section=problems&id=92 + +! DESCRIPTION +! ----------- + +! A number chain is created by continuously adding the square of the digits in +! a number to form a new number until it has been seen before. + +! For example, + +! 44 -> 32 -> 13 -> 10 -> 1 -> 1 +! 85 -> 89 -> 145 -> 42 -> 20 -> 4 -> 16 -> 37 -> 58 -> 89 + +! Therefore any chain that arrives at 1 or 89 will become stuck in an endless +! loop. What is most amazing is that EVERY starting number will eventually +! arrive at 1 or 89. + +! How many starting numbers below ten million will arrive at 89? + + +! SOLUTION +! -------- + +digits [ sq ] sigma ; + +: chain-ending ( n -- m ) + dup 1 = over 89 = or [ next-link chain-ending ] unless ; + +: lower-endings ( -- seq ) + 567 [1,b] [ chain-ending ] map ; + +: fast-chain-ending ( seq n -- m ) + dup 567 > [ next-link ] when 1- swap nth ; + +PRIVATE> + +: euler092 ( -- answer ) + lower-endings 9999999 [1,b] [ fast-chain-ending 89 = ] with count ; + +! [ euler092 ] time +! 68766 ms run / 372 ms GC time + +! TODO: solution is still too slow, maybe try using a 10000000-byte array that +! keeps track of each number in the chain and their endings + +MAIN: euler092 diff --git a/extra/project-euler/common/common.factor b/extra/project-euler/common/common.factor index af03662061..09d5f1442d 100644 --- a/extra/project-euler/common/common.factor +++ b/extra/project-euler/common/common.factor @@ -14,7 +14,7 @@ IN: project-euler.common ! log10 - #25, #134 ! max-path - #18, #67 ! nth-triangle - #12, #42 -! number>digits - #16, #20, #30, #34 +! number>digits - #16, #20, #30, #34, #35, #38, #43, #52, #55, #56, #92 ! palindrome? - #4, #36, #55 ! pandigital? - #32, #38 ! pentagonal? - #44, #45 @@ -78,7 +78,7 @@ PRIVATE> ] if ; : number>digits ( n -- seq ) - number>string string>digits ; + [ dup zero? not ] [ 10 /mod ] [ ] unfold reverse nip ; : nth-triangle ( n -- n ) dup 1+ * 2 / ; diff --git a/extra/project-euler/project-euler.factor b/extra/project-euler/project-euler.factor index b2d6e7e68a..8cf36d6f44 100644 --- a/extra/project-euler/project-euler.factor +++ b/extra/project-euler/project-euler.factor @@ -15,8 +15,8 @@ USING: definitions io io.files kernel math math.parser project-euler.ave-time project-euler.041 project-euler.042 project-euler.043 project-euler.044 project-euler.045 project-euler.048 project-euler.052 project-euler.053 project-euler.056 project-euler.067 project-euler.075 project-euler.079 - project-euler.097 project-euler.134 project-euler.169 project-euler.173 - project-euler.175 ; + project-euler.092 project-euler.097 project-euler.134 project-euler.169 + project-euler.173 project-euler.175 ; IN: project-euler