AIZU ONLINE JUDGE

AOJ ITP1 11_C(Dice III)を解く

AOJ_ITP1_11_C

Aizu Online Judge(AOJ)が提供している「プログラミング入門」(ITP1)の11_C問題をC++とPython で解いてみました。

ITP1 のトピック11では、構造体とクラスについて学びます。「構造体やクラスによって独自の型を定義し、プログラムで利用します。」とあります。この学習コースを通じて、Python に慣れていきたいと考えています。

問題(11_C:Dice III)

問題はリンク先をご覧ください。

AOJ ITP1 11_C問題:Dice III

前回(11-A)に作成した Dice クラスに機能を追加して、問題を解きます。

考察

ベースとなるクラスの仕様は、11_Aの記事を参照してください。

今回は、サイコロの目(number)を正規化する norm メソッドを追加します。正規化は、サイコロの数字の並びをある規則で並べ直します。norm は、11_B で実装した get_right と処理が似ています。

以下は、norm の実装方針です。これは正規化の定義にもなっています。

  • サイコロの一番小さな数を上の面(number[0])に移動させる。
  • 2番目に小さな数を前の面(number[1])に移動させる。
  • 2番目に小さな数が下の面(number[5])の場合、3番目に小さな数を前の面(number[1])に移動させる。

解答案

C++ プログラム例(ITP1 11_C)

以下は、考察で扱った norm メソッドのプログラムです。

	vector<int> norm(void)
	{
		vector<int> temp(6);
		temp = number;
		sort(temp.begin(), temp.end());

		if (temp[0] == number[1]) {
			this->N();
		} else if (temp[0] == number[2]) {
			this->W();
		} else if (temp[0] == number[3]) {
			this->E();
		} else if (temp[0] == number[4]) {
			this->S();
		} else if (temp[0] == number[5]) {
			this->N();
			this->N();
		}
		if (temp[1] == number[2]) {
			this->roll();
		} else if (temp[1] == number[3]) {
			this->roll();
			this->roll();
			this->roll();
		} else if (temp[1] == number[4]) {
			this->roll();
			this->roll();
		} else if (temp[1] == number[5]) {
			if (temp[2] == number[2]) {
				this->roll();
			} else if (temp[2] == number[3]) {
				this->roll();
				this->roll();
				this->roll();
			} else if (temp[2] == number[4]) {
				this->roll();
				this->roll();
			}
		}

		return number;
	}

サイコロの処理を Dice クラスで処理しているため、main 自体は、以下のようにすっきりと書けています。

int main()
{
	vector<int> number1(6);
	for (int i = 0; i < 6; ++i) {
		cin >> number1[i];
	}
	vector<int> number2(6);
	for (int i = 0; i < 6; ++i) {
		cin >> number2[i];
	}

	Dice d1(number1);
	Dice d2(number2);

	if (d1.norm() == d2.norm()) {
		cout << "Yes" << endl;
	} else {
		cout << "No" << endl;
	}

	return 0;
}

プログラム全体は、このブログ記事の最後に掲載しました。

Python プログラム例(ITP1 11_C)

Python 版の Dice クラスにも、同じようにクラスメソッドを追加します。追加した norm メソッドは、以下となります。

    def norm(self):
        temp = self.n.copy()
        temp.sort()

        if temp[0] == self.n[1]:
            self.N()
        elif temp[0] == self.n[2]:
            self.W()
        elif temp[0] == self.n[3]:
            self.E()
        elif temp[0] == self.n[4]:
            self.S()
        elif temp[0] == self.n[5]:
            self.N()
            self.N()
        if temp[1] == self.n[2]:
            self.roll()
        elif temp[1] == self.n[3]:
            self.roll()
            self.roll()
            self.roll()
        elif temp[1] == self.n[4]:
            self.roll()
            self.roll()
        elif temp[1] == self.n[5]:
            if temp[2] == self.n[2]:
                self.roll()
            elif temp[2] == self.n[3]:
                self.roll()
                self.roll()
                self.roll()
            elif temp[2] == self.n[4]:
                self.roll()
                self.roll()

        return self.n

インスタンス変数 n を一時的なリスト temp にコピーしています。ただの代入では、参照がコピーされるだけなので、うまく動作しません(temp を sort すると、self.n も sort されます)。このため copy メソッドを使っています(2行目)。

処理の本体は、以下となります。処理を Dice クラスにまかせているため、3行で書けています。

d1 = Dice(list(map(int, input().split())))
d2 = Dice(list(map(int, input().split())))
print("Yes" if d1.norm() == d2.norm() else "No")

プログラム全体は、このブログ記事の最後に掲載しました。

最後に

今回は、Dice クラスのメソッドを追加しました。このメソッドを追加した効果は、次回の問題を解くときに発揮されます。

次回が ITP1 最後の問題となります。

C++ 全体ソース(ITP1 11_C)

以下が、C++ 版の全体ソースコードとなります。

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

class Dice {
	vector<int> number;

public:
	Dice(vector<int> num)
	{
		number = num;
	}

	void E(void)
	{
		vector<int> temp(6);
		temp[2] = number[0];
		temp[1] = number[1];
		temp[5] = number[2];
		temp[0] = number[3];
		temp[4] = number[4];
		temp[3] = number[5];
		number = temp;
	}

