using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
const int UB = 4 - 1;
struct JyoutaiDef
{
internal int CurrX;
internal int CurrY;
internal int[,] BillArr;
}
static void Main()
{
var stk = new Stack<JyoutaiDef>();
JyoutaiDef WillPush;
WillPush.CurrX = WillPush.CurrY = 0;
for (int I = 1; I <= 4; I++) {
WillPush.BillArr = new int[UB + 1, UB + 1];
WillPush.BillArr[0, 0] = I;
stk.Push(WillPush);
}
int AnswerCnt = 0;
while (stk.Count > 0) {
JyoutaiDef Popped = stk.Pop();
//X座標の繰上げ処理
if (++Popped.CurrX > UB) {
Popped.CurrX = 0;
Popped.CurrY++;
}
//クリア判定
if (Popped.CurrY > UB) {
if (CanSeeBillsCnt(new int[]{Popped.BillArr[3,0],Popped.BillArr[2,0],
Popped.BillArr[1,0],Popped.BillArr[0,0]}) != 2) continue;
if (CanSeeBillsCnt(new int[]{Popped.BillArr[0,1],Popped.BillArr[1,1],
Popped.BillArr[2,1],Popped.BillArr[3,1]}) != 3) continue;
if (CanSeeBillsCnt(new int[]{Popped.BillArr[1,3],Popped.BillArr[1,2],
Popped.BillArr[1,1],Popped.BillArr[1,0]}) != 2) continue;
if (CanSeeBillsCnt(new int[]{Popped.BillArr[3,3],Popped.BillArr[3,2],
Popped.BillArr[3,1],Popped.BillArr[3,0]}) != 3) continue;
Console.WriteLine("解{0}を発見", ++AnswerCnt);
PrintAnswer(Popped.BillArr);
continue;
}
for (int I = 1; I <= 4; I++) {
bool IsUsed = false;
//横方向で使用してないこと
for (int X = 0; X <= UB; X++) {
if (Popped.BillArr[X, Popped.CurrY] == I) {
IsUsed = true;
break;
}
}
//縦方向で使用してないこと
for (int Y = 0; Y <= UB; Y++) {
if (Popped.BillArr[Popped.CurrX, Y] == I) {
IsUsed = true;
break;
}
}
if (IsUsed == false) {
WillPush.CurrX = Popped.CurrX;
WillPush.CurrY = Popped.CurrY;
WillPush.BillArr = (int[,])Popped.BillArr.Clone();
WillPush.BillArr[Popped.CurrX, Popped.CurrY] = I;
stk.Push(WillPush);
}
}
}
}
//見えるビルの数を判定
static int CanSeeBillsCnt(int[] pBillArr)
{
int WillReturn = 1;
int CurrMaxHeight = pBillArr[0];
//最大値を超えたらインクリメント
for (int I = 1; I <= UB; I++) {
if (CurrMaxHeight < pBillArr[I]) {
CurrMaxHeight = pBillArr[I];
WillReturn++;
}
}
return WillReturn;
}
//解を出力
static void PrintAnswer(int[,] pBillArr)
{
var sb = new System.Text.StringBuilder();
for (int Y = 0; Y <= UB; Y++) {
for (int X = 0; X <= UB; X++) {
sb.Append(pBillArr[X, Y]);
}
sb.AppendLine();
}
Console.WriteLine(sb.ToString());
}
}