using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Solve(1);
Solve(2);
}
static void Solve(int pQuestionNo)
{
//座標を設定
if (pQuestionNo == 1) DerivePointArrQ1();
else DerivePointArrQ2();
int UB = mPointArr.GetUpperBound(0);
int AnswerCnt = 0;
for (int I = 0; I <= UB; I++) {
for (int J = I + 1; J <= UB; J++) {
for (int K = J + 1; K <= UB; K++) {
if (IsSeisankakukei(mPointArr[I], mPointArr[J], mPointArr[K]) == false)
continue;
Console.WriteLine("解{0}を発見", ++AnswerCnt);
if (pQuestionNo == 1) PrintAnswerQ1(I, J, K);
else PrintAnswerQ2(I, J, K);
}
}
}
}
struct Point
{
internal int X;
internal int YRoot3;
}
static Point[] mPointArr;
//座標を設定(Q1用)
static void DerivePointArrQ1()
{
var WillReturn = new List<Point>();
WillReturn.Add(new Point() { X = 0, YRoot3 = 0 });
for (int I = -1; I <= 1; I += 2)
WillReturn.Add(new Point() { X = I, YRoot3 = 1 });
for (int I = -2; I <= 2; I += 2)
WillReturn.Add(new Point() { X = I, YRoot3 = 2 });
for (int I = -3; I <= 3; I += 2)
WillReturn.Add(new Point() { X = I, YRoot3 = 3 });
mPointArr = WillReturn.ToArray();
}
//座標を設定(Q2用)
static void DerivePointArrQ2()
{
var WillReturn = new List<Point>();
WillReturn.Add(new Point() { X = 0, YRoot3 = 0 });
for (int I = -1; I <= 1; I += 2)
WillReturn.Add(new Point() { X = I, YRoot3 = 1 });
for (int I = -6; I <= 6; I += 2)
WillReturn.Add(new Point() { X = I, YRoot3 = 2 });
for (int I = -5; I <= 5; I += 2)
WillReturn.Add(new Point() { X = I, YRoot3 = 3 });
for (int I = -4; I <= 4; I += 2)
WillReturn.Add(new Point() { X = I, YRoot3 = 4 });
for (int I = -5; I <= 5; I += 2)
WillReturn.Add(new Point() { X = I, YRoot3 = 5 });
for (int I = -6; I <= 6; I += 2)
WillReturn.Add(new Point() { X = I, YRoot3 = 6 });
for (int I = -1; I <= 1; I += 2)
WillReturn.Add(new Point() { X = I, YRoot3 = 7 });
WillReturn.Add(new Point() { X = 0, YRoot3 = 8 });
mPointArr = WillReturn.ToArray();
}
//座標3つを引数として正三角形かを判定
static bool IsSeisankakukei(Point p1, Point p2, Point p3)
{
//三辺の長さが等しければ正三角形
int Kyori1 = DeriveKyori2Jyou(p1, p2);
int Kyori2 = DeriveKyori2Jyou(p1, p3);
int Kyori3 = DeriveKyori2Jyou(p2, p3);
if (Kyori1 != Kyori2) return false;
if (Kyori1 != Kyori3) return false;
return true;
}
//2点間の距離の2乗を求める
static int DeriveKyori2Jyou(Point p1, Point p2)
{
int wkX = Math.Abs(p1.X - p2.X);
int wkYRoot3 = Math.Abs(p1.YRoot3 - p2.YRoot3);
return wkX * wkX + wkYRoot3 * wkYRoot3 * 3;
}
//解を出力(Q1用)
static void PrintAnswerQ1(int p1, int p2, int p3)
{
var sb = new System.Text.StringBuilder();
Func<int, char> wkFunc = pInt =>
(pInt == p1 || pInt == p2 || pInt == p3) ? '●' : '・';
sb.AppendFormat(" {0}", wkFunc(0));
sb.AppendLine();
sb.AppendFormat(" {0}{1}", wkFunc(1), wkFunc(2));
sb.AppendLine();
sb.AppendFormat(" {0}{1}{2}", wkFunc(3), wkFunc(4), wkFunc(5));
sb.AppendLine();
sb.AppendFormat("{0}{1}{2}{3}", wkFunc(6), wkFunc(7), wkFunc(8), wkFunc(9));
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
//解を出力(Q2用)
static void PrintAnswerQ2(int p1, int p2, int p3)
{
var sb = new System.Text.StringBuilder();
Func<int, char> wkFunc = pInt =>
(pInt == p1 || pInt == p2 || pInt == p3) ? '●' : '・';
sb.AppendFormat(" {0}", wkFunc(0));
sb.AppendLine();
sb.AppendFormat(" {0}{1}", wkFunc(1), wkFunc(2));
sb.AppendLine();
for (int I = 3; I <= 9; I++) sb.Append(wkFunc(I));
sb.AppendLine();
sb.Append(" ");
for (int I = 10; I <= 15; I++) sb.Append(wkFunc(I));
sb.AppendLine();
sb.Append(" ");
for (int I = 16; I <= 20; I++) sb.Append(wkFunc(I));
sb.AppendLine();
sb.Append(" ");
for (int I = 21; I <= 26; I++) sb.Append(wkFunc(I));
sb.AppendLine();
for (int I = 27; I <= 33; I++) sb.Append(wkFunc(I));
sb.AppendLine();
sb.AppendFormat(" {0}{1}", wkFunc(34), wkFunc(35));
sb.AppendLine();
sb.AppendFormat(" {0}", wkFunc(36));
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
}