diff --git a/ykoiso/src/A057_Swipe.java b/ykoiso/src/A057_Swipe.java new file mode 100644 index 0000000000000000000000000000000000000000..357dd57d2f7e5fd52f7bfdf785550e34dc57a6cd --- /dev/null +++ b/ykoiso/src/A057_Swipe.java @@ -0,0 +1,180 @@ +import java.util.Scanner; + +public class A057_Swipe { + public static void main(String[] args) { + final Scanner scan = new Scanner(System.in); + final int N = scan.nextInt(); + final int[][] squaresNum = new int[N][N]; + // スワイプの最大回数 + int maxSwipeCount = 0; + // 計算ごとの連続スワイプ数 + int currentSwipeCount = 0; + String str; + String[] strings; + // splitしたものをint型に直す + for (int y = 0; y < N; y++) { + str = scan.next(); + strings = str.split(""); + for (int x = 0; x < N; x++) { + squaresNum[y][x] = Integer.parseInt(strings[x]); + } + } + // それぞれの方向で最大連続数を更新していく + for (int y = 0; y < N; y++) { + for (int x = 0; x < N; x++) { + currentSwipeCount = checkBeside(squaresNum, N, y, x); + maxSwipeCount = updateMaxSwipeCount(maxSwipeCount, currentSwipeCount); + currentSwipeCount = checkVertical(squaresNum, N, y, x); + maxSwipeCount = updateMaxSwipeCount(maxSwipeCount, currentSwipeCount); + currentSwipeCount = checkRightDia(squaresNum, N, y, x); + maxSwipeCount = updateMaxSwipeCount(maxSwipeCount, currentSwipeCount); + currentSwipeCount = checkLeftDia(squaresNum, N, y, x); + maxSwipeCount = updateMaxSwipeCount(maxSwipeCount, currentSwipeCount); + } + } + // 結果の出力 + System.out.println(maxSwipeCount); + scan.close(); + } + + // 最大連続数を可能であれば更新する + //(判定する場合にはcan) + public static int updateMaxSwipeCount(final int maxSwipeCount, final int currentSwipeCount) { + if (currentSwipeCount > maxSwipeCount) { + return currentSwipeCount; + } + return maxSwipeCount; + } + + // 横に向けての計算 + // 増減両方判断するので反対側は必要なし + public static int checkBeside(final int[][] squaresNum, final int N, final int y, final int x) { + final int ruleNum; + // 連続できないなら1を返す + if (x == N - 1) { + return 1; + } + int target = squaresNum[y][x]; + int targetBeside = squaresNum[y][x + 1]; + // 連続の規則性を判断 + // 連続しない場合1を返す + if (target + 1 == targetBeside) { + ruleNum = +1; + } else if (target - 1 == targetBeside) { + ruleNum = -1; + } else { + return 1; + } + // 連続数の計算 + int maxSwipeCount = 1; + for (int currentX = x; currentX < N - 1; currentX++) { + target = squaresNum[y][currentX]; + targetBeside = squaresNum[y][currentX + 1]; + if (target + ruleNum == targetBeside) { + maxSwipeCount++; + } else { + break; + } + } + return maxSwipeCount; + } + + // 縦に向かって数字が連続しているかを計算 + //いくつ連続しているかを返す + public static int checkVertical(final int[][] squaresNum, final int N, final int y, + final int x) { + final int ruleNum; + if (y == N - 1) { + return 1; + } + int target = squaresNum[y][x]; + int targetVertical = squaresNum[y + 1][x]; + if (target + 1 == targetVertical) { + ruleNum = +1; + } else if (target - 1 == targetVertical) { + ruleNum = -1; + } else { + return 1; + } + int maxSwipeCount = 1; + for (int currentY = y; currentY < N - 1; currentY++) { + target = squaresNum[currentY][x]; + targetVertical = squaresNum[currentY + 1][x]; + if (target + ruleNum == targetVertical) { + maxSwipeCount++; + } else { + break; + } + } + return maxSwipeCount; + } + + // 右斜め下に対しての計算 + public static int checkRightDia(final int[][] squaresNum, final int N, final int y, + final int x) { + final int ruleNum; + if (y == N - 1 || x == N - 1) { + return 1; + } + int target = squaresNum[y][x]; + int targetRightDia = squaresNum[y + 1][x + 1]; + if (target + 1 == targetRightDia) { + ruleNum = +1; + } else if (target - 1 == targetRightDia) { + ruleNum = -1; + } else { + return 1; + } + // xとyの両方が変わるためwhile文に + int currentX = x; + int currentY = y; + int maxSwipeCount = 1; + while (currentY < N - 1 && currentX < N - 1) { + target = squaresNum[currentY][currentX]; + targetRightDia = squaresNum[currentY + 1][currentX + 1]; + if (target + ruleNum == targetRightDia) { + maxSwipeCount++; + // 値のインクリメント + currentX++; + currentY++; + } else { + break; + } + } + return maxSwipeCount; + } + + // 左斜めに対しての計算 + public static int checkLeftDia(final int[][] squaresNum, final int N, final int y, + final int x) { + final int ruleNum; + if (y == N - 1 || x == 0) { + return 1; + } + int target = squaresNum[y][x]; + int targetLeftDia = squaresNum[y + 1][x - 1]; + if (target + 1 == targetLeftDia) { + ruleNum = +1; + } else if (target - 1 == targetLeftDia) { + ruleNum = -1; + } else { + return 1; + } + int currentX = x; + int currentY = y; + int maxSwipeCount = 1; + while (currentY < N - 1 && currentX > 0) { + target = squaresNum[currentY][currentX]; + targetLeftDia = squaresNum[currentY + 1][currentX - 1]; + if (target + ruleNum == targetLeftDia) { + maxSwipeCount++; + // 反対方向なのでxはデクリメント + currentX--; + currentY++; + } else { + break; + } + } + return maxSwipeCount; + } +} diff --git a/ykoiso/test/A057_SwipeTest.java b/ykoiso/test/A057_SwipeTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a2087bc424f0696e17d8fc2b8e1009b92feb6d22 --- /dev/null +++ b/ykoiso/test/A057_SwipeTest.java @@ -0,0 +1,75 @@ +import static org.junit.Assert.assertThat; +import org.junit.Test; +import static org.hamcrest.CoreMatchers.*; + +public class A057_SwipeTest { + int[][] map = { + {1, 2, 3, 4, 5,}, + {2, 5, 1, 4, 5,}, + {3, 5, 3, 2, 5,}, + {5, 2, 5, 5, 1,}, + {1, 5, 5, 4, 5,} + }; + final int N = 5; + int x; + int y; + A057_Swipe swipe = new A057_Swipe(); + + @Test + public void 横方向に対しての値の増加をカウントできる() { + y = 0; + x = 0; + final int actual = swipe.checkBeside(map, N, y, x); + final int expected = 5; + assertThat(actual, is(expected)); + } + @Test + public void 縦に対しての値の増加をカウントできる() { + y = 0; + x = 0; + final int actual = swipe.checkVertical(map, N, y, x); + final int expected = 3; + assertThat(actual, is(expected)); + } + @Test + public void 斜め右に対して値の上下を正しくカウントできる() { + y = 1; + x = 2; + final int actual = swipe.checkRightDia(map, N, y, x); + final int expected = 2; + assertThat(actual, is(expected)); + } + @Test + public void 斜め左に対して値の減少をカウントできる() { + y = 0; + x = 4; + final int actual = swipe.checkLeftDia(map, N, y, x); + final int expected = 5; + assertThat(actual, is(expected)); + } + @Test + public void 計算できない位置で呼び出したとき1を返す() { + y = 2; + x = 4; + final int actual = swipe.checkBeside(map, N, y, x); + final int expected = 1; + assertThat(actual, is(expected)); + } + @Test + public void 連続していないとき1を返す() { + y = 1; + x = 0; + final int actual = swipe.checkBeside(map, N, y, x); + final int expected = 1; + assertThat(actual, is(expected)); + } + @Test + public void 値が上下するような場合はカウントされない() { + y = 4; + x = 2; + final int actual = swipe.checkBeside(map, N, y, x); + final int expected = 2; + assertThat(actual, is(expected)); + } + +}