USING: accessors html.parser.analyzer io kernel math namespaces
present regexp sequences ;
IN: all-roads-to-wiki
SYMBOL: G
: match-good-pages (a -- ?/f)
R/ \/wiki\/[^:]*$/ first-match ;
: filter-urls (tags -- urls)
find-hrefs [ present ] map
[ match-good-pages ] filter
[ match-good-pages seq>> ] map ;
: findpath (url -- url)
G get =
[
! false
]
[ scrape-html nip
[
dup "title" find-by-name drop 1 + swap nth
text>> R/ - Wikipedia,/ re-split first print
]
[
"bodyContent" find-by-id-between filter-urls [ findpath ] map
] bi
] if ; inline recursive
: allroads-entry (-- a)
readln "http://en.wikipedia.org/wiki/" prepend G set-global
"enwp.org/Special:Random" findpath ; inline
上記のコードは、探しているものが見つかるまで、ウィキペディアのすべてのリンクで繰り返されます。複雑な再帰的スタック効果?
findpath
は、最終的には "戻る"(すなわち、再び呼び出されない)ため、巨大なネストされたデータ構造をスタックに残すので、大丈夫です。しかし、私はこれをコンパイルしようとすると、私はunbalanced-recursion
エラーを取得:
The recursive word “findpath” leaves with the stack having the wrong height
unbalanced-recursion
: Thrown when stack effect inference determines that an inline recursive word has an incorrect stack effect declaration.
をどんなに私は何をすべきか、ファクター(当然)が、最大一致しないスタック効果文句ありません。これを適切に再発させるにはどうすればよいですか?
偽のブランチに 'drop f'を、正しく理解していれば、リストの偽物を取り除くために' sift'を使います。 2つ目は 'G get ='の前に 'dup'がないと思います(=がURLを消費するため)。 3-再帰が終了するのは確かですか?リストは永遠に成長しないでしょうか? –
これは、リンクのグラフ上での深さ優先検索のようなものではありませんか?どこかでサイクルが見つかると、永遠にそこに詰め込まれるでしょう! @fedes。 –
@fedes。あなたはおそらく正しいでしょうが、再帰的ソリューションのように動作するはずです:http://codegolf.stackexchange.com/questions/34662/find-a-route-between-ww-wikipedia-articles – cat