PHPでお絵かきロジックの任意の一行/一列分のスペースの全パターンを列挙する
開発環境は、Windows 7 Professional(32bit)+XAMPP v3.22+PHP 7.1.7。
お絵かきロジック
例えば、一行が15マスで、ある横のヒント数が3,1,1,3として、4つだった場合、スペースとして考えられるのは、5箇所(ヒント数+1)なので、5と指定。
次に、ヒント数の合計(3,1,1,3とすれば8)を一行の15マスから引いて、余りが7。
自作したtest関数では、第1引数に5を第2引数に7を入れると、その一行分のスペースの全パターンが取得できる。
ある一行分/一列分だけ実現するためには、for文を何重にもして作ればいいが、あらゆる行列に汎用的に対応するためには、再帰関数を作ったほうが良いので作った。頭がこんがらがりながらも、何とか作りました。
<?php /* 任意の1行/1列分のスペースの全パターンが列挙される。 $max - スペースの数 = ヒント数+1 $comma_sum - 余っているコマの合計 = 一列か行の枠の数 - ヒント数の合計 $count - 現在の階層を知る = 常に0。内部ではカウントしていく。 $p - 現在の位置を取得する $comma_sumは、数が少ない場合と多い場合は、組み合わせのパターンは少なくて、中央部分の 組み合わせのパターンは多い?正規分布みたいになる?合計が0と最大値はただ1つだけだ。 */ function test($max,$comma_sum,$count = 0,$p = null){ $frame_min = 0; $frame_max = 0; $count++; if(($count === 1 or $count === $max) and $max !== 2){ $frame_min = 0; $frame_max = $comma_sum; }else if(($count === 1 or $count === $max) and $max === 2){ # ヒント数が1つしかない場合 $frame_min = 0; $frame_max = $comma_sum+1; }else{ $frame_min = 1; $frame_max = $comma_sum; } for($i = $frame_min; $i < $frame_max; $i++){ if($count < $max){ test($max,$comma_sum,$count,$p.$i.","); }else{ $x = $p.$i; $arr = explode(",",$x); $sum = 0; for($s = 0; $s < count($arr); $s++){ $sum += $arr[$s]; } if($sum === $comma_sum){ echo $x."<br>"; } } } } test(5,7); ?>
動作結果はこちら、