From 4dfc151c89c04828d0beabf3a701deeaad48146d Mon Sep 17 00:00:00 2001 From: Aaron Schaefer Date: Thu, 7 Feb 2008 19:48:00 -0500 Subject: [PATCH] Solution to Project Euler problem 79 --- extra/project-euler/079/079.factor | 65 ++++++++++++++++++++++++ extra/project-euler/079/keylog.txt | 50 ++++++++++++++++++ extra/project-euler/project-euler.factor | 4 +- 3 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 extra/project-euler/079/079.factor create mode 100644 extra/project-euler/079/keylog.txt diff --git a/extra/project-euler/079/079.factor b/extra/project-euler/079/079.factor new file mode 100644 index 0000000000..d28484c881 --- /dev/null +++ b/extra/project-euler/079/079.factor @@ -0,0 +1,65 @@ +! Copyright (c) 2008 Aaron Schaefer. +! See http://factorcode.org/license.txt for BSD license. +USING: assocs hashtables io.files kernel math math.parser namespaces sequences ; +IN: project-euler.079 + +! http://projecteuler.net/index.php?section=problems&id=79 + +! DESCRIPTION +! ----------- + +! A common security method used for online banking is to ask the user for three +! random characters from a passcode. For example, if the passcode was 531278, +! they may asked for the 2nd, 3rd, and 5th characters; the expected reply would +! be: 317. + +! The text file, keylog.txt, contains fifty successful login attempts. + +! Given that the three characters are always asked for in order, analyse the +! file so as to determine the shortest possible secret passcode of unknown +! length. + + +! SOLUTION +! -------- + +edges ( seq -- seq ) + [ + [ string>digits [ 2 head , ] keep 2 tail* , ] each + ] { } make ; + +: find-source ( seq -- elt ) + dup values swap keys [ prune ] 2apply seq-diff + dup empty? [ "Topological sort failed" throw ] [ first ] if ; + +: remove-source ( seq elt -- seq ) + [ swap member? not ] curry subset ; + +: (topological-sort) ( seq -- ) + dup length 1 > [ + dup find-source dup , remove-source (topological-sort) + ] [ + dup empty? [ drop ] [ first [ , ] each ] if + ] if ; + +PRIVATE> + +: topological-sort ( seq -- seq ) + [ [ (topological-sort) ] { } make ] keep + concat prune dupd seq-diff append ; + +: euler079 ( -- answer ) + source-079 >edges topological-sort 10 swap digits>integer ; + +! [ euler079 ] 100 ave-time +! 2 ms run / 0 ms GC ave time - 100 trials + +! TODO: prune and seq-diff are relatively slow; topological sort could be +! cleaned up and generalized much better, but it works for this problem + +MAIN: euler079 diff --git a/extra/project-euler/079/keylog.txt b/extra/project-euler/079/keylog.txt new file mode 100644 index 0000000000..b6f9903128 --- /dev/null +++ b/extra/project-euler/079/keylog.txt @@ -0,0 +1,50 @@ +319 +680 +180 +690 +129 +620 +762 +689 +762 +318 +368 +710 +720 +710 +629 +168 +160 +689 +716 +731 +736 +729 +316 +729 +729 +710 +769 +290 +719 +680 +318 +389 +162 +289 +162 +718 +729 +319 +790 +680 +890 +362 +319 +760 +316 +729 +380 +319 +728 +716 diff --git a/extra/project-euler/project-euler.factor b/extra/project-euler/project-euler.factor index 36a9069d77..c3db60c481 100644 --- a/extra/project-euler/project-euler.factor +++ b/extra/project-euler/project-euler.factor @@ -14,8 +14,8 @@ USING: definitions io io.files kernel math math.parser project-euler.ave-time project-euler.037 project-euler.038 project-euler.039 project-euler.040 project-euler.041 project-euler.042 project-euler.043 project-euler.044 project-euler.048 project-euler.052 project-euler.067 project-euler.075 - project-euler.097 project-euler.134 project-euler.169 project-euler.173 - project-euler.175 ; + project-euler.079 project-euler.097 project-euler.134 project-euler.169 + project-euler.173 project-euler.175 ; IN: project-euler