トラ・ライオン・ヒョウの3組の親子が、舟で川を渡ろうとしている。 舟は1艘(そう)しかないが、1度に2匹まで乗ることができ、 またどの動物も舟を漕(こ)ぐことが可能である。 ただし、親子同士でない成獣(親)と幼獣(子)が同じ場所におり、 かつその子の親が近くにいない場合、子は食べられてしまう。 さて、全員が無事に川を渡り切るにはどうすればよいだろうか? 猛獣親子の川渡り : クイズ&パズルの部屋「Quizzical Days.」
using System; using System.Collections.Generic; class Program { struct JyoutaiDef { internal int Level; internal bool IsToraOyaLeft; internal bool IsToraKoLeft; internal bool IsLionOyaLeft; internal bool IsLionKoLeft; internal bool IsHyouOyaLeft; internal bool IsHyouKoLeft; internal bool IsIkadaLeft; internal List<string> LogList; internal void Init() { Level = 0; IsToraOyaLeft = IsToraKoLeft = true; IsLionOyaLeft = IsLionKoLeft = true; IsHyouOyaLeft = IsHyouKoLeft = true; IsIkadaLeft = true; LogList = new List<string>(); AddOneLog(); } internal void MakeKishiInfo(bool pIsLeftInfo, System.Text.StringBuilder pSb) { if (pIsLeftInfo == IsToraOyaLeft) pSb.Append("親トラ,"); if (pIsLeftInfo == IsToraKoLeft) pSb.Append("子トラ,"); if (pIsLeftInfo == IsLionOyaLeft) pSb.Append("親ライオン,"); if (pIsLeftInfo == IsLionKoLeft) pSb.Append("子ライオン,"); if (pIsLeftInfo == IsHyouOyaLeft) pSb.Append("親ヒョウ,"); if (pIsLeftInfo == IsHyouKoLeft) pSb.Append("子ヒョウ,"); } internal bool AddOneLog() { var sb = new System.Text.StringBuilder(); MakeKishiInfo(true, sb); sb.Append(IsIkadaLeft ? " 筏 川川川 " : " 川川川 筏 "); MakeKishiInfo(false, sb); string wkStr = sb.ToString(); if (LogList.Contains(wkStr)) return false; LogList.Add(wkStr); return true; } internal void PrintLog() { for (int I = 0; I <= LogList.Count - 1; I++) Console.WriteLine("レベル{0,2} {1}", I, LogList[I]); } internal bool IsValid() { if (IsToraOyaLeft != IsToraKoLeft && (IsToraKoLeft == IsLionOyaLeft || IsToraKoLeft == IsHyouOyaLeft)) return false; if (IsLionOyaLeft != IsLionKoLeft && (IsLionKoLeft == IsToraOyaLeft || IsLionKoLeft == IsHyouOyaLeft)) return false; if (IsHyouOyaLeft != IsHyouKoLeft && (IsHyouKoLeft == IsToraOyaLeft || IsHyouKoLeft == IsLionOyaLeft)) return false; return true; } } static void Main() { var Jyoutai = new JyoutaiDef(); Jyoutai.Init(); var que = new Queue<JyoutaiDef>(); que.Enqueue(Jyoutai); int AnswerLevel = int.MaxValue; int AnswerCnt = 0; while (que.Count != 0) { Jyoutai = que.Dequeue(); //Jyoutai.PrintLog(); if (++Jyoutai.Level > AnswerLevel) continue; if (Jyoutai.IsToraOyaLeft == false && Jyoutai.IsToraKoLeft == false && Jyoutai.IsLionOyaLeft == false && Jyoutai.IsLionKoLeft == false && Jyoutai.IsHyouOyaLeft == false && Jyoutai.IsHyouKoLeft == false && Jyoutai.IsIkadaLeft == false) { Console.WriteLine("解{0}を発見しました。", ++AnswerCnt); Jyoutai.PrintLog(); AnswerLevel = Jyoutai.Level; continue; } Action<JyoutaiDef> EnqueueSyori = (pWillEnqueue) => { pWillEnqueue.LogList = new List<string>(Jyoutai.LogList); pWillEnqueue.IsIkadaLeft = !Jyoutai.IsIkadaLeft; if (pWillEnqueue.AddOneLog() && pWillEnqueue.IsValid()) que.Enqueue(pWillEnqueue); }; if (Jyoutai.IsIkadaLeft) { //親トラと親ライオンで移動 if (Jyoutai.IsToraOyaLeft && Jyoutai.IsLionOyaLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraOyaLeft = WillEnqueue.IsLionOyaLeft = false; EnqueueSyori(WillEnqueue); } //親トラと親ヒョウで移動 if (Jyoutai.IsToraOyaLeft && Jyoutai.IsHyouOyaLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraOyaLeft = WillEnqueue.IsHyouOyaLeft = false; EnqueueSyori(WillEnqueue); } //親ライオンと親ヒョウで移動 if (Jyoutai.IsLionOyaLeft && Jyoutai.IsHyouOyaLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsLionOyaLeft = WillEnqueue.IsHyouOyaLeft = false; EnqueueSyori(WillEnqueue); } //親トラで移動 if (Jyoutai.IsToraOyaLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraOyaLeft = false; EnqueueSyori(WillEnqueue); } //親ライオンで移動 if (Jyoutai.IsLionOyaLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsLionOyaLeft = false; EnqueueSyori(WillEnqueue); } //親ヒョウで移動 if (Jyoutai.IsHyouOyaLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsHyouOyaLeft = false; EnqueueSyori(WillEnqueue); } //親トラと子トラで移動 if (Jyoutai.IsToraOyaLeft && Jyoutai.IsToraKoLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraOyaLeft = WillEnqueue.IsToraKoLeft = false; EnqueueSyori(WillEnqueue); } //親ライオンと子ライオンで移動 if (Jyoutai.IsLionOyaLeft && Jyoutai.IsLionKoLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsLionOyaLeft = WillEnqueue.IsLionKoLeft = false; EnqueueSyori(WillEnqueue); } //親ヒョウと子ヒョウで移動 if (Jyoutai.IsHyouOyaLeft && Jyoutai.IsHyouKoLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsHyouOyaLeft = WillEnqueue.IsHyouKoLeft = false; EnqueueSyori(WillEnqueue); } //子トラと子ライオンで移動 if (Jyoutai.IsToraKoLeft && Jyoutai.IsLionKoLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraKoLeft = WillEnqueue.IsLionKoLeft = false; EnqueueSyori(WillEnqueue); } //子トラと子ヒョウで移動 if (Jyoutai.IsToraKoLeft && Jyoutai.IsHyouKoLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraKoLeft = WillEnqueue.IsHyouKoLeft = false; EnqueueSyori(WillEnqueue); } //子ライオンと子ヒョウで移動 if (Jyoutai.IsLionKoLeft && Jyoutai.IsHyouKoLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsLionKoLeft = WillEnqueue.IsHyouKoLeft = false; EnqueueSyori(WillEnqueue); } //子トラで移動 if (Jyoutai.IsToraKoLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraKoLeft = false; EnqueueSyori(WillEnqueue); } //子ライオンで移動 if (Jyoutai.IsLionKoLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsLionKoLeft = false; EnqueueSyori(WillEnqueue); } //子ヒョウで移動 if (Jyoutai.IsHyouKoLeft) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsHyouKoLeft = false; EnqueueSyori(WillEnqueue); } } else { //親トラと親ライオンで移動 if (Jyoutai.IsToraOyaLeft == false && Jyoutai.IsLionOyaLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraOyaLeft = WillEnqueue.IsLionOyaLeft = true; EnqueueSyori(WillEnqueue); } //親トラと親ヒョウで移動 if (Jyoutai.IsToraOyaLeft == false && Jyoutai.IsHyouOyaLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraOyaLeft = WillEnqueue.IsHyouOyaLeft = true; EnqueueSyori(WillEnqueue); } //親ライオンと親ヒョウで移動 if (Jyoutai.IsLionOyaLeft == false && Jyoutai.IsHyouOyaLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsLionOyaLeft = WillEnqueue.IsHyouOyaLeft = true; EnqueueSyori(WillEnqueue); } //親トラで移動 if (Jyoutai.IsToraOyaLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraOyaLeft = true; EnqueueSyori(WillEnqueue); } //親ライオンで移動 if (Jyoutai.IsLionOyaLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsLionOyaLeft = true; EnqueueSyori(WillEnqueue); } //親ヒョウで移動 if (Jyoutai.IsHyouOyaLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsHyouOyaLeft = true; EnqueueSyori(WillEnqueue); } //親トラと子トラで移動 if (Jyoutai.IsToraOyaLeft == false && Jyoutai.IsToraKoLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraOyaLeft = WillEnqueue.IsToraKoLeft = true; EnqueueSyori(WillEnqueue); } //親ライオンと子ライオンで移動 if (Jyoutai.IsLionOyaLeft == false && Jyoutai.IsLionKoLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsLionOyaLeft = WillEnqueue.IsLionKoLeft = true; EnqueueSyori(WillEnqueue); } //親ヒョウと子ヒョウで移動 if (Jyoutai.IsHyouOyaLeft == false && Jyoutai.IsHyouKoLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsHyouOyaLeft = WillEnqueue.IsHyouKoLeft = true; EnqueueSyori(WillEnqueue); } //子トラと子ライオンで移動 if (Jyoutai.IsToraKoLeft == false && Jyoutai.IsLionKoLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraKoLeft = WillEnqueue.IsLionKoLeft = true; EnqueueSyori(WillEnqueue); } //子トラと子ヒョウで移動 if (Jyoutai.IsToraKoLeft == false && Jyoutai.IsHyouKoLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraKoLeft = WillEnqueue.IsHyouKoLeft = true; EnqueueSyori(WillEnqueue); } //子ライオンと子ヒョウで移動 if (Jyoutai.IsLionKoLeft == false && Jyoutai.IsHyouKoLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsLionKoLeft = WillEnqueue.IsHyouKoLeft = true; EnqueueSyori(WillEnqueue); } //子トラで移動 if (Jyoutai.IsToraKoLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsToraKoLeft = true; EnqueueSyori(WillEnqueue); } //子ライオンで移動 if (Jyoutai.IsLionKoLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsLionKoLeft = true; EnqueueSyori(WillEnqueue); } //子ヒョウで移動 if (Jyoutai.IsHyouKoLeft == false) { JyoutaiDef WillEnqueue = Jyoutai; WillEnqueue.IsHyouKoLeft = true; EnqueueSyori(WillEnqueue); } } } } }
省略 解486を発見しました。 レベル 0 親トラ,子トラ,親ライオン,子ライオン,親ヒョウ,子ヒョウ, 筏 川川川 レベル 1 親トラ,子トラ,親ライオン,親ヒョウ, 川川川 筏 子ライオン,子ヒョウ, レベル 2 親トラ,子トラ,親ライオン,親ヒョウ,子ヒョウ, 筏 川川川 子ライオン, レベル 3 親トラ,親ライオン,親ヒョウ, 川川川 筏 子トラ,子ライオン,子ヒョウ, レベル 4 親トラ,親ライオン,親ヒョウ,子ヒョウ, 筏 川川川 子トラ,子ライオン, レベル 5 親ヒョウ,子ヒョウ, 川川川 筏 親トラ,子トラ,親ライオン,子ライオン, レベル 6 親ライオン,子ライオン,親ヒョウ,子ヒョウ, 筏 川川川 親トラ,子トラ, レベル 7 子ライオン,子ヒョウ, 川川川 筏 親トラ,子トラ,親ライオン,親ヒョウ, レベル 8 子トラ,子ライオン,子ヒョウ, 筏 川川川 親トラ,親ライオン,親ヒョウ, レベル 9 子トラ, 川川川 筏 親トラ,親ライオン,子ライオン,親ヒョウ,子ヒョウ, レベル10 子トラ,子ヒョウ, 筏 川川川 親トラ,親ライオン,子ライオン,親ヒョウ, レベル11 川川川 筏 親トラ,子トラ,親ライオン,子ライオン,親ヒョウ,子ヒョウ,
幅優先探索で解いてます。