diff --git a/knoda/src/A066_ContinuousWork.java b/knoda/src/A066_ContinuousWork.java new file mode 100644 index 0000000000000000000000000000000000000000..c549d3c89fe82cb17015ac08b1f5d976f81c37b0 --- /dev/null +++ b/knoda/src/A066_ContinuousWork.java @@ -0,0 +1,120 @@ +package hellojunit; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.Set; + +public class A066_ContinuousWork { + + public static void main(String[] args) { + final Scanner scan = new Scanner(System.in); + final int workNum = scan.nextInt(); + final List> workList = new ArrayList>(); + for (int i = 0; i < workNum; i++) { + final List schedule = new ArrayList(); + schedule.add(scan.nextInt()); // ある仕事の開始日 + schedule.add(scan.nextInt()); // ある仕事の終了日 + workList.add(schedule); + } + final ContinuousWork continuousWork = new ContinuousWork(); + // 最大連勤日数を取得する + System.out.println(continuousWork.getContinuousWorkDay(workList)); + scan.close(); + } + +} + +class ContinuousWork { + private final int START_TIME_INDEX = 0; // ある仕事開始日の要素番号 + private final int FINISH_TIME_INDEX = 1; // ある仕事終了日の表す要素番号 + private Map workDayMap = new LinkedHashMap(); + + /** + * 最大連勤日数を取得するメソッド + * @param workList : それぞれの仕事の開始日と終了日が格納されているリスト + * @return maxContinuousWorkDay : 最大連勤日数 + */ + public int getContinuousWorkDay(final List> workList) { + final int startDay = getStartDay(workList); // すべての仕事の開始日 + final int finishDay = getFinishDay(workList); // すべての仕事の終了日 + + // すべての日の勤務状態をfalseに初期化する + setWorkDayMap(startDay, finishDay); + + // 仕事を行う日を調べる(workDayMapの値をtrueにする) + for (final List schedule : workList) { + for (int day = schedule.get(START_TIME_INDEX); day <= schedule.get(FINISH_TIME_INDEX); day++) { + workDayMap.replace(day, true); + } + } + + // 連勤日数を格納するリスト + final List continuousWorkDayList = new ArrayList(); + final Set daySet = workDayMap.keySet(); + int continuousWorkDay = 0; // 連勤日数 + // 連勤日数を算出する + for (final Integer day : daySet) { + if (workDayMap.get(day)) { + continuousWorkDay++; + } else { + continuousWorkDayList.add(continuousWorkDay); + continuousWorkDay = 0; + } + } + continuousWorkDayList.add(continuousWorkDay); + + int maxContinuousWorkDay = 1; + // 最大連勤日数を算出する + for (final Integer cWorkDay : continuousWorkDayList) { + if (maxContinuousWorkDay < cWorkDay) { + maxContinuousWorkDay = cWorkDay; + } + } + return maxContinuousWorkDay; + } + + + /** + * すべての仕事の開始日を取得するメソッド + * @param workList : それぞれの仕事の開始日と終了日が格納されているリスト + * @return startDay : すべての仕事の開始日 + */ + private int getStartDay(final List> workList) { + int startDay = 100000; + for (int i = 0; i < workList.size(); i++) { + if (workList.get(i).get(START_TIME_INDEX) < startDay) { + startDay = workList.get(i).get(START_TIME_INDEX); + } + } + return startDay; + } + + /** + * すべての仕事の終了日を取得するメソッド + * @param workList : それぞれの仕事の開始日と終了日が格納されているリスト + * @return finishDay : すべての仕事の終了日 + */ + private int getFinishDay(final List> workList) { + int finishDay = 1; + for (int i = 0; i < workList.size(); i++) { + if (finishDay < workList.get(i).get(FINISH_TIME_INDEX)) { + finishDay = workList.get(i).get(FINISH_TIME_INDEX); + } + } + return finishDay; + } + + /** + * すべての日の勤務状態をfalseに初期化するメソッド + * @param startDay : すべての仕事の開始日 + * @param finishDay : すべての仕事の終了日 + */ + private void setWorkDayMap(final int startDay, final int finishDay) { + for (int day = startDay; day <= finishDay; day++) { + workDayMap.put(day, false); + } + } +} diff --git a/knoda/test/A066_ContinuousWorkTest.java b/knoda/test/A066_ContinuousWorkTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5e81bee58a8a18f600acaa81a1a520cafc80a814 --- /dev/null +++ b/knoda/test/A066_ContinuousWorkTest.java @@ -0,0 +1,74 @@ +package hellojunit; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class A066_ContinuousWorkTest { + + @Test + public void 仕事が1つのみ存在するときのテスト() { + final List> workList = new ArrayList>(Arrays.asList( + new ArrayList(Arrays.asList(1, 4)))); + final ContinuousWork continuousWork = new ContinuousWork(); + final int expected = 4; + final int actual = continuousWork.getContinuousWorkDay(workList); + assertThat(actual, is(expected)); + } + + @Test + public void 仕事が10000存在するときのテスト() { + final List> workList = new ArrayList>(); + for (int i = 0; i < 10000; i++) { + final List schedule = new ArrayList(); + schedule.add(i + 1); + schedule.add(i + 1); + workList.add(schedule); + } + final ContinuousWork continuousWork = new ContinuousWork(); + final int expected = 10000; + final int actual = continuousWork.getContinuousWorkDay(workList); + assertThat(actual, is(expected)); + } + + @Test + public void 基本テスト1() { + final List> workList = new ArrayList>(Arrays.asList( + new ArrayList(Arrays.asList(1, 4)), + new ArrayList(Arrays.asList(5, 7)))); + final ContinuousWork continuousWork = new ContinuousWork(); + final int expected = 7; + final int actual = continuousWork.getContinuousWorkDay(workList); + assertThat(actual, is(expected)); + } + + @Test + public void 基本テスト2() { + final List> workList = new ArrayList>(Arrays.asList( + new ArrayList(Arrays.asList(1, 2)), + new ArrayList(Arrays.asList(2, 3)), + new ArrayList(Arrays.asList(5, 7)), + new ArrayList(Arrays.asList(8, 15)))); + final ContinuousWork continuousWork = new ContinuousWork(); + final int expected = 11; + final int actual = continuousWork.getContinuousWorkDay(workList); + assertThat(actual, is(expected)); + } + + @Test + public void 基本テスト3() { + final List> workList = new ArrayList>(Arrays.asList( + new ArrayList(Arrays.asList(1, 4)), + new ArrayList(Arrays.asList(5, 6)), + new ArrayList(Arrays.asList(3, 7)))); + final ContinuousWork continuousWork = new ContinuousWork(); + final int expected = 7; + final int actual = continuousWork.getContinuousWorkDay(workList); + assertThat(actual, is(expected)); + } +}