わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

ぷよぷよ2連鎖171種類!

  • 「2連鎖」の状態を100種類以上,書いてください.

(略)

  • 最初(1連鎖目)はちょうど4個消え,2連鎖目もちょうど4個消えます.
  • 消える4個+4個以外のぷよ(おじゃまぷよを含む)は使用しません.
  • フィールドは6列です(7列を使う連鎖は,認めません).
  • 鏡像は同一とします.
  • 組み方や発火点が違っていても,消去を始める状態が同じなら,同一とします.
  • 1組のぷよを置いて,消去を始めるという状態に限定します.
  • 1連鎖目のぷよは「1」,2連鎖目のぷよは「2」で表記します.
  • プログラムで生成するのではなく,手で(テキストエディタで)一つ一つ書きます.
ぷよぷよ2連鎖100種類 - わさっき

プログラムで生成してみました.いつもならRubyのソースを出して,解説してから,実行結果としていますが,今回は規模が大きいので見送ります.それでも少しは解説を.
フィールドを2次元配列で保持した上で,消去判定(4個以上くっついているかの判定)や消去・落下処理は,過去にCで書いたり授業にしたりしているので,Rubyでも問題なく作成できました.
その連鎖シュミレータを足がかりに,「1」を4個と「2」を4個,ランダムに並べて,最初に「1」,次に「2」が消える2連鎖になり,かつ発火点を持つ(どこか1組のぷよを取り除けば,消去が起こらない状態になっている)ものを検査するコードも,書けました.
あとは全組み合わせを生成すれば,それぞれを上記の検査コードに通して,OKになるものを解として出力するわけです.生成方法は,手書きのときと同じで,『最下段が何になるかで場合分けしてから,それぞれでパターンを漏れなくダブりなく,書いていきました』.
具体例を.本日は,ぷよの文字を半角で表現しています.

 2 
 2 
 2 
 11
112

このフィールド状態を,「112, :1222:1」で表します.カンマの前の112は,最下段を左から右に並べたもの,:1222:1はコロン区切りで,列ごとに,下から上にどの文字を置くかを指示したものです.この例では以下のようになります.

  • 最初の:の左には何もないので,左端最下段の1の上には,何も積まれません.
  • 最初の:の右は1222となっているので,左から2列目は,最下段の1の上に,1,2,2,2と積みます.
  • 2番目の:の右は2となっているので,左から3列目は,最下段の2の上に,2を積みます.

生成方法は後回しにして,鏡像チェックについて書いておきます.2種類行います.まず最下段のチェックです.これは最下段文字列,上の例なら「112」と,それを反転した「211」とを比較して,もとのほうが小さいか等しければ採用,大きければ棄却します.
次に,最下段文字列とその反転したものが等しい,すなわち最下段でぷよが左右対称に配置している場合には,それより上の置き方でも,鏡像チェックが必要となります.別の例を出しますと…

 2 
 1 
 1 
11 
222

これは「222, 1:1112:」という表現になります.「1:1112:」を,コロン単位(文字単位ではなく)で反転すると,「:1112:1」となります.これは以下のように,もとのと左右対称なフィールドを意味します.

 2 
 1 
 1 
 11
222

ということで,コロン区切りの文字列(この例だと「1:1112:」)と,それをコロン単位で反転させたもの(同「:1112:1」)を文字列比較して,候補のほうが小さいか等しければ採用,大きければ棄却しました.
生成については,4個+4個に限定しないことにしました.任意の文字列を入力にとります.内部では,1文字単位に分割*1してから,最下段に置く個数(列数),具体的には1から6までのそれぞれについて,その個数だけ順に抽出します.鏡像チェックを通れば,残りの各文字と,列数マイナス1個の「:」について,順列を作ります.文字列化して,最下段が対称形ならここでも鏡像チェックを行います.これが通れば(もしくは最下段が対称でないか,1列しかないときには,2度目の鏡像チェックを行うことなく),2連鎖かどうか検査すべきフィールドの完成です.
ここで,最下段の「順に抽出」と,2段目移行の「順列」は,重複に注意した順列となります.自作するより,既存のものを探しました.[ruby-list:37550]順列イテレータのArray#perm2が,希望するものなので,使用しました.Ruby 1.9でも問題なく動作しました.
それともう一つ,フィールドに置くべきぷよの文字のリスト(4個+4個なら,1,1,1,1,2,2,2,2)から,最下段の文字を取り除く処理が必要なことに気づきました.Array#- は,配列の要素を集合と見なして,集合差を求めるもののようで,irbで確認すると

