using System;
using System.Collections.Generic;
class Program
{
struct RocketInfoDef
{
internal int RocketID;
internal char RocketName;
internal int NeedDays;
internal bool IsLeft;
internal bool IsMoveing;
internal int RestDays;
internal bool HasPilot1;
internal bool HasPilot2;
internal void Init(int pRocketID, char pRocketName, int pNeedDays)
{
RocketID = pRocketID;
RocketName = pRocketName;
NeedDays = pNeedDays;
IsLeft = true;
IsMoveing = false;
RestDays = 0;
HasPilot1 = HasPilot2 = false;
}
}
struct JyoutaiDef
{
internal int TotalDays;
internal bool IsPilot1Left;
internal bool IsPilot1Moveing;
internal bool IsPilot2Left;
internal bool IsPilot2Moveing;
internal bool CanHasshin; //ロケットが発進可能か?
internal RocketInfoDef[] RocketInfoArr;
internal List<string> LogList;
internal void Init()
{
TotalDays = 0;
IsPilot1Left = IsPilot2Left = true;
IsPilot1Moveing = IsPilot2Moveing = false;
CanHasshin = true;
RocketInfoArr = new RocketInfoDef[4];
RocketInfoArr[0].Init(0, '黒', 1);
RocketInfoArr[1].Init(1, '赤', 2);
RocketInfoArr[2].Init(2, '青', 4);
RocketInfoArr[3].Init(3, '白', 8);
LogList = new List<string>();
//AddOneLog();
}
internal void MakeKishiInfo(bool pIsLeftInfo, System.Text.StringBuilder pSb)
{
for (int I = 0; I <= RocketInfoArr.GetUpperBound(0); I++) {
if (RocketInfoArr[I].IsLeft == pIsLeftInfo && RocketInfoArr[I].IsMoveing == false) {
pSb.Append(RocketInfoArr[I].RocketName);
}
}
}
internal void MakeMidInfo(System.Text.StringBuilder pSb)
{
for (int I = 0; I <= RocketInfoArr.GetUpperBound(0); I++) {
if (RocketInfoArr[I].IsMoveing) {
string HasPilotInfo = "";
if (RocketInfoArr[I].HasPilot1 && RocketInfoArr[I].HasPilot2) HasPilotInfo = "1と2";
if (RocketInfoArr[I].HasPilot1 && !RocketInfoArr[I].HasPilot2) HasPilotInfo = "1のみ";
if (!RocketInfoArr[I].HasPilot1 && RocketInfoArr[I].HasPilot2) HasPilotInfo = "2のみ";
pSb.AppendFormat("{0}{1}(Pilot{2})残{3}日。",
RocketInfoArr[I].RocketName,
RocketInfoArr[I].IsLeft ? "←" : "⇒", HasPilotInfo, RocketInfoArr[I].RestDays);
}
}
}
internal bool AddOneLog()
{
var sb = new System.Text.StringBuilder();
MakeKishiInfo(true, sb);
sb.Append(" ■ ");
MakeMidInfo(sb);
sb.Append(" ■ ");
MakeKishiInfo(false, sb);
string wkStr = sb.ToString();
if (LogList.Contains(wkStr)) return false;
LogList.Add(wkStr);
return true;
}
internal bool IsOK()
{
if (IsPilot1Left) return false;
if (IsPilot2Left) return false;
return Array.TrueForAll(RocketInfoArr, X => X.IsLeft == false && X.IsMoveing == false);
}
internal void PrintLog()
{
var sb = new System.Text.StringBuilder();
for (int I = 0; I <= LogList.Count - 1; I++) {
sb.AppendFormat("{0,2}日目 {1}", I + 1, LogList[I]);
sb.AppendLine();
}
Console.WriteLine(sb.ToString());
}
}
static void Main()
{
var sw = System.Diagnostics.Stopwatch.StartNew();
var Jyoutai = new JyoutaiDef();
Jyoutai.Init();
var stk = new Stack<JyoutaiDef>();
stk.Push(Jyoutai);
int MaxTime = 2 + 1 + 4 + 1 + 8;
int AnswerCnt = 0;
while (stk.Count > 0) {
Jyoutai = stk.Pop();
if (Jyoutai.LogList.Count > MaxTime)
continue;
//到着判定と到着処理
for (int I = 0; I <= Jyoutai.RocketInfoArr.GetUpperBound(0); I++) {
if (Jyoutai.RocketInfoArr[I].IsMoveing) {
if (--Jyoutai.RocketInfoArr[I].RestDays == 0) {
Jyoutai.CanHasshin = true;
Jyoutai.RocketInfoArr[I].IsMoveing = false;
if (Jyoutai.RocketInfoArr[I].HasPilot1) {
Jyoutai.RocketInfoArr[I].HasPilot1 = false;
Jyoutai.IsPilot1Moveing = false;
}
if (Jyoutai.RocketInfoArr[I].HasPilot2) {
Jyoutai.RocketInfoArr[I].HasPilot2 = false;
Jyoutai.IsPilot2Moveing = false;
}
}
}
}
if (Jyoutai.IsOK()) {
MaxTime = Jyoutai.LogList.Count;
Console.WriteLine("{0}。解{1}を発見しました。", sw.Elapsed, ++AnswerCnt);
Jyoutai.AddOneLog();
Jyoutai.PrintLog();
continue;
}
//パイロットの到着を待つ
if (Jyoutai.IsPilot1Moveing || Jyoutai.IsPilot2Moveing) {
JyoutaiDef WillEnqueue = Jyoutai;
WillEnqueue.CanHasshin = false;
WillEnqueue.LogList = new List<string>(Jyoutai.LogList);
if (WillEnqueue.AddOneLog()) stk.Push(WillEnqueue);
}
if (Jyoutai.CanHasshin == false) continue;
//パイロット1だけで地球から月に移動
if (Jyoutai.IsPilot1Left && Jyoutai.IsPilot1Moveing == false) {
for (int I = 0; I <= Jyoutai.RocketInfoArr.GetUpperBound(0); I++) {
if (Jyoutai.RocketInfoArr[I].IsLeft && Jyoutai.RocketInfoArr[I].IsMoveing == false) {
JyoutaiDef WillEnqueue = Jyoutai;
WillEnqueue.CanHasshin = false;
WillEnqueue.IsPilot1Left = false; WillEnqueue.IsPilot1Moveing = true;
WillEnqueue.RocketInfoArr = (RocketInfoDef[])Jyoutai.RocketInfoArr.Clone();
WillEnqueue.RocketInfoArr[I].HasPilot1 = true;
WillEnqueue.RocketInfoArr[I].IsLeft = false;
WillEnqueue.RocketInfoArr[I].IsMoveing = true;
WillEnqueue.RocketInfoArr[I].RestDays = WillEnqueue.RocketInfoArr[I].NeedDays;
WillEnqueue.LogList = new List<string>(Jyoutai.LogList);
if (WillEnqueue.AddOneLog()) stk.Push(WillEnqueue);
}
}
}
//パイロット1だけで月から地球に移動
if (Jyoutai.IsPilot1Left == false && Jyoutai.IsPilot1Moveing == false) {
for (int I = 0; I <= Jyoutai.RocketInfoArr.GetUpperBound(0); I++) {
if (Jyoutai.RocketInfoArr[I].IsLeft == false && Jyoutai.RocketInfoArr[I].IsMoveing == false) {
JyoutaiDef WillEnqueue = Jyoutai;
WillEnqueue.CanHasshin = false;
WillEnqueue.IsPilot1Left = true; WillEnqueue.IsPilot1Moveing = true;
WillEnqueue.RocketInfoArr = (RocketInfoDef[])Jyoutai.RocketInfoArr.Clone();
WillEnqueue.RocketInfoArr[I].HasPilot1 = true;
WillEnqueue.RocketInfoArr[I].IsLeft = true;
WillEnqueue.RocketInfoArr[I].IsMoveing = true;
WillEnqueue.RocketInfoArr[I].RestDays = WillEnqueue.RocketInfoArr[I].NeedDays;
WillEnqueue.LogList = new List<string>(Jyoutai.LogList);
if (WillEnqueue.AddOneLog()) stk.Push(WillEnqueue);
}
}
}
//パイロット2だけで地球から月に移動
if (!(Jyoutai.IsPilot1Left && Jyoutai.IsPilot1Moveing == false) &&
Jyoutai.IsPilot2Left && Jyoutai.IsPilot2Moveing == false) {
for (int I = 0; I <= Jyoutai.RocketInfoArr.GetUpperBound(0); I++) {
if (Jyoutai.RocketInfoArr[I].IsLeft && Jyoutai.RocketInfoArr[I].IsMoveing == false) {
JyoutaiDef WillEnqueue = Jyoutai;
WillEnqueue.CanHasshin = false;
WillEnqueue.IsPilot2Left = false; WillEnqueue.IsPilot2Moveing = true;
WillEnqueue.RocketInfoArr = (RocketInfoDef[])Jyoutai.RocketInfoArr.Clone();
WillEnqueue.RocketInfoArr[I].HasPilot2 = true;
WillEnqueue.RocketInfoArr[I].IsLeft = false;
WillEnqueue.RocketInfoArr[I].IsMoveing = true;
WillEnqueue.RocketInfoArr[I].RestDays = WillEnqueue.RocketInfoArr[I].NeedDays;
WillEnqueue.LogList = new List<string>(Jyoutai.LogList);
if (WillEnqueue.AddOneLog()) stk.Push(WillEnqueue);
}
}
}
//パイロット2だけで月から地球に移動
if (!(Jyoutai.IsPilot1Left == false && Jyoutai.IsPilot1Moveing == false) &&
Jyoutai.IsPilot2Left == false && Jyoutai.IsPilot2Moveing == false) {
for (int I = 0; I <= Jyoutai.RocketInfoArr.GetUpperBound(0); I++) {
if (Jyoutai.RocketInfoArr[I].IsLeft == false && Jyoutai.RocketInfoArr[I].IsMoveing == false) {
JyoutaiDef WillEnqueue = Jyoutai;
WillEnqueue.CanHasshin = false;
WillEnqueue.IsPilot2Left = true; WillEnqueue.IsPilot2Moveing = true;
WillEnqueue.RocketInfoArr = (RocketInfoDef[])Jyoutai.RocketInfoArr.Clone();
WillEnqueue.RocketInfoArr[I].HasPilot2 = true;
WillEnqueue.RocketInfoArr[I].IsLeft = true;
WillEnqueue.RocketInfoArr[I].IsMoveing = true;
WillEnqueue.RocketInfoArr[I].RestDays = WillEnqueue.RocketInfoArr[I].NeedDays;
WillEnqueue.LogList = new List<string>(Jyoutai.LogList);
if (WillEnqueue.AddOneLog()) stk.Push(WillEnqueue);
}
}
}
//パイロット1と2が同じロケットで地球から月に移動
if (Jyoutai.IsPilot1Left && Jyoutai.IsPilot1Moveing == false &&
Jyoutai.IsPilot2Left && Jyoutai.IsPilot2Moveing == false) {
for (int I = 0; I <= Jyoutai.RocketInfoArr.GetUpperBound(0); I++) {
if (Jyoutai.RocketInfoArr[I].IsLeft && Jyoutai.RocketInfoArr[I].IsMoveing == false) {
JyoutaiDef WillEnqueue = Jyoutai;
WillEnqueue.CanHasshin = false;
WillEnqueue.IsPilot1Left = false; WillEnqueue.IsPilot1Moveing = true;
WillEnqueue.IsPilot2Left = false; WillEnqueue.IsPilot2Moveing = true;
WillEnqueue.RocketInfoArr = (RocketInfoDef[])Jyoutai.RocketInfoArr.Clone();
WillEnqueue.RocketInfoArr[I].HasPilot1 = true;
WillEnqueue.RocketInfoArr[I].HasPilot2 = true;
WillEnqueue.RocketInfoArr[I].IsLeft = false;
WillEnqueue.RocketInfoArr[I].IsMoveing = true;
WillEnqueue.RocketInfoArr[I].RestDays = WillEnqueue.RocketInfoArr[I].NeedDays;
WillEnqueue.LogList = new List<string>(Jyoutai.LogList);
if (WillEnqueue.AddOneLog()) stk.Push(WillEnqueue);
}
}
}
//パイロット1と2が同じロケットで月から地球に移動
if (Jyoutai.IsPilot1Left == false && Jyoutai.IsPilot1Moveing == false &&
Jyoutai.IsPilot2Left == false && Jyoutai.IsPilot2Moveing == false) {
for (int I = 0; I <= Jyoutai.RocketInfoArr.GetUpperBound(0); I++) {
if (Jyoutai.RocketInfoArr[I].IsLeft == false && Jyoutai.RocketInfoArr[I].IsMoveing == false) {
JyoutaiDef WillEnqueue = Jyoutai;
WillEnqueue.CanHasshin = false;
WillEnqueue.IsPilot1Left = true; WillEnqueue.IsPilot1Moveing = true;
WillEnqueue.IsPilot2Left = true; WillEnqueue.IsPilot2Moveing = true;
WillEnqueue.RocketInfoArr = (RocketInfoDef[])Jyoutai.RocketInfoArr.Clone();
WillEnqueue.RocketInfoArr[I].HasPilot1 = true;
WillEnqueue.RocketInfoArr[I].HasPilot2 = true;
WillEnqueue.RocketInfoArr[I].IsLeft = true;
WillEnqueue.RocketInfoArr[I].IsMoveing = true;
WillEnqueue.RocketInfoArr[I].RestDays = WillEnqueue.RocketInfoArr[I].NeedDays;
WillEnqueue.LogList = new List<string>(Jyoutai.LogList);
if (WillEnqueue.AddOneLog()) stk.Push(WillEnqueue);
}
}
}
//パイロット1と2が別々のロケットで地球から月に移動
if (Jyoutai.IsPilot1Left && Jyoutai.IsPilot1Moveing == false &&
Jyoutai.IsPilot2Left && Jyoutai.IsPilot2Moveing == false) {
for (int I = 0; I <= Jyoutai.RocketInfoArr.GetUpperBound(0); I++) {
if (!(Jyoutai.RocketInfoArr[I].IsLeft && Jyoutai.RocketInfoArr[I].IsMoveing == false))
continue;
for (int J = I + 1; J <= Jyoutai.RocketInfoArr.GetUpperBound(0); J++) {
if (!(Jyoutai.RocketInfoArr[J].IsLeft && Jyoutai.RocketInfoArr[J].IsMoveing == false))
continue;
JyoutaiDef WillEnqueue = Jyoutai;
WillEnqueue.CanHasshin = false;
WillEnqueue.IsPilot1Left = false; WillEnqueue.IsPilot1Moveing = true;
WillEnqueue.IsPilot2Left = false; WillEnqueue.IsPilot2Moveing = true;
WillEnqueue.RocketInfoArr = (RocketInfoDef[])Jyoutai.RocketInfoArr.Clone();
WillEnqueue.RocketInfoArr[I].HasPilot1 = true;
WillEnqueue.RocketInfoArr[J].HasPilot2 = true;
WillEnqueue.RocketInfoArr[I].IsLeft = false;
WillEnqueue.RocketInfoArr[J].IsLeft = false;
WillEnqueue.RocketInfoArr[I].IsMoveing = true;
WillEnqueue.RocketInfoArr[J].IsMoveing = true;
WillEnqueue.RocketInfoArr[I].RestDays = WillEnqueue.RocketInfoArr[I].NeedDays;
WillEnqueue.RocketInfoArr[J].RestDays = WillEnqueue.RocketInfoArr[J].NeedDays;
WillEnqueue.LogList = new List<string>(Jyoutai.LogList);
if (WillEnqueue.AddOneLog()) stk.Push(WillEnqueue);
}
}
}
//パイロット1と2が別々のロケットで月から地球に移動
if (Jyoutai.IsPilot1Left == false && Jyoutai.IsPilot1Moveing == false &&
Jyoutai.IsPilot2Left == false && Jyoutai.IsPilot2Moveing == false) {
for (int I = 0; I <= Jyoutai.RocketInfoArr.GetUpperBound(0); I++) {
if (!(Jyoutai.RocketInfoArr[I].IsLeft == false && Jyoutai.RocketInfoArr[I].IsMoveing == false))
continue;
for (int J = I + 1; J <= Jyoutai.RocketInfoArr.GetUpperBound(0); J++) {
if (!(Jyoutai.RocketInfoArr[J].IsLeft == false && Jyoutai.RocketInfoArr[J].IsMoveing == false))
continue;
JyoutaiDef WillEnqueue = Jyoutai;
WillEnqueue.CanHasshin = false;
WillEnqueue.IsPilot1Left = false; WillEnqueue.IsPilot1Moveing = true;
WillEnqueue.IsPilot2Left = false; WillEnqueue.IsPilot2Moveing = true;
WillEnqueue.RocketInfoArr = (RocketInfoDef[])Jyoutai.RocketInfoArr.Clone();
WillEnqueue.RocketInfoArr[I].HasPilot1 = true;
WillEnqueue.RocketInfoArr[J].HasPilot2 = true;
WillEnqueue.RocketInfoArr[I].IsLeft = true;
WillEnqueue.RocketInfoArr[J].IsLeft = true;
WillEnqueue.RocketInfoArr[I].IsMoveing = true;
WillEnqueue.RocketInfoArr[J].IsMoveing = true;
WillEnqueue.RocketInfoArr[I].RestDays = WillEnqueue.RocketInfoArr[I].NeedDays;
WillEnqueue.RocketInfoArr[J].RestDays = WillEnqueue.RocketInfoArr[J].NeedDays;
WillEnqueue.LogList = new List<string>(Jyoutai.LogList);
if (WillEnqueue.AddOneLog()) stk.Push(WillEnqueue);
}
}
}
//パイロット1が地球から月に移動し、パイロット2が月から地球に移動
if (Jyoutai.IsPilot1Left && Jyoutai.IsPilot1Moveing == false &&
Jyoutai.IsPilot2Left == false && Jyoutai.IsPilot2Moveing == false) {
for (int I = 0; I <= Jyoutai.RocketInfoArr.GetUpperBound(0); I++) {
if (!(Jyoutai.RocketInfoArr[I].IsLeft && Jyoutai.RocketInfoArr[I].IsMoveing == false))
continue;
for (int J = 0; J <= Jyoutai.RocketInfoArr.GetUpperBound(0); J++) {
if (!(Jyoutai.RocketInfoArr[J].IsLeft == false && Jyoutai.RocketInfoArr[J].IsMoveing == false))
continue;
JyoutaiDef WillEnqueue = Jyoutai;
WillEnqueue.CanHasshin = false;
WillEnqueue.IsPilot1Left = false; WillEnqueue.IsPilot1Moveing = true;
WillEnqueue.IsPilot2Left = true; WillEnqueue.IsPilot2Moveing = true;
WillEnqueue.RocketInfoArr = (RocketInfoDef[])Jyoutai.RocketInfoArr.Clone();
WillEnqueue.RocketInfoArr[I].HasPilot1 = true;
WillEnqueue.RocketInfoArr[J].HasPilot2 = true;
WillEnqueue.RocketInfoArr[I].IsLeft = false;
WillEnqueue.RocketInfoArr[J].IsLeft = true;
WillEnqueue.RocketInfoArr[I].IsMoveing = true;
WillEnqueue.RocketInfoArr[J].IsMoveing = true;
WillEnqueue.RocketInfoArr[I].RestDays = WillEnqueue.RocketInfoArr[I].NeedDays;
WillEnqueue.RocketInfoArr[J].RestDays = WillEnqueue.RocketInfoArr[J].NeedDays;
WillEnqueue.LogList = new List<string>(Jyoutai.LogList);
if (WillEnqueue.AddOneLog()) stk.Push(WillEnqueue);
}
}
}
//パイロット1が月から地球に移動し、パイロット2が地球から月に移動
if (Jyoutai.IsPilot1Left == false && Jyoutai.IsPilot1Moveing == false &&
Jyoutai.IsPilot2Left && Jyoutai.IsPilot2Moveing == false) {
for (int I = 0; I <= Jyoutai.RocketInfoArr.GetUpperBound(0); I++) {
if (!(Jyoutai.RocketInfoArr[I].IsLeft == false && Jyoutai.RocketInfoArr[I].IsMoveing == false))
continue;
for (int J = 0; J <= Jyoutai.RocketInfoArr.GetUpperBound(0); J++) {
if (!(Jyoutai.RocketInfoArr[J].IsLeft && Jyoutai.RocketInfoArr[J].IsMoveing == false))
continue;
JyoutaiDef WillEnqueue = Jyoutai;
WillEnqueue.CanHasshin = false;
WillEnqueue.IsPilot1Left = true; WillEnqueue.IsPilot1Moveing = true;
WillEnqueue.IsPilot2Left = false; WillEnqueue.IsPilot2Moveing = true;
WillEnqueue.RocketInfoArr = (RocketInfoDef[])Jyoutai.RocketInfoArr.Clone();
WillEnqueue.RocketInfoArr[I].HasPilot1 = true;
WillEnqueue.RocketInfoArr[J].HasPilot2 = true;
WillEnqueue.RocketInfoArr[I].IsLeft = true;
WillEnqueue.RocketInfoArr[J].IsLeft = false;
WillEnqueue.RocketInfoArr[I].IsMoveing = true;
WillEnqueue.RocketInfoArr[J].IsMoveing = true;
WillEnqueue.RocketInfoArr[I].RestDays = WillEnqueue.RocketInfoArr[I].NeedDays;
WillEnqueue.RocketInfoArr[J].RestDays = WillEnqueue.RocketInfoArr[J].NeedDays;
WillEnqueue.LogList = new List<string>(Jyoutai.LogList);
if (WillEnqueue.AddOneLog()) stk.Push(WillEnqueue);
}
}
}
}
}
}