Comment detail

島の数をカウントする (Nested Flatten)
初投稿です。
変態的な実装ができないかと考えていたのですが、
最適化していくうちに#8104さんと似た考え方になってしまいました。
秀丸の新規窓の左上に島を書いて、マクロ実行です。

考え方は以下の通りです。
1.左上から右下に向かって横にスキャン
2.上と左の島連番取得
3.取得出来なければ新しい島&島数プラス
4.上と左の島連番が一致しない場合、左の島連番を塗り直し&島数マイナス
 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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#xcharlen=2;
$wchar="□";
$bchar="■";

#xlen=4;
#ylen=4;

#wcnt=0;
#bcnt=0;
##x=0;
##y=0;
##serial=1;

    while( ##y < #ylen ) {
        ##x=0;
        while( ##x < #xlen ) {
            call GETCHAR ##x, ##y;
            $$c = $$return;
            if( ##y == 0 ) {
                ##no = ##serial;
            } else {
                call GETCHAR ##x, ##y-1;
                if( $$return == $$c ) {
                    ##no = #mtx[##y-1][##x];
                } else {
                    ##no = ##serial;
                }
            }
            if( ##x > 0 ) {
                call GETCHAR ##x-1, ##y;
                if( $$return == $$c ) {
                    if( ##no == ##serial ) {
                        ##no = #mtx[##y][##x-1];
                    } else if( ##no != #mtx[##y][##x-1] ) {
                        call RENUM ##no, #mtx[##y][##x-1], ##y, $$c;
                    }
                }
            }
            #mtx[##y][##x] = ##no;
            if( ##no == ##serial ) {
                call CNTISLAND $$c, 1;
                ##serial = ##serial+1;
            }
            ##x = ##x+1;
        }
        ##y = ##y+1;
    }

    message "白の島は" + str(#wcnt) + "つ\n" + "黒の島は" + str(#bcnt) + "つ";

    endmacro;

RENUM:
    ##i=0;
    while( ##i < ##3+1 ) {
        ##j=0;
        while( ##j < #xlen ) {
            if( #mtx[##i][##j]==##2 ) {
                #mtx[##i][##j]=##1;
            }
            ##j=##j+1;
        }
        ##i=##i+1;
    }

    call CNTISLAND $$4, -1;

    return;

CNTISLAND:
    if( $$1 == $wchar ) {
        #wcnt=#wcnt+##2;
    } else {
        #bcnt=#bcnt+##2;
    }

    return;

GETCHAR:
    ##x1 = ##1 * #xcharlen;
    ##x2 = ##x1 + #xcharlen;
    $$res=gettext(##x1, ##2, ##x2, ##2, 0);

    return $$res;

調べる位置が、右と下 左と上の違い なのでそんな大差はないのかもしれないけど、 スキャンする方向が、左上から右下ということを 考えると、#8104 より、こっちのほうが、島の塗り直しがシンプルでいいですね。

遅くなりましたがありがとうございます。 普通のやりかたも考えたのですが、秀丸マクロはサブルーチンのネストが20階層までらしいので、マップが広がった時に対応出来ないので、この方法に至りました。

Index

Feed

Other

Link

Pathtraq

loading...