diff --git a/ntakanabe/src/ValentineChocolate.java b/ntakanabe/src/ValentineChocolate.java new file mode 100644 index 0000000000000000000000000000000000000000..919c62239ccb5da48775a59344dbd10a09b03620 --- /dev/null +++ b/ntakanabe/src/ValentineChocolate.java @@ -0,0 +1,236 @@ +package paiza.src; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +/** + * . B136 バレンタインデーにチョコレートをもらうシミュレーション 指定された移動経路と各座席のチョコレートの数に基づいて、 + * 移動ごとに獲得したチョコレートの数を記録し、その結果を出力するクラス + * + * @author ntakanabe + */ +public class ValentineChocolate { + + /** + * . 標準入力から各データを読み込み、 チョコレート獲得処理メソッドを呼び出し、 その結果を出力メソッドに渡すmainメソッド + * + * @param args コマンドライン引数 + */ + public static void main(final String[] args) { + + final Scanner sc = new Scanner(System.in); + + // 移動回数moveCount、クラスの縦の席数height、横の席数width + final int moveCount = sc.nextInt(); + final int height = sc.nextInt(); + final int width = sc.nextInt(); + + // 自分の座席の開始位置startY(前から何列目か)、startX(左から何列目か) + final int startY = sc.nextInt() - 1; + final int startX = sc.nextInt() - 1; + + // 移動経路を表す文字列(F(前)、B(後)、L(左)、R(右)) + final String movePath = sc.next(); + + // 前からi列目、左からj列目にいるクラスメイトがくれるチョコレートの数 + final int[][] chocolates = new int[height][width]; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + chocolates[i][j] = sc.nextInt(); + } + } + + sc.close(); + + final InputRouteInfo inputRouteInfo = new InputRouteInfo(moveCount, height, width, startY, + startX, movePath, + chocolates); + + // moveProcessメソッドでのエラー発生時に出力するtry-catch文 + try { + final List getChocolates = moveProcess(inputRouteInfo); + outputResults(getChocolates); + } catch (final IllegalArgumentException e) { + System.err + .println("エラー: " + + e.getMessage()); + } + + } + + /** + * . 移動経路に基づいてチョコレートを獲得する処理メソッド + * + * @param moveCount 移動回数 + * @param startY 自分の座席の開始位置(行) + * @param startX 自分の座席の開始位置(列) + * @param movePath 移動経路を表す文字列 + * @param chocolates 各座席のチョコレートの数を格納した二次元配列 + * @return 獲得したチョコレートの数を順番に格納したリスト + */ + private static List moveProcess(final InputRouteInfo inputRouteInfo) { + + final List getChocolates = new ArrayList<>(); + + int currentY = inputRouteInfo.getStartY(); + int currentX = inputRouteInfo.getStartX(); + + final int height = inputRouteInfo.getHeight(); + final int width = inputRouteInfo.getWidth(); + + final int[][] seats = inputRouteInfo.getSeats(); + + // 移動経路に従ってチョコレートを獲得 + for (int i = 0; i < inputRouteInfo.getMoveCount(); i++) { + final char move = inputRouteInfo.getMovePath().charAt(i); + + switch (move) { + case 'F': // 前方向 + currentY--; + break; + case 'B': // 後方向 + currentY++; + break; + case 'L': // 左方向 + currentX--; + break; + case 'R': // 右方向 + currentX++; + break; + default: + break; + } + + // 境界値チェック + if (currentY < 0 || currentY >= height || currentX < 0 || currentX >= width) { + throw new IllegalArgumentException("座席の移動が範囲を超えました。現在の座標: (" + + currentY + + ", " + + currentX + + "), 移動方向: " + + move); + } + + getChocolates.add(seats[currentY][currentX]); + } + return getChocolates; + } + + /** + * . 獲得したチョコレートの数を出力するメソッド + * + * @param chocolates 獲得したチョコレートの数を格納したリスト + */ + private static void outputResults(final List chocolates) { + for (int chocolate : chocolates) { + System.out.println(chocolate); + } + } + + /** + * . 入力データを保持するためのヘルパークラス + */ + private static class InputRouteInfo { + private final int moveCount; + private final int height; + private final int width; + private final int startY; + private final int startX; + private final String movePath; + private final int[][] chocolates; + + /** + * . InputRouteInfoの新しいインスタンスを生成し、全てのフィールドを初期化するコンストラクタ + * + * @param moveCount 移動回数 + * @param height クラスの縦の席数 + * @param width クラスの横の席数 + * @param startY 自分の座席の開始行 + * @param startX 自分の座席の開始列 + * @param movePath 移動経路を表す文字列 + * @param chocolates 各座席のチョコレートの数を格納した二次元配列 + */ + public InputRouteInfo(final int moveCount, final int height, final int width, + final int startY, final int startX, final String movePath, + final int[][] chocolates) { + + this.moveCount = moveCount; + this.height = height; + this.width = width; + this.startY = startY; + this.startX = startX; + this.movePath = movePath; + this.chocolates = chocolates; + } + + /** + * . 移動回数を取得 + * + * @return 移動回数 + */ + public int getMoveCount() { + + return moveCount; + } + + /** + * . クラスの縦の席数を取得 + * + * @return クラスの縦の席数 + */ + public int getHeight() { + + return height; + } + + /** + * . クラスの横の席数を取得 + * + * @return クラスの横の席数 + */ + public int getWidth() { + + return width; + } + + /** + * . 自分の座席の開始行を取得 + * + * @return 自分の座席の開始行 + */ + public int getStartY() { + return startY; + } + + /** + * . 自分の座席の開始列を取得 + * + * @return 自分の座席の開始列 + */ + public int getStartX() { + + return startX; + } + + /** + * . 移動経路を表す文字列を取得 + * + * @return 移動経路を表す文字列 + */ + public String getMovePath() { + + return movePath; + } + + /** + * . すべての座席のチョコレートの数を取得 + * + * @return すべての座席のチョコレートの数を格納した二次元配列 + */ + public int[][] getSeats() { + + return chocolates; + } + } +}