はじめに
この記事は、プログラミング初心者が書いています。
間違っていること、もっとこうした方がいいよ!!等ございましたら、
コメントお願いします。
また、この問題はpaizaの練習問題になります。
ランクの上下には全く関係のないものですので、ご安心ください。
 
非オブジェクト指向で書いたやつ
Javaで解いてみた!! Paiza練習問題「長テーブルのうなぎ屋」
こちらは手続き型(あってる?)で解いています。
この記事を投稿した際に、オブジェクト指向で書いたコードがあったため、
自分なりに消化させていただきました。
問題の具体的な内容などもこちらでご確認ください。
オブジェクト指向で考える
非オブジェクト指向で書いたコード
import java.util.*;
public class unagiya {
    public static void main(String[] args) {
        /*
         * 店の総席数、来店するグループ数をString型で取得しlineに格納
         * lineに格納したデータをsplitで分けてString配列のlineArrayに格納
         */
        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] lineArray = line.split(" ");
        /*
         * lineArrayに格納したデータをキャストして各変数に格納
         * 
         * seatNum:座席の数
         * totalGuest:来店するグループの数
        */
        int seatNum = castString(lineArray[0]);
        int totalGuest = castString(lineArray[1]);
        /*
         * seats:座席数をhashMapで作成
         * Integerが席番号
         * Booleanが人の有無(trueなら座れる,)
         */
        Map<Integer,Boolean> seats = new HashMap<>();
        for(int i = 1; i <= seatNum; i++){
            seats.put(i,true);
        }
        /*
         *isSitCustomer:客が選んだ席に人がいるかいないか確認
         *いなければtrueを投げる
         *
         * choiceSeat:来た客が選ぶ基点となる席番号
         *menberNum:来た客の数
         */
        int choiceSeat = 0;
        int memberNum = 0;
        for(int i = 0; i < totalGuest; i++){
            //コンソールの入力値を受け取り、
            //memberNumとchoiceSeatに代入
            line = scanner.nextLine();
            lineArray = line.split(" ");
            memberNum = castString(lineArray[0]);
            choiceSeat = castString(lineArray[1]);
            //isSitGuestがtrueなら、客の選んだ席、人数の座席情報をfalseに書き換える
            if(isSitGuest(seats,choiceSeat,memberNum)){
                for(int j = 0,index = 1 ; j < memberNum; j++){
                    if(seats.size() < choiceSeat + j){
                        seats.put(index, false);
                        index++;
                    } else {
                        seats.put(choiceSeat + j,false);
                    }
                }
            }
        }
        //座席情報のfalseの数を調べてリザルトに代入
        int result = 0;
        for(int i = 1; i <= seats.size(); i++){
            if(seats.get(i).equals(false)){
                result++;
            }
        }
        System.out.println(result);
    }
    //String型の数値をint型にキャスト
    public static int castString(String strNum){
        int num = Integer.parseInt(strNum);
        return num;
    }
    /*
     * Map座席の情報、客が選んだ席、客の人数を受け取り、
     * 客が選んだ席から、客の人数分、falseがあるかチェック
     * 
     * 条件
     * 客の人数が席より多ければfalseを返す
     * 座席情報に一つでもfalseがあればfalseを返す
     */
    public static boolean isSitGuest(Map seats, int choiceSeat, int menberNum){
        if(menberNum > seats.size()){
            return false;    
        }
        boolean flag = true;
        for(int i = 0,index = 1; i < menberNum; i++){
            //index:座席情報の一番最初の1を指定
            //客の数が座席番号を超えたら1から数える時に使用
            if(seats.size() < choiceSeat + i){
                if(seats.get(index).equals(false)){
                    flag = false;
                    index++;
                } else {
                    index++;
                }
            } else if(seats.get(choiceSeat + i).equals(false)){
                flag = false;
            }
            }
        if(flag){
            return true;
        } else {
            return false;
        }
    }
}
だ、誰が書いたんだこのコード・・・
2週間ほど経って読み返してみたのですが、まあ見難い。
Mapで座席を作って色々やってますね・・・。
(途中で読むのをやめた)
この時の自分は「まあまあいいコード書けたぜw」なんて調子乗ってました。
しかし、流星のように現れたshiracamusさんの一言
「せっかくなのでオブジェクト指向しましょ」
その言葉と一緒に残していったコードがこちら
(shiracamusさんからコード掲載の許可をいただいております)
@shiracamusさんのコード
import java.util.*;
enum Seat { AVAILABLE, TAKEN };
class LongTable {
    private Seat seat[];
    LongTable(int seatNum) {
        seat = new Seat[seatNum];
        for (int i = 0; i < seatNum; i++) {
            seat[i] = Seat.AVAILABLE;
        }
    }
    boolean sit(int position, int num) {
        for (int i = position; i < position + num; i++) {
            if (seat[i % seat.length] != Seat.AVAILABLE) {
                return false;
            }
        }
        for (int i = position; i < position + num; i++) {
            seat[i % seat.length] = Seat.TAKEN;
        }
        return true;
    }
}
public class Unagiya {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String[] input = scanner.nextLine().split(" ");
        int seatNum = Integer.parseInt(input[0]);
        int groupNum = Integer.parseInt(input[1]);
        LongTable table = new LongTable(seatNum);
        int sitCount = 0;
        for (int i = 0; i < groupNum; i++){
            input = scanner.nextLine().split(" ");
            int memberNum = Integer.parseInt(input[0]);
            int seatNumber = Integer.parseInt(input[1]);
            if (table.sit(seatNumber, memberNum)) {
                sitCount += memberNum;
            }
        }
        System.out.println(sitCount);
    }
}
オブジェクト指向ってなんだっけ???
このコードを見た瞬間、体に電撃が流れました。
おそらく僕のコードをベースに書き直したのでしょう。
ならば僕はもっと時間を掛けて、
僕なりの「オブジェクト指向」で書いてみようと思います。
うなぎ屋の登場オブジェクト
僕はまず登場人物から考え始めます。
まずは
・長テーブル
enum Seat {AVAILABLE,UNAVAILABLE}
TAKENから
対象的なUNAVAILABLEに変更しました。
そしてテーブル。
テーブルはテーブルなので、メソッド(動作)はありません。そこにただ存在するだけです。
class LongTable {
	Seat[] seats;
	/**
	 * テーブルを作成するコンストラクタ
	 * 初期値はAVAILABLE
	 * @param tableNum
	 */
	LongTable(Integer tableNum) {
		this.seats = new Seat[tableNum];
		for (int i = 0; i < tableNum; i++) {
			seats[i] = Seat.AVAILABLE;
		}
	}
}
次に江戸っ子のお客さん。今回は少し気が早いとのことです。
席に人がいなかったら(isSit)座る(sitting)
席に人がいたら(isSit)帰る
class Guest {
	/**
	 * 客が選んだ席に人がいなかったらtrueを投げるメソッド
	 * @param guestNum
	 * @param choiceNum
	 * @param table
	 * @return
	 */
	public static Boolean isSit(Integer guestNum, Integer choiceNum, LongTable table) {
		Boolean seatConfirmation = true;
		for (int i = choiceNum; i < choiceNum + guestNum; i++) {
			if (table.seats[i % table.seats.length] == Seat.UNAVAILABLE) {
				seatConfirmation = false;
			}
		}
		return seatConfirmation;
	}
	/**
	 * 客が座り、その席をUNAVAILABLEにするメソッド
	 * @param guestNum
	 * @param choiceNum
	 * @param table
	 */
	public static void sitting(Integer guestNum, Integer choiceNum, LongTable table) {
		for (int i = choiceNum; i < choiceNum + guestNum; i++) {
			table.seats[i % table.seats.length] = Seat.UNAVAILABLE; 
		}
	}
}
では、席に座っている人の数を数えるのは・・・
多分お店のスタッフさんになりますね。
class Staff {
	/**
	 * 座っている人の数を数えるメソッド
	 * @param table
	 * @return count(SeatのUNAVAILABLEの数を数える)
	 */
	public static Integer sitCount(LongTable table) {
		Integer count = 0;
		for (int i = 0; i < table.seats.length; i++) {
			if (table.seats[i] == Seat.UNAVAILABLE) {
				count++;
			}
		}
		return count;
	}
}
これで登場人物は揃いました。
あとはストーリーが進んでいくのを見守るだけです。
Mainメソッドの記述
ストーリーはmainメソッドに記述していきます。
public class Unagiya {
	public static void main(String[] args) throws Exception{
		//input:コンソールからの入力値を1行取得
		//inpuArray:1行の数値を分けて配列に格納
		Scanner scanner = new Scanner(System.in);
		String input = scanner.nextLine();
		String[] inputArray = input.split(" ");
		
		//tableNum:うなぎ屋の座席の数
		//toDayGuest:本日ゲストが全部で何グループ来るか
		Integer tableNum = toCastString(inputArray[0]);
		Integer toDayGuest = toCastString(inputArray[1]);
		
		LongTable table = new LongTable(tableNum);
		
		//guestNum:1グループの人数
		//choiceNum:ゲストが選んだ席
		Integer guestNum = 0;
		Integer choiceNum = 0;
		for (int i = 0; i < toDayGuest; i++) {
			
			input = scanner.nextLine();
			inputArray = input.split(" ");
			
			guestNum = toCastString(inputArray[0]);
			choiceNum = toCastString(inputArray[1]);
			
			if (Guest.isSit(guestNum, choiceNum, table)) {
				Guest.sitting(guestNum, choiceNum, table);
			}
		}
		Integer count = Staff.sitCount(table);
		System.out.println(count);
	}
	/**
	 * String型のアラビア数字をInteger型に変換するメソッド
	 * @param strNum
	 * @return num
	 */
	public static Integer toCastString(String strNum) {
		Integer num = Integer.parseInt(strNum);
		return num;
	}
	
}
結果
問題なく通りました。
参考
https://www.slideshare.net/masuda220/ss-14263541
こちらのスライドは非常に参考になるのですが、
縛りが非常に厳しいため、少し緩めにやっていますww
意見、感想、改善点、僕の悪口、募集中です
僭越ながら2回目の記事投稿になりました。
Qiitaの暗黙の了解などおそらくガン無視して書いてます。
上記の件含め、読んでくださった方は、何か記録を残していただけるとありがたいです。
最後まで読んでくれた方、ありがとうございました。


