Aizu Online Judge(AOJ)が提供している「プログラミング入門」(ITP1)の11_D問題をC++とPython で解いてみました。
ITP1 のトピック11では、構造体とクラスについて学びます。「構造体やクラスによって独自の型を定義し、プログラムで利用します。」とあります。この学習コースを通じて、Python に慣れていきたいと考えています。
問題(11_D:Dice IV)
問題はリンク先をご覧ください。
前回(11-C)に作成した Dice クラスを再利用して、問題を解きます。
考察
Dice クラスにある機能を再利用します。
具体的には、サイコロの目(number)を正規化する norm メソッドを使います。正規化したサイコロの面を set コンテナに登録します。最後に set コンテナに登録された要素数と登録した数(n)を比較すれば、解答が求まります。
解答案
C++ プログラム例(ITP1 11_D)
考察で記した方針に従い、main をプログラムしました。サイコロの処理を Dice クラスで処理しているため、必要なコードのみですっきりと書けています。
int main()
{
int n;
cin >> n;
set<vector<int>> s;
for (int i = 0; i < n; ++i) {
vector<int> number(6);
for (int j = 0; j < 6; ++j) {
cin >> number[j];
}
Dice d(number);
s.insert(d.norm());
}
if (s.size() == n) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
return 0;
}
プログラム全体は、このブログ記事の最後に掲載しました。
Python プログラム例(ITP1 11_D)
Python 版も考察に従い、set に登録します。Python の set は、リストを登録できないため、タプルに変換して登録しています(6行目)。
処理の本体は、以下となります。こちらもすっきりと書けています。
n = int(input())
s = set()
for i in range(n):
number = list(map(int, input().split()))
d = Dice(number)
s.add(tuple(d.norm()))
print("Yes" if len(s) == n else "No")
プログラム全体は、このブログ記事の最後に掲載しました。
最後に
トピック11では、クラスを学びました。クラスを再利用できたため、少ない労力で問題を解くことができました。
今回で、「プログラミング入門」(ITP1)が提供している全44問を解くことができました。
ITP1 は、C++ で解いていました。昨年から、Python の習熟度を高めるために、再度挑戦しました。ただし、過去に書いた C++ プログラムも多くの改良点が見つかりました。総合的なプログラミング能力が高まったと感じています。
良質なコンテンツを無料で公開していただいている会津大学に感謝いたします。
C++ 全体ソース(ITP1 11_D)
以下が、C++ 版の全体ソースコードとなります。
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
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()
{
int n;
cin >> n;
set<vector<int>> s;
for (int i = 0; i < n; ++i) {
vector<int> number(6);
for (int j = 0; j < 6; ++j) {
cin >> number[j];
}
Dice d(number);
s.insert(d.norm());
}
if (s.size() == n) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
return 0;
}
Python 全体ソース(ITP1 11_D)
以下が、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
n = int(input())
s = set()
for i in range(n):
number = list(map(int, input().split()))
d = Dice(number)
s.add(tuple(d.norm()))
print("Yes" if len(s) == n else "No")
上記プログラムは、どちらも AOJ で「AC(Accepted=正解)」と判定されます。