$ irb
irb(main):001:0> [1,1,1,1,2,2,2,2]-[2,2,2]
=> [1, 1, 1, 1]
irb(main):002:0> [1,1,1,1,2,2,2,2]-[1,1,2]
=> []

となります.メソッドを定義してもよかったのですが,http://f52.aaa.livedoor.jp/~maraigue/multiset/を利用しました.
実行結果です.4個+4個の全パターンについては,前回との比較のため,すべて載せます.

No.1
2
1
1
1
1
2
2
2
No.2
2 
2 
2 
1 
12
11
No.3
2 
1 
12
12
12
No.4
2 
2 
2 
1 
11
12
No.5
2 
2 
12
11
12
No.6
2 
2 
11
12
12
No.7
22
12
11
12
No.8
22
11
12
12
No.9
 2
 2
12
11
12
No.10
 2
 2
11
12
12
No.11
2 
2 
21
11
12
No.12
22
21
11
12
No.13
 2
 2
21
11
12
No.14
 2
 2
 2
 1
11
12
No.15
2 
1 
1 
1 
12
22
No.16
2 
2 
1 
1 
11
22
No.17
2 
1 
12
11
22
No.18
2 
1 
11
12
22
No.19
12
12
11
22
No.20
12
11
12
22
No.21
2 
2 
11
11
22
No.22
22
11
11
22
No.23
21
11
12
22
No.24
 2
 1
11
12
22
No.25
2 
1 
1 
1 
1 
2 
22
No.26
2  
2  
2  
12 
111
No.27
2  
2  
122
111
No.28
2 2
122
111
No.29
22 
212
111
No.30
 2 
 2 
 2 
21 
111
No.31
 2 
 2 
212
111
No.32
2  
2  
1  
12 
112
No.33
2  
12 
12 
112
No.34
2  
1  
122
112
No.35
 2 
12 
12 
112
No.36
2  
22 
11 
112
No.37
 2 
22 
11 
112
No.38
22 
112
112
No.39
 2 
 2 
 2 
11 
112
No.40
 2 
 2 
112
112
No.41
 2 
21 
21 
112
No.42
22 
211
112
No.43
 2 
 2 
 1 
21 
112
No.44
 2 
 1 
212
112
No.45
 2 
 2 
211
112
No.46
 22
211
112
No.47
 2 
 2 
 2 
 1 
 1 
112
No.48
 2 
 2 
 1 
 12
112
No.49
 2 
 12
 12
112
No.50
 2 
 2 
 2 
 11
112
No.51
 2 
 22
 11
112
No.52
  2
 22
 11
112
No.53
  2
  2
  2
 11
112
No.54
2  
1  
1  
12 
122
No.55
2  
1  
1  
1 2
122
No.56
2  
2  
1  
11 
122
No.57
2  
12 
11 
122
No.58
2  
1  
112
122
No.59
2  
11 
12 
122
No.60
 2 
12 
11 
122
No.61
12 
112
122
No.62
 2 
11 
12 
122
No.63
2  
21 
11 
122
No.64
2  
2  
111
122
No.65
 2 
21 
11 
122
No.66
21 
112
122
No.67
22 
111
122
No.68
2 2
111
122
No.69
 2 
 2 
 1 
11 
122
No.70
 2 
 1 
112
122
No.71
 2 
 2 
111
122
No.72
 22
111
122
No.73
  2
  2
111
122
No.74
2  
12 
11 
212
No.75
 2 
12 
11 
212
No.76
12 
112
212
No.77
 2 
21 
11 
212
No.78
22 
111
212
No.79
 2 
 2 
 1 
11 
212
No.80
 2 
 1 
112
212
No.81
 2 
 2 
111
212
No.82
 2 
11 
21 
212
No.83
 2 
 1 
 1 
21 
212
No.84
2  
1  
1  
1  
1  
222
No.85
2  
1  
1  
11 
222
No.86
1  
12 
11 
222
No.87
2  
11 
11 
222
No.88
2  
1  
111
222
No.89
 2 
11 
11 
222
No.90
12 
111
222
No.91
1 2
111
222
No.92
 1 
21 
11 
222
No.93
21 
111
222
No.94
 2 
 1 
 1 
11 
222
No.95
 2 
 1 
111
222
No.96
 2 
 1 
 1 
 1 
 1 
222
No.97
2   
122 
1112
No.98
 2  
