challenge 四字熟語パズルの作成

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

出力例:

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

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

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

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

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

Posted feedbacks - Scala

12107件でした。kozimaさんと近いですね。
Athlon64 3000,メモリ1G,WinXPで出力含め15秒ほどでした。

ちなみに、Scalaのforはモナドのための記法として扱えます。
HashMap#getはOptionといういわゆるMaybeモナドですのでシンプルに書けます。
 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
34
35
36
import scala.io.Source.fromFile
import scala.collection.mutable.{HashMap,LinkedHashSet}

object JukugoPazzule {
  type S = LinkedHashSet[String]
  val jukugos = fromFile("kanji_uniq.txt").getLines.toList
  val headMap = (new HashMap[Char, S]() /: jukugos){(map, jukugo) => 
    map.getOrElseUpdate(jukugo(0), new S) += jukugo; map
  }

  def solve = {
    var i = 0
    var uniqChekMap = new S
    for(j1 <- jukugos;
        jlst2 <- headMap.get(j1(0));
        j2 <- jlst2 if j2 != j1;
        jlst3 <- headMap.get(j1(3));
        j3 <- jlst3 if j3!=j2 && j3!=j1 && j1(3)!=j2(3);
        jlst4 <- headMap.get(j2(3));
        j4 <- jlst4 if j4!=j3 && j4!=j2 && j4!=j1 && j4(3)==j3(3)
    ) {
      var all = List(j1,j2,j3,j4).sort(_<_).mkString("")
      if(!uniqChekMap.contains(all)) {
        print(j1)
        (1 to 2).foreach{i => println(j2(i)+"    "+j3(i))}
        println(j4)
        println("-----------------------")
        i = i+1
        uniqChekMap += all
      }
    }
    println(i)
  }
}

JukugoPazzule.solve

Index

Feed

Other

Link

Pathtraq

loading...