2008-02-07 19:48:00 -05:00
|
|
|
! Copyright (c) 2008 Aaron Schaefer.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2008-02-16 23:17:41 -05:00
|
|
|
USING: assocs hashtables io.files kernel math math.parser namespaces
|
2008-04-14 03:40:32 -04:00
|
|
|
io.encodings.ascii sequences sets ;
|
2008-02-07 19:48:00 -05:00
|
|
|
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
|
|
|
|
! --------
|
|
|
|
|
|
|
|
<PRIVATE
|
|
|
|
|
|
|
|
: source-079 ( -- seq )
|
2008-05-06 13:37:11 -04:00
|
|
|
"resource:extra/project-euler/079/keylog.txt" ascii file-lines ;
|
2008-02-07 19:48:00 -05:00
|
|
|
|
|
|
|
: >edges ( seq -- seq )
|
|
|
|
[
|
|
|
|
[ string>digits [ 2 head , ] keep 2 tail* , ] each
|
|
|
|
] { } make ;
|
|
|
|
|
|
|
|
: find-source ( seq -- elt )
|
2008-07-20 02:13:46 -04:00
|
|
|
unzip diff prune
|
2008-02-07 19:48:00 -05:00
|
|
|
dup empty? [ "Topological sort failed" throw ] [ first ] if ;
|
|
|
|
|
|
|
|
: remove-source ( seq elt -- seq )
|
2008-04-26 00:17:08 -04:00
|
|
|
[ swap member? not ] curry filter ;
|
2008-02-07 19:48:00 -05:00
|
|
|
|
|
|
|
: (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
|
2008-04-26 03:01:43 -04:00
|
|
|
concat prune over diff append ;
|
2008-02-07 19:48:00 -05:00
|
|
|
|
|
|
|
: euler079 ( -- answer )
|
2008-02-07 20:25:03 -05:00
|
|
|
source-079 >edges topological-sort 10 digits>integer ;
|
2008-02-07 19:48:00 -05:00
|
|
|
|
|
|
|
! [ euler079 ] 100 ave-time
|
|
|
|
! 2 ms run / 0 ms GC ave time - 100 trials
|
|
|
|
|
2008-04-14 00:09:42 -04:00
|
|
|
! TODO: prune and diff are relatively slow; topological sort could be
|
2008-02-07 19:48:00 -05:00
|
|
|
! cleaned up and generalized much better, but it works for this problem
|
|
|
|
|
|
|
|
MAIN: euler079
|