トップページに戻る    次のC#のサンプルへ    前のC#のサンプルへ

8-37 川渡り問題8 忙しい月旅行

問題



地球に4台のロケットがある。これをパイロット2人で月まで運びたい。
ただし、黒いロケットは月まで片道1日かかり、
同様に、赤は2日、青は4日、白は8日かかる。
また、ロケットには2人まで乗ることができる。

さて、すべてのロケットを最短日数で月まで運ぶには何日必要だろうか?

忙しい月旅行 : クイズ&パズルの部屋「Quizzical Days.」


ソース

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);
                    }
                }
            }
        }
    }
}


実行結果

省略
00:00:34.1501805。解74を発見しました。
 1日目 青白 ■ 黒⇒(Pilot1のみ)残1日。赤⇒(Pilot2のみ)残2日。 ■
 2日目 青白 ■ 赤⇒(Pilot2のみ)残1日。 ■ 黒
 3日目 青白 ■ 黒←(Pilot1と2)残1日。 ■ 赤
 4日目 青 ■ 黒⇒(Pilot1のみ)残1日。白⇒(Pilot2のみ)残8日。 ■ 赤
 5日目 青 ■ 赤←(Pilot1のみ)残2日。白⇒(Pilot2のみ)残7日。 ■ 黒
 6日目 青 ■ 赤←(Pilot1のみ)残1日。白⇒(Pilot2のみ)残6日。 ■ 黒
 7日目 赤 ■ 青⇒(Pilot1のみ)残4日。白⇒(Pilot2のみ)残5日。 ■ 黒
 8日目 赤 ■ 青⇒(Pilot1のみ)残3日。白⇒(Pilot2のみ)残4日。 ■ 黒
 9日目 赤 ■ 青⇒(Pilot1のみ)残2日。白⇒(Pilot2のみ)残3日。 ■ 黒
10日目 赤 ■ 青⇒(Pilot1のみ)残1日。白⇒(Pilot2のみ)残2日。 ■ 黒
11日目 赤 ■ 白⇒(Pilot2のみ)残1日。 ■ 黒青
12日目 赤 ■ 黒←(Pilot1と2)残1日。 ■ 青白
13日目  ■ 黒⇒(Pilot1のみ)残1日。赤⇒(Pilot2のみ)残2日。 ■ 青白
14日目  ■ 赤⇒(Pilot2のみ)残1日。 ■ 黒青白
15日目  ■  ■ 黒赤青白


解説

ひたすら場合分けしつつ、深さ優先探索でその時点での最小日数を枝切り条件に使ってます。