challenge 四字熟語パズルの作成

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

出力例:

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

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

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

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

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

Posted feedbacks - Perl

熟語データはeuc-jpのin.txt

Celeron2.4GHzで8.6秒ほどかかって12118件でした。

40行目は鏡像のチェックです
 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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/local/bin/perl

use strict;
use warnings;

use encoding 'euc-jp';

open( my $file, "<:encoding(euc-jp)", "in.txt" ) or die;
my @words;
my %left_right_list;    #1文字目をキーにしたテーブル
my %bottom_list;        #1,4文字目をキーにしたテーブル
for my $word (<$file>)
{
    chomp $word;
    push @words, $word;
    my ( $char_0, $char_3 ) = ( split //, $word )[ 0, 3 ];
    push @{ $left_right_list{$char_0} }, $word;
    push @{ $bottom_list{"$char_0$char_3"} }, $word;
}
close $file;

my $counter;
my %seen;
for my $top (@words)
{
    my ( $top_char_0, $top_char_3 ) = ( split //, $top )[ 0, 3 ];

    for my $left ( @{ $left_right_list{$top_char_0} } )
    {
        next if $top eq $left;
        my $left_char_3 = substr $left, 3, 1;
        next if $top_char_3 eq $left_char_3;

        for my $right ( @{ $left_right_list{$top_char_3} } )
        {
            my $right_char_3 = substr $right, 3, 1;

            for my $bottom ( @{ $bottom_list{"$left_char_3$right_char_3"} } )
            {
                next if $seen{"$left$top$bottom$right"};
                $seen{"$top$left$right$bottom"} = 1;
                print "$top $left $right $bottom\n";
                print substr( $left, 1, 1 ), " ", " ", substr( $right, 1, 1 ), "\n";
                print substr( $left, 2, 1 ), " ", " ", substr( $right, 2, 1 ), "\n";
                print "$bottom\n";
                print "--------\n";
                $counter++;
            }
        }
    }
}
print "$counter\n";

Index

Feed

Other

Link

Pathtraq

loading...