	void N(void)
	{
		vector<int> temp(6);
		temp[4] = number[0];
		temp[0] = number[1];
		temp[2] = number[2];
		temp[3] = number[3];
		temp[5] = number[4];
		temp[1] = number[5];
		number = temp;
	}

	void S(void)
	{
		vector<int> temp(6);
		temp[1] = number[0];
		temp[5] = number[1];
		temp[2] = number[2];
		temp[3] = number[3];
		temp[0] = number[4];
		temp[4] = number[5];
		number = temp;
	}

	void W(void)
	{
		vector<int> temp(6);
		temp[3] = number[0];
		temp[1] = number[1];
		temp[0] = number[2];
		temp[5] = number[3];
		temp[4] = number[4];
		temp[2] = number[5];
		number = temp;
	}

	void roll(void)
	{
		vector<int> temp(6);
		temp[0] = number[0];
		temp[3] = number[1];
		temp[1] = number[2];
		temp[4] = number[3];
		temp[2] = number[4];
		temp[5] = number[5];
		number = temp;
	}

	void move(char ch)
	{
		switch (ch) {
		case 'E':
			this->E();
		    break;
		case 'N':
			this->N();
		    break;
		case 'S':
			this->S();
		    break;
		case 'W':
			this->W();
		    break;
		default:
		    break;
		}
	}

	vector<int> get_number(void)
	{
		return number;
	}

	vector<int> norm(void)
	{
		vector<int> temp(6);
		temp = number;
		sort(temp.begin(), temp.end());

		if (temp[0] == number[1]) {
			this->N();
		} else if (temp[0] == number[2]) {
			this->W();
		} else if (temp[0] == number[3]) {
			this->E();
		} else if (temp[0] == number[4]) {
			this->S();
		} else if (temp[0] == number[5]) {
			this->N();
			this->N();
		}
		if (temp[1] == number[2]) {
			this->roll();
		} else if (temp[1] == number[3]) {
			this->roll();
			this->roll();
			this->roll();
		} else if (temp[1] == number[4]) {
			this->roll();
			this->roll();
		} else if (temp[1] == number[5]) {
			if (temp[2] == number[2]) {
				this->roll();
			} else if (temp[2] == number[3]) {
				this->roll();
				this->roll();
				this->roll();
			} else if (temp[2] == number[4]) {
				this->roll();
				this->roll();
			}
		}

		return number;
	}
};

int main()
{
	vector<int> number1(6);
	for (int i = 0; i < 6; ++i) {
		cin >> number1[i];
	}
	vector<int> number2(6);
	for (int i = 0; i < 6; ++i) {
		cin >> number2[i];
	}

	Dice d1(number1);
	Dice d2(number2);

	if (d1.norm() == d2.norm()) {
		cout << "Yes" << endl;
	} else {
		cout << "No" << endl;
	}

	return 0;
}

Python 全体ソース(ITP1 11_C)

以下が、Python 版の全体ソースコードとなります。

class Dice:
    def __init__(self, number):
        self.n = number.copy()

    def E(self):
        self.n[2], self.n[5], self.n[0], self.n[3] = \
            self.n[0], self.n[2], self.n[3], self.n[5]

    def N(self):
        self.n[4], self.n[0], self.n[5], self.n[1] = \
            self.n[0], self.n[1], self.n[4], self.n[5]

    def S(self):
        self.n[1], self.n[5], self.n[0], self.n[4] = \
            self.n[0], self.n[1], self.n[4], self.n[5]

    def W(self):
        self.n[3], self.n[0], self.n[5], self.n[2] = \
            self.n[0], self.n[2], self.n[3], self.n[5]

    def roll(self):
        self.n[3], self.n[1], self.n[4], self.n[2] = \
            self.n[1], self.n[2], self.n[3], self.n[4]

    def move(self, ch):
        if ch == 'E':
            self.E()
        elif ch == 'N':
            self.N()
        elif ch == 'S':
            self.S()
        elif ch == 'W':
            self.W()

    def get_number(self):
        return self.n

    def norm(self):
        temp = self.n.copy()
        temp.sort()

        if temp[0] == self.n[1]:
            self.N()
        elif temp[0] == self.n[2]:
            self.W()
        elif temp[0] == self.n[3]:
            self.E()
        elif temp[0] == self.n[4]:
            self.S()
        elif temp[0] == self.n[5]:
            self.N()
            self.N()
        if temp[1] == self.n[2]:
            self.roll()
        elif temp[1] == self.n[3]:
            self.roll()
            self.roll()
            self.roll()
        elif temp[1] == self.n[4]:
            self.roll()
            self.roll()
        elif temp[1] == self.n[5]:
            if temp[2] == self.n[2]:
                self.roll()
            elif temp[2] == self.n[3]:
                self.roll()
                self.roll()
                self.roll()
            elif temp[2] == self.n[4]:
                self.roll()
                self.roll()

        return self.n


d1 = Dice(list(map(int, input().split())))
d2 = Dice(list(map(int, input().split())))
print("Yes" if d1.norm() == d2.norm() else "No")

上記プログラムは、どちらも AOJ で「AC(Accepted=正解)」と判定されます。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA