2015年4月16日 星期四

[Reference] MidExam


Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinJugPuzzle
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            JugPuzzle jug = new JugPuzzle();
            jug.Message = txtMessage;
            jug.CapacityOfJugA = Convert.ToInt16(txtCapacityOfJugA.Text);
            jug.CapacityOfJugB = Convert.ToInt16(txtCapacityOfJugB.Text);
            jug.Target = Convert.ToInt16(txtTarget.Text);
            jug.Solve();
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            txtMessage.Clear();
        }
    }
}
JugPuzzle
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinJugPuzzle
{
    class JugPuzzle
    {
        public int CapacityOfJugA;
        public int CapacityOfJugB;
        public int Target;
        public TextBox Message;
        public void Solve()
        {
            if (!isSolvable())
            {
                Message.AppendText("無解,你被唬了, Boom!\n");
                return;
            }
            int capacityA = 0;    //容器A 的水量
            int capacityB = 0;      //容器B 的水量
            Message.AppendText("開始進行分水步驟!\n");
            while (true)
            {
                // 條件: 容器 A 空的
                // 動作: 將容器A 裝滿
                if (capacityA == 0)
                {
                    capacityA = CapacityOfJugA;
                    Action(capacityA, capacityB,1);
                    if (capacityA == Target || (capacityA + capacityB == Target))
                        break;
                }
                // 條件: 容器 A 滿的
                // 動作: 將容器A的水倒進容器B
                else if (capacityA == CapacityOfJugA)
                {
                    // 條件: 容器 A 的水量少於 容器B 可以再裝的容量jugB - capacityB
                    // 動作: 將容器A的水全部倒進容器B
                    if (capacityA <= CapacityOfJugB - capacityB)
                    {
                        capacityB += capacityA;
                        capacityA = 0;
                        Action(capacityA, capacityB,2);
                        if (capacityB == Target)
                            break;
                    }
                    else
                    {
                        // 條件: 容器 A 的水量大於 容器B 可以再裝的容量(jugB - capacityB)
                        // 動作: 將容器A的水倒 (jugB - capacityB) 進容器B
                        capacityA -= (CapacityOfJugB - capacityB);
                        capacityB += (CapacityOfJugB - capacityB);
                        Action(capacityA, capacityB,3);
                        if (capacityA == Target)
                            break;
                    }
                }
                // 條件: 容器 B 滿的
                // 動作: 將容器B的水倒光
                else if (capacityB == CapacityOfJugB)
                {
                    capacityB = 0;
                    Action(capacityA, capacityB,4);
                }
                // 條件: 容器 A 有水,但沒有滿
                // 動作: 將容器A的水倒進容器B
                else if (capacityA > 0 && capacityA < CapacityOfJugA)
                {
                    capacityB += capacityA;
                    capacityA = 0;
                    Action(capacityA, capacityB,5);
                }
            }
            ShowSolution(capacityA, capacityB);
        }

        //將步驟列印到 Textbox
        void Action(int capacityA, int capacityB,int moveMethod)
        {
            Message.AppendText("===============================\n");
            switch (moveMethod)
            {
                case 1:
                    Message.AppendText("將容器A 裝滿\n");
                    break;
                case 2:
                    Message.AppendText("將容器A的水全部倒進容器B\n");
                    break;
                case 3:
                    Message.AppendText("將容器A的水倒進容器B,直到B滿為止\n");
                    break;
                case 4:
                    Message.AppendText("將容器B的水倒光\n");
                    break;
                case 5:
                    Message.AppendText("將容器A的水倒進容器B\n");
                    break;
                default:
                    break;
            }
            Message.AppendText("(A,B)=(" + capacityA.ToString() + ',' + capacityB.ToString() + ") \n");
        }
        //Show Solution
        void ShowSolution(int capacityA, int capacityB)
        {
            Message.AppendText("**********************************\n");
            Message.AppendText("**********************************\n");
            if (capacityA == Target)
            {
                Message.AppendText("將容器A放在磅秤上,即為所求\n");
            }
            else if (capacityB == Target)
            {
                Message.AppendText("將容器B放在磅秤上,即為所求\n");
            }
            else
            {
                Message.AppendText("將容器A與B一起放在磅秤上,即為所求\n");
            }
            Message.AppendText("炸彈解除!\n");
        }

        // 檢查 Jug puzzle 是否有解
        bool isSolvable()
        {
            if (Target % gcd(CapacityOfJugA, CapacityOfJugB) != 0)
                return false;
            return true;
        }
        //求最大公因數
        int gcd(int num1, int num2)
        {
            int temp = num1 % num2;
            while (num1 % num2 != 0)
            {
                temp = num1 % num2;
                num1 = num2;
                num2 = temp;
            }
            return num2;
        }
     
    }
}

沒有留言:

張貼留言