paiza×Qiita記事投稿キャンペーンということで、paizaラーニングレベルアップ問題集の神経衰弱をオブジェクト指向でやってみました。対象はコードモンスター大図鑑で対応している9言語です。
2024/08/25更新
Javascriptのコードを修正いたしました。
方針
-
神経衰弱クラスを作成し、これらの入力値
$H$ $W$ $N$
$t_{1,1}$ $t_{1,2}$ $\dots$ $t_{1,W}$
$t_{2,1}$ $t_{2,2}$ $\dots$ $t_{2,W}$
$\dots$
$t_{H,1}$ $t_{H,2}$ $\dots$ $t_{H,W}$をコンストラクタに渡します。
-
記録の長さ
L
を受け取ります。 -
入力の後半部分
$a_1$ $b_1$ $A_1$ $B_1$
$a_2$ $b_2$ $A_2$ $B_2$
$\dots$
$a_L$ $b_L$ $A_L$ $B_L$を一行ずつ受け取り、メソッドに渡します。
-
メソッドは、問題文の
- 並べられたトランプから2枚のトランプを選び、めくります。
- めくった2枚のトランプに異なる数字が書かれていれば、
-
同じ数字であれば、次の操作をおこないます。
- まず、2枚のトランプはめくったプレーヤーのものとなり、
を実装します。
PHP
<?php
// 神経衰弱クラス
class Concentration
{
// プレイヤーの数
private $nPlayers;
// 配置されたトランプに書かれた数字
private $cards;
// 各プレイヤーが取り除いたトランプの枚数
private $scores;
// 手番のプレイヤー
private $player;
// プレイヤーが取り除いたトランプの枚数を返します。
public function getScore($i)
{
return $this->scores[$i];
}
// コンストラクタ
public function __construct($n, $t)
{
// プレイヤーの数
$this->nPlayers = $n;
// 配置されたトランプに書かれた数字
$this->cards = $t;
// プレイヤーが取り除いたトランプの枚数を初期化
$this->scores = array_fill(0, $n, 0);
// ゲームが始まると、0番の人からプレイしていきます。
$this->player = 0;
}
// トランプを捲ります。
public function play($a, $b, $c, $d)
{
//並べられたトランプから2枚のトランプを選び、めくります。
$t0 = $this->cards[$a][$b];
$t1 = $this->cards[$c][$d];
// めくった2枚のトランプに
if ($t0 == $t1) { // 同じ数字が書かれていれば
// 2枚のトランプはめくったプレーヤーのものとなります。
$this->scores[$this->player] += 2;
} else { // 異なる数字が書かれていれば
// 次のプレイヤーの手番となります。
$this->player += 1;
// N-1番のプレイヤーの次のプレイヤーは0番のプレイヤーであるとします。
$this->player %= $this->nPlayers;
}
}
}
//1行目には3つの整数H, W, Nが入力されます。
//HとWはそれぞれ並べられたトランプの縦方向の枚数と横方向の枚数で、
//Nはプレイヤーの数を表します。
[$h, $w, $n] = explode(" ", fgets(STDIN));
//続くH行には、配置されたトランプに書かれた数字が入力されます。
$t = [];
for ($i = 0; $i < $h; $i++) {
//t[i][j]はi行j列に置かれたトランプに書かれた数字を表します。
$t[] = explode(" ", fgets(STDIN));
}
// 神経衰弱クラスをインスタンス化します。
$concentration = new Concentration($n, $t);
// 次の行には、記録の長さ L が与えられます。
$L = fgets(STDIN);
// 続く L 行には、捲られたトランプの記録が時系列順で与えられます。
for ($i = 0; $i < $L; $i++) {
// これは、a行b列のトランプとA行B列のトランプが捲られたことを表します。
[$a, $b, $A, $B] = array_map(fn($x) => $x - 1, explode(" ", fgets(STDIN)));
// トランプを捲ります。
$concentration->play($a, $b, $A, $B);
}
for ($i = 0; $i < $n; $i++) {
// i番目のプレイヤーが取り除いたトランプの枚数を出力します。
echo $concentration->getScore($i) . "\n";
}
?>
Ruby
# 神経衰弱クラス
class Concentration
# コンストラクタ
def initialize(n, t)
# プレイヤーの数
@nPlayers = n
# 配置されたトランプに書かれた数字
@cards = t
# プレイヤーが取り除いたトランプの枚数を初期化
@scores = Array.new(n, 0)
# ゲームが始まると、0番の人からプレイしていきます。
@player = 0
end
# トランプを捲ります。
def play(a, b, c, d)
#並べられたトランプから2枚のトランプを選び、めくります。
t0 = @cards[a][b]
t1 = @cards[c][d]
# めくった2枚のトランプに
if t0 == t1 # 同じ数字が書かれていれば
# 2枚のトランプはめくったプレーヤーのものとなります。
@scores[@player] += 2
else # 異なる数字が書かれていれば
# 次のプレイヤーの手番となります。
@player += 1
# N-1番のプレイヤーの次のプレイヤーは0番のプレイヤーであるとします。
@player %= @nPlayers
end
end
# プレイヤーが取り除いたトランプの枚数を返します。
def score(i)
return @scores[i]
end
end
#1行目には3つの整数H, W, Nが入力されます。
#HとWはそれぞれ並べられたトランプの縦方向の枚数と横方向の枚数で、
#Nはプレイヤーの数を表します。
h, w, n = gets.split.map(&:to_i)
#続くH行には、配置されたトランプに書かれた数字が入力されます。
t = []
h.times do
#t[i][j]はi行j列に置かれたトランプに書かれた数字を表します。
t << gets.chomp.split
end
# 神経衰弱クラスをインスタンス化します。
concentration = Concentration.new(n, t)
# 次の行には、記録の長さ L が与えられます。
L = gets.to_i
# 続く L 行には、捲られたトランプの記録が時系列順で与えられます。
L.times do
# これは、a行b列のトランプとc行d列のトランプが捲られたことを表します。
a, b, c, d = gets.split.map(&lambda{ |x| x.to_i - 1 })
# トランプを捲ります。
concentration.play(a, b, c, d)
end
n.times do |i|
# i番目のプレイヤーが取り除いたトランプの枚数を出力します。
p concentration.score(i)
end
Java
import java.util.*;
// 神経衰弱クラス
class Concentration {
// プレイヤーの数
private int nPlayers;
// 配置されたトランプに書かれた数字
private String[][] cards;
// 各プレイヤーが取り除いたトランプの枚数
private int[] scores;
// 手番のプレイヤー
private int player;
// プレイヤーが取り除いたトランプの枚数を返します。
public int getScore(int i) {
return this.scores[i];
}
// コンストラクタ
public Concentration(int n, String[][] t) {
// プレイヤーの数
this.nPlayers = n;
// 配置されたトランプに書かれた数字
this.cards = t;
// プレイヤーが取り除いたトランプの枚数を初期化
this.scores = new int[n];
// ゲームが始まると、0番の人からプレイしていきます。
this.player = 0;
}
// トランプを捲ります。
public void play(int a, int b, int c, int d) {
// 並べられたトランプから2枚のトランプを選び、めくります。
String t0 = this.cards[a][b];
String t1 = this.cards[c][d];
// めくった2枚のトランプに
if (t0.equals(t1)) { // 同じ数字が書かれていれば
// 2枚のトランプはめくったプレーヤーのものとなります。
this.scores[this.player] += 2;
} else { // 異なる数字が書かれていれば
// 次のプレイヤーの手番となります。
this.player += 1;
// N-1番のプレイヤーの次のプレイヤーは0番のプレイヤーであるとします。
this.player %= this.nPlayers;
}
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 1行目には3つの整数H, W, Nが入力されます。
// HとWはそれぞれ並べられたトランプの縦方向の枚数と横方向の枚数で、
// Nはプレイヤーの数を表します。
int h = sc.nextInt();
int w = sc.nextInt();
int n = sc.nextInt();
// 続くH行には、配置されたトランプに書かれた数字が入力されます。
String[][] t = new String[h][];
for (int i = 0; i < h; i++) {
t[i] = new String[w];
for (int j = 0; j < w; j++) {
// t[i][j]はi行j列に置かれたトランプに書かれた数字を表します。
t[i][j] = sc.next();
}
}
// 神経衰弱クラスをインスタンス化します。
Concentration concentration = new Concentration(n, t);
// 次の行には、記録の長さ L が与えられます。
int L = sc.nextInt();
// 続く L 行には、捲られたトランプの記録が時系列順で与えられます。
for (int i = 0; i < L; i++) {
// これは、a行b列のトランプとA行B列のトランプが捲られたことを表します。
int a = sc.nextInt() - 1;
int b = sc.nextInt() - 1;
int A = sc.nextInt() - 1;
int B = sc.nextInt() - 1;
// トランプを捲ります。
concentration.play(a, b, A, B);
}
sc.close();
for (int i = 0; i < n; i++) {
// i番目のプレイヤーが取り除いたトランプの枚数を出力します。
System.out.println(concentration.getScore(i));
}
}
}
Python
# 神経衰弱クラス
class Concentration:
# コンストラクタ
def __init__(self, n, t):
# プレイヤーの数
self.nPlayers = n
# 配置されたトランプに書かれた数字
self.cards = t
# プレイヤーが取り除いたトランプの枚数を初期化
self.scores = [0 for _ in range(n)]
# ゲームが始まると、0番の人からプレイしていきます。
self.player = 0
# トランプを捲ります。
def play(self, a, b, c, d):
# 並べられたトランプから2枚のトランプを選び、めくります。
t0 = self.cards[a][b]
t1 = self.cards[c][d]
# めくった2枚のトランプに
if t0 == t1: # 同じ数字が書かれていれば
# 2枚のトランプはめくったプレーヤーのものとなります。
self.scores[self.player] += 2
else: # 異なる数字が書かれていれば
# 次のプレイヤーの手番となります。
self.player += 1
# N-1番のプレイヤーの次のプレイヤーは0番のプレイヤーであるとします。
self.player %= self.nPlayers
# プレイヤーが取り除いたトランプの枚数を返します。
def score(self, i):
return self.scores[i]
# 1行目には3つの整数H, W, Nが入力されます。
# HとWはそれぞれ並べられたトランプの縦方向の枚数と横方向の枚数で、
# Nはプレイヤーの数を表します。
h, w, n = map(int, input().split())
# 続くH行には、配置されたトランプに書かれた数字が入力されます。
t = []
for _ in range(h):
# t[i][j]はi行j列に置かれたトランプに書かれた数字を表します。
t.append(input().split())
# 神経衰弱クラスをインスタンス化します。
concentration = Concentration(n, t)
# 次の行には、記録の長さ L が与えられます。
L = int(input())
# 続く L 行には、捲られたトランプの記録が時系列順で与えられます。
for _ in range(L):
# これは、a行b列のトランプとc行d列のトランプが捲られたことを表します。
a, b, c, d = map(lambda x: int(x) - 1, input().split())
# トランプを捲ります。
concentration.play(a, b, c, d)
for i in range(n):
# i番目のプレイヤーが取り除いたトランプの枚数を出力します。
print(concentration.score(i))
C言語
#include <stdio.h>
#include <string.h>
// 神経衰弱構造体
typedef struct Concentration {
// プレイヤーの数
int nPlayers;
// 配置されたトランプに書かれた数字
int **cards;
// 各プレイヤーが取り除いたトランプの枚数
int *scores;
// 手番のプレイヤー
int player;
} Concentration;
// トランプを捲ります。
void play(Concentration *concentration, int a, int b, int c, int d) {
//並べられたトランプから2枚のトランプを選び、めくります。
int t0 = concentration->cards[a][b];
int t1 = concentration->cards[c][d];
// めくった2枚のトランプに
if (t0 == t1) { // 同じ数字が書かれていれば
// 2枚のトランプはめくったプレーヤーのものとなります。
concentration->scores[concentration->player] += 2;
} else { // 異なる数字が書かれていれば
// 次のプレイヤーの手番となります。
concentration->player += 1;
// N-1番のプレイヤーの次のプレイヤーは0番のプレイヤーであるとします。
concentration->player %= concentration->nPlayers;
}
}
/* プレイヤーが取り除いたトランプの枚数を返します。
int getScore(const Concentration *concentration, int i) {
return concentration->scores[i];
}
*/
int main() {
//1行目には3つの整数H, W, Nが入力されます。
//HとWはそれぞれ並べられたトランプの縦方向の枚数と横方向の枚数で、
//Nはプレイヤーの数を表します。
int h, w, n;
scanf("%d %d %d", &h, &w, &n);
//続くH行には、配置されたトランプに書かれた数字が入力されます。
int t[h][w];
int *p[h];
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
//t[i][j]はi行j列に置かれたトランプに書かれた数字を表します。
scanf("%d", &t[i][j]);
}
p[i] = t[i];
}
// 神経衰弱クラスをインスタンス化します。
int scores[n];
memset(scores, 0, sizeof(scores));
Concentration concentration = { n, p, scores, 0 };
// 次の行には、記録の長さ L が与えられます。
int L;
scanf("%d", &L);
// 続く L 行には、捲られたトランプの記録が時系列順で与えられます。
for (int i = 0; i < L; i++) {
// これは、a行b列のトランプとA行B列のトランプが捲られたことを表します。
int a, b, A, B;
scanf("%d %d %d %d", &a, &b, &A, &B);
// トランプを捲ります。
play(&concentration, a - 1, b - 1, A - 1, B - 1);
}
for (int i = 0; i < n; i++) {
// i番目のプレイヤーが取り除いたトランプの枚数を出力します。
// printf("%d\n", getScore(&concentration, i));
printf("%d\n", scores[i]);
}
return 0;
}
C#
using System;
// 神経衰弱クラス
class Concentration
{
// プレイヤーの数
private int nPlayers;
// 配置されたトランプに書かれた数字
private String[][] cards;
// 各プレイヤーが取り除いたトランプの枚数
private int[] scores;
// 手番のプレイヤー
private int player;
// プレイヤーが取り除いたトランプの枚数を返します。
public int GetScore(int i)
{
return scores[i];
}
// コンストラクタ
public Concentration(int n, String[][] t)
{
// プレイヤーの数
nPlayers = n;
// 配置されたトランプに書かれた数字
cards = t;
// プレイヤーが取り除いたトランプの枚数を初期化
scores = new int[n];
// ゲームが始まると、0番の人からプレイしていきます。
player = 0;
}
// トランプを捲ります。
public void Play(int a, int b, int c, int d)
{
// 並べられたトランプから2枚のトランプを選び、めくります。
string t0 = cards[a][b];
string t1 = cards[c][d];
// めくった2枚のトランプに
if (t0.Equals(t1))
{ // 同じ数字が書かれていれば
// 2枚のトランプはめくったプレーヤーのものとなります。
scores[player] += 2;
}
else
{ // 異なる数字が書かれていれば
// 次のプレイヤーの手番となります。
player += 1;
// N-1番のプレイヤーの次のプレイヤーは0番のプレイヤーであるとします。
player %= nPlayers;
}
}
}
class Program
{
static void Main(string[] args)
{
// 1行目には3つの整数H, W, Nが入力されます。
// HとWはそれぞれ並べられたトランプの縦方向の枚数と横方向の枚数で、
// Nはプレイヤーの数を表します。
int[] hwn = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
int h = hwn[0];
// int w = hwn[1];
int n = hwn[2];
// 続くH行には、配置されたトランプに書かれた数字が入力されます。
string[][] t = new string[h][];
for (int i = 0; i < h; i++)
{
// t[i][j]はi行j列に置かれたトランプに書かれた数字を表します。
t[i] = Console.ReadLine().Split();
}
// 神経衰弱クラスをインスタンス化します。
Concentration concentration = new Concentration(n, t);
// 次の行には、記録の長さ L が与えられます。
int L = int.Parse(Console.ReadLine());
// 続く L 行には、捲られたトランプの記録が時系列順で与えられます。
for (int i = 0; i < L; i++)
{
// これは、a行b列のトランプとA行B列のトランプが捲られたことを表します。
int[] abAB = Array.ConvertAll(Console.ReadLine().Split(), x => int.Parse(x) - 1);
// トランプを捲ります。
concentration.Play(abAB[0], abAB[1], abAB[2], abAB[3]);
}
for (int i = 0; i < n; i++)
{
// i番目のプレイヤーが取り除いたトランプの枚数を出力します。
Console.WriteLine(concentration.GetScore(i));
}
}
}
Javascript
2024/08/25 parseInt
をNumber
に修正いたしました。
// 神経衰弱クラス
class Concentration {
// プレイヤーの数
nPlayers = 0;
// 配置されたトランプに書かれた数字
cards = null;
// 各プレイヤーが取り除いたトランプの枚数
scores = null;
// 手番のプレイヤー
player = 0;
// プレイヤーが取り除いたトランプの枚数を返します。
getScore(i) {
return this.scores[i];
}
// コンストラクタ
constructor(n, t) {
// プレイヤーの数
this.nPlayers = n;
// 配置されたトランプに書かれた数字
this.cards = t;
// プレイヤーが取り除いたトランプの枚数を初期化
this.scores = new Array(n).fill(0);
// ゲームが始まると、0番の人からプレイしていきます。
this.player = 0;
}
// トランプを捲ります。
play(a, b, c, d) {
//並べられたトランプから2枚のトランプを選び、めくります。
const t0 = this.cards[a][b];
const t1 = this.cards[c][d];
// めくった2枚のトランプに
if (t0 === t1) { // 同じ数字が書かれていれば
// 2枚のトランプはめくったプレーヤーのものとなります。
this.scores[this.player] += 2;
} else { // 異なる数字が書かれていれば
// 次のプレイヤーの手番となります。
this.player += 1;
// N-1番のプレイヤーの次のプレイヤーは0番のプレイヤーであるとします。
this.player %= this.nPlayers;
}
}
}
const lines = require("fs").readFileSync("/dev/stdin", "utf8").split("\n");
let row = 0;
// 1行目には3つの整数H, W, Nが入力されます。
// HとWはそれぞれ並べられたトランプの縦方向の枚数と横方向の枚数で、
// Nはプレイヤーの数を表します。
// const [h, w, n] = lines[row++].split(" ").map(x => parseInt(x, 10));
const [h, w, n] = lines[row++].split(" ").map(Number);
//続くH行には、配置されたトランプに書かれた数字が入力されます。
const t = [];
for (var i = 0; i < h; i++) {
//t[i][j]はi行j列に置かれたトランプに書かれた数字を表します。
t.push(lines[row++].split(" "));
}
// 神経衰弱クラスをインスタンス化します。
const concentration = new Concentration(n, t);
// 次の行には、記録の長さ L が与えられます。
// const L = parseInt(lines[row++]);
const L = Number(lines[row++]);
// 続く L 行には、捲られたトランプの記録が時系列順で与えられます。
for (var i = 0; i < L; i++) {
// これは、a行b列のトランプとA行B列のトランプが捲られたことを表します。
// let [a, b, A, B] = lines[row++].split(" ").map(x => parseInt(x, 10) - 1);
let [a, b, A, B] = lines[row++].split(" ").map(x => Number(x) - 1);
// トランプを捲ります。
concentration.play(a, b, A, B);
}
for (var i = 0; i < n; i++) {
// i番目のプレイヤーが取り除いたトランプの枚数を出力します。
console.log(concentration.getScore(i));
}
C++
#include <iostream>
#include <vector>
using namespace std;
// 神経衰弱クラス
class Concentration {
// プレイヤーの数
int nPlayers;
// 配置されたトランプに書かれた数字
vector<vector<string>> &cards;
// 各プレイヤーが取り除いたトランプの枚数
vector<int> scores;
// 手番のプレイヤー
int player;
public:
// プレイヤーが取り除いたトランプの枚数を返します。
int getScore(int i) {
return scores[i];
}
// コンストラクタ
Concentration(int n, vector<vector<string>> &t) :
nPlayers(n), cards(t) {
// プレイヤーが取り除いたトランプの枚数を初期化
scores.resize(n, 0);
// ゲームが始まると、0番の人からプレイしていきます。
player = 0;
}
// トランプを捲ります。
void play(int a, int b, int c, int d) {
//並べられたトランプから2枚のトランプを選び、めくります。
string t0 = cards[a][b];
string t1 = cards[c][d];
// めくった2枚のトランプに
if (t0 == t1) { // 同じ数字が書かれていれば
// 2枚のトランプはめくったプレーヤーのものとなります。
scores[player] += 2;
} else { // 異なる数字が書かれていれば
// 次のプレイヤーの手番となります。
player += 1;
// N-1番のプレイヤーの次のプレイヤーは0番のプレイヤーであるとします。
player %= nPlayers;
}
}
};
int main(void) {
//1行目には3つの整数H, W, Nが入力されます。
//HとWはそれぞれ並べられたトランプの縦方向の枚数と横方向の枚数で、
//Nはプレイヤーの数を表します。
int h, w, n;
cin >> h >> w >> n;
//続くH行には、配置されたトランプに書かれた数字が入力されます。
vector<vector<string>> t(h, vector<string>(w));
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
//t[i][j]はi行j列に置かれたトランプに書かれた数字を表します。
cin >> t[i][j];
}
}
// 神経衰弱クラスをインスタンス化します。
Concentration concentration(n, t);
// 次の行には、記録の長さ L が与えられます。
int L;
cin >> L;
// 続く L 行には、捲られたトランプの記録が時系列順で与えられます。
for (int i = 0; i < L; i++) {
// これは、a行b列のトランプとA行B列のトランプが捲られたことを表します。
int a, b, A, B;
cin >> a >> b >> A >> B;
// トランプを捲ります。
concentration.play(a - 1, b - 1, A - 1, B - 1);
}
for (int i = 0; i < n; i++) {
// i番目のプレイヤーが取り除いたトランプの枚数を出力します。
cout << concentration.getScore(i) << endl;
}
}
Kotlin
import java.util.*
// 神経衰弱クラス
class Concentration {
// プレイヤーの数
var nPlayers: Int
// 配置されたトランプに書かれた数字
var cards: Array<Array<String>>
// 各プレイヤーが取り除いたトランプの枚数
var scores: Array<Int>
// 手番のプレイヤー
var player: Int
// プレイヤーが取り除いたトランプの枚数を返します。
fun getScore(i: Int): Int {
return scores[i]
}
// コンストラクタ
constructor(n: Int, t: Array<Array<String>>) {
// プレイヤーの数
this.nPlayers = n
// 配置されたトランプに書かれた数字
this.cards = t
// プレイヤーが取り除いたトランプの枚数を初期化
this.scores = Array(n) { 0 }
// ゲームが始まると、0番の人からプレイしていきます。
this.player = 0
}
// トランプを捲ります。
fun play(a: Int, b: Int, c: Int, d: Int) {
// 並べられたトランプから2枚のトランプを選び、めくります。
val t0 = cards[a][b]
val t1 = cards[c][d]
// めくった2枚のトランプに
if (t0.equals(t1)) { // 同じ数字が書かれていれば
// 2枚のトランプはめくったプレーヤーのものとなります。
this.scores[this.player] += 2
} else { // 異なる数字が書かれていれば
// 次のプレイヤーの手番となります。
this.player += 1
// N-1番のプレイヤーの次のプレイヤーは0番のプレイヤーであるとします。
this.player %= this.nPlayers
}
}
}
fun main() {
val sc = Scanner(System.`in`)
// 1行目には3つの整数H, W, Nが入力されます。
// HとWはそれぞれ並べられたトランプの縦方向の枚数と横方向の枚数で、
// Nはプレイヤーの数を表します。
val h = sc.nextInt()
val w = sc.nextInt()
val n = sc.nextInt()
// 続くH行には、配置されたトランプに書かれた数字が入力されます。
val t = Array(h){ Array(w) { "" }}
for (i in 0 until h) {
for (j in 0 until w) {
// t[i][j]はi行j列に置かれたトランプに書かれた数字を表します。
t[i][j] = sc.next()
}
}
// 神経衰弱クラスをインスタンス化します。
val concentration = Concentration(n, t)
// 次の行には、記録の長さ L が与えられます。
val L = sc.nextInt()
// 続く L 行には、捲られたトランプの記録が時系列順で与えられます。
for (i in 1..L) {
// これは、a行b列のトランプとA行B列のトランプが捲られたことを表します。
var a = sc.nextInt() - 1
var b = sc.nextInt() - 1
var A = sc.nextInt() - 1
var B = sc.nextInt() - 1
// トランプを捲ります。
concentration.play(a, b, A, B)
}
sc.close()
for (i in 0 until n) {
// i番目のプレイヤーが取り除いたトランプの枚数を出力します。
println(concentration.getScore(i))
}
}