122 
1112
No.99
  2 
122 
1112
No.100
  2 
  2 
1 2 
1112
No.101
 2  
212 
1112
No.102
  2 
221 
1112
No.103
 2  
 2  
 12 
1112
No.104
 22 
 12 
1112
No.105
 2  
 122
1112
No.106
  2 
  2 
 12 
1112
No.107
 22 
 21 
1112
No.108
  2 
  2 
 21 
1112
No.109
  2 
 212
1112
No.110
  2 
  2 
  2 
  1 
1112
No.111
  2 
  2 
  12
1112
No.112
2   
1   
12  
1122
No.113
12  
12  
1122
No.114
1   
12 2
1122
No.115
22  
11  
1122
No.116
 2  
 2  
11  
1122
No.117
 2  
112 
1122
No.118
 2  
11 2
1122
No.119
 2  
 1  
21  
1122
No.120
 2  
211 
1122
No.121
 2  
 2  
 1  
 1  
1122
No.122
 2  
 1  
 12 
1122
No.123
 2  
 1  
 1 2
1122
No.124
 2  
 2  
 11 
1122
No.125
 22 
 11 
1122
No.126
 2  
 112
1122
No.127
  2 
  2 
 11 
1122
No.128
  2 
 112
1122
No.129
2   
1   
1   
1   
1222
No.130
2   
1   
11  
1222
No.131
12  
11  
1222
No.132
21  
11  
1222
No.133
2   
111 
1222
No.134
 2  
 1  
11  
1222
No.135
 2  
111 
1222
No.136
  2 
111 
1222
No.137
 2  
112 
2112
No.138
 2  
 1  
 12 
2112
No.139
 22 
 11 
2112
No.140
12  
11  
2122
No.141
 2  
 1  
11  
2122
No.142
 2  
111 
2122
No.143
 2  
 1  
 1  
 1  
2122
No.144
 2  
 1  
 11 
2122
No.145
 21 
 11 
2122
No.146
 2  
 111
2122
No.147
 222 
11112
No.148
  2  
  22 
11112
No.149
   2 
  22 
11112
No.150
   2 
   2 
   2 
11112
No.151
122  
11122
No.152
  2  
1 2  
11122
No.153
1 2 2
11122
No.154
 2   
 12  
11122
No.155
  2  
 12  
11122
No.156
 12 2
11122
No.157
  2  
 21  
11122
No.158
  2  
  2  
  1  
11122
No.159
  2  
  12 
11122
No.160
  2  
  1 2
11122
No.161
1    
12   
11222
No.162
 2   
11   
11222
No.163
 2   
 1   
 1   
11222
No.164
 2   
 11  
11222
No.165
  2  
 11  
11222
No.166
  22  
111122
No.167
   2  
   2  
111122
No.168
   2 2
111122
No.169
1 2   
111222
No.170
 12   
111222
No.171
  2   
  1   
111222

手書きの前回は138でしたので,30個ほど,漏れがあったということです.最下段が「111122」という消し方は,完全に見落としていました.
せっかく,4個+4個に限定しないことにしたのですから,別のも試しました.
1連鎖目に「1」がちょうど5個消え,2連鎖目も「2」がちょうど5個消えるパターンです.482種類ありました.最初と最後のほか,途中を100単位で抜き出しています.

No.1
22
11
12
12
12
No.100
 2 
 2 
11 
112
212
No.200
22  
2111
1122
No.300
 22 
1111
2122
No.400
 2   
 2   
 111 
11222
No.482
  2   
111   
121222

4個+4個+4個の3連鎖も,試しました.8204通りと出ました.こちらは1000番単位で.

No.1
3 
3 
3 
2 
2 
2 
13
11
12
No.1000
 2 
 2 
 23
 13
112
133
No.2000
 2 
31 
211
231
233
No.3000
  2 
  2 
 323
 132
1113
No.4000
1233
1122
1332
No.5000
 3  
 2  
11  
31  
21  
2233
No.6000
  23 
  33 
 312 
11122
No.7000
 3   
 2   
 2   
 2   
 1   
 11  
21333
No.8000
 233  
 111  
212233
No.8204
  3   
  2   
  1111
222333

解の数と作業量を,表にしました.

4個+4個 5個+5個 4個+4個+4個
解の数 171 482 8204
検査対象の数 4294 48426 17768208
実行時間 約5秒 約30秒 約2時間

*1:そういえば「分割する」を「バラす」と言わなくなったなあ….