challenge 四字熟語パズルの作成

与えられた四字熟語のリストから下のように四角く配置することのできる熟語の組み合わせを探すプログラムを作成してください。

出力例:

無憂無風
礼  林
千  火
万水千山

知行合一
者  筆
不  勾
言語道断

四字熟語は左から右、上から下へ読むものとします。また右上隅の漢字と左下隅の漢字は異なるものでなければいけません。

四字熟語のデータは扱いやすい形(たとえばユニコード文字列のリスト)で与えられていると仮定して構いません。サンプルデータが必要であれば FOR Microsoft IME The四字熟語辞典(データ / 文書作成) にテキスト形式のデータが入っているのでそれを使えると思います。

問題の規模の参考までに、40行程度のPythonスクリプトでこのデータ(重複をのぞいて8312件)を処理してみたところ2.4GHzのCPUで13秒程度かかりました。結果は8133件出力されました。

Posted feedbacks - Prolog

12116組となりました。
件数が違うことが気になったので、Prologバカサーチで件数を確認しました。
12118件との差異は、
/一切即一/一唱三嘆/一読三嘆/嘆息嗟嘆/
/一切即一/一場春夢/一炊之夢/夢中説夢/
の2件について、それぞれ2パターン生成できるのですが、それをどう数えるかによります。
プログラムの結果として生成するresultというファイルは12118件、しかし、sort|uniqに相当する操作の結果の件数(リストの長さ)は12116となります。
さて、題意はどちらだったのでしょう?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
:-dynamic(for4/4).
for4:-
    reader,
    tell('result'),
    setof(F,match(F),M),
    seen,
    length(M,L),display(L),ttynl.
reader:-
    see('for4.txt'),
    repeat, getln(L), parse(L), L==[],!,
    seen.
parse([C|L]):-C\=0'    ,!,parse(L).
parse([_,C1,C2,C3,C4|_]):-for4(C1,C2,C3,C4),!.
parse([_,C1,C2,C3,C4|_]):-!,
    asserta(for4(C1,C2,C3,C4)).
parse([]).

match(F):-
    for4(A1,A2,A3,A4),
    for4(A1,B2,B3,B4), A4>B4,
    for4(A4,C2,C3,C4),
    for4(B4,D2,D3,C4),
     F0=[
    for4(A1,A2,A3,A4),
    for4(A1,B2,B3,B4),
    for4(A4,C2,C3,C4),
    for4(B4,D2,D3,C4)],
    sort(F0,F),
    pp(F).
pp([for4(X1,X2,X3,X4)|L]):-!,
    put(0'/),put(X1), put(X2), put(X3), put(X4),
    pp(L).
pp([]):-put(0'/),nl.

Index

Feed

Other

Link

Pathtraq

loading...