From 51bdea6cc6594b573eadda1c65a24bc2261c1550 Mon Sep 17 00:00:00 2001 From: kkanazawa Date: Thu, 3 Jul 2025 09:09:24 +0900 Subject: [PATCH 1/3] =?UTF-8?q?paiza=E3=81=AE=E5=95=8F=E9=A1=8CB138?= =?UTF-8?q?=E3=81=AE=E5=9B=9E=E7=AD=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kkanazawa/src/CountDonuts.java | 130 +++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 kkanazawa/src/CountDonuts.java diff --git a/kkanazawa/src/CountDonuts.java b/kkanazawa/src/CountDonuts.java new file mode 100644 index 0000000..7ba9077 --- /dev/null +++ b/kkanazawa/src/CountDonuts.java @@ -0,0 +1,130 @@ +package paiza.src; + +import java.util.Scanner; + +/** + * 二次元の入力に含まれているドーナツを検出し、その数を表示する. + * + * @author 金澤継心 + */ +public class CountDonuts { + + /** + * 入力値の行数と列数を入力した後、入力値に含まれているドーナツを検出し、その数を表示する. + * + */ + public static void main(String[] args) { + + DonutsFeature feature = new DonutsFeature(); // ドーナツを構成する要素のクラスオブジェクト + + Scanner sc = new Scanner(System.in); + int lineAmount = sc.nextInt(); // 入力値の行の数 + int columnAmount = sc.nextInt(); // 入力値の列の数 + String[] pictureRow = new String[lineAmount]; // 入力値を保存する配列 + + for (int i = 0; i < lineAmount; i++) { + pictureRow[i] = sc.next(); + } + sc.close(); + + System.out.println(returnDonutsAmount(lineAmount, columnAmount, pictureRow, feature)); + + } + + /** + * 受け取った配列に含まれているドーナツを検出し、その数を返す + * + * @param lineAmount 配列の要素数 二次元の行の数に相当 + * @param columnAmount 配列の要素一つあたりの文字数 二次元の列の数に相当 + * @param pictureRow 文字列の配列 + * @param ドーナツを構成する要素のクラスオブジェクト + */ + public static int returnDonutsAmount(final int lineAmount, final int columnAmount, + final String[] pictureRow, final DonutsFeature feature) { + + int donutsAmount = 0; // 検出したドーナツの数 + + // まず上の行から順にドーナツの構成要素1が含まれているか検索 + // ドーナツは3行必要なので、繰り返し数は(行の総数-2) + for (int i = 0; i < lineAmount - 2; i++) { + int j = 0;// これから検索する列の先頭インデックス + + // ドーナツは3列必要なので、(検索するインデックス+2)が列の総数を超えたらその行の検索終了 + while (columnAmount >= j + 2) { + // 構成要素1があるインデックスを返す + // 構成要素がなければ-1を返す + int featureIndex = pictureRow[i].indexOf(feature.getFeature1(), j); + + // ドーナツの構成要素1がヒットした場合、その下の列にも構成要素があるか調べる + if (-1 != featureIndex) { + // 1つ下の行のうち、構成要素1がヒットした列と同じ範囲の部分文字列 + String secondLine = pictureRow[i + 1].substring(featureIndex, featureIndex + 3); + // 2つ下の行のうち、構成要素1がヒットした列と同じ範囲の部分文字列 + String thirdLine = pictureRow[i + 2].substring(featureIndex, featureIndex + 3); + // 1つ下の行、2つ下の行で構成要素と合致していればドーナツを検出したとしてカウント + if (feature.isFitFeature2(secondLine) && feature.isFitFeature3(thirdLine)) { + donutsAmount++; + // 検索する列の先頭を(ドーナツを検出した列+1)に更新 + j = featureIndex + 1; + } else { + j++; // 構成要素2または構成要素3が見つからなければ検索する列の先頭を進める + } + // 構成要素1が現在の行で見つからなければ次の行の検索に移行 + } else { + break; + } + } + } + return donutsAmount; + } +} + + +/** + * ドーナツを構成する要素のクラス ドーナツの構成要素を3つの列に分けている. + * + * + */ +class DonutsFeature { + private String feature1 = "###"; // ドーナツの構成要素1列目 + private String feature2 = "#.#"; // ドーナツの構成要素2列目 + private String feature3 = "###"; // ドーナツの構成要素3列目 + + public String getFeature1() { + return feature1; + } + + public void setFeature1(final String feature1) { + this.feature1 = feature1; + } + + public String getFeature2() { + return feature2; + } + + public void setFeature2(final String feature2) { + this.feature2 = feature2; + } + + public String getFeature3() { + return feature3; + } + + public void setFeature3(final String feature3) { + this.feature3 = feature3; + } + + // 引数の文字列が構成要素と合致していればtrue, 合致していなければfalse + public boolean isFitFeature1(final String str) { + return str.equals(this.feature1); + } + + public boolean isFitFeature2(final String str) { + return str.equals(this.feature2); + } + + public boolean isFitFeature3(final String str) { + return str.equals(this.feature3); + } + +} -- GitLab From eee26abaf22910ff69a71dba13f4efe9631f22fd Mon Sep 17 00:00:00 2001 From: kkanazawa Date: Thu, 3 Jul 2025 09:18:39 +0900 Subject: [PATCH 2/3] =?UTF-8?q?paiza=E3=81=AE=E5=95=8F=E9=A1=8CB138?= =?UTF-8?q?=E3=81=AE=E5=9B=9E=E7=AD=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kkanazawa/src/CountDonuts.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kkanazawa/src/CountDonuts.java b/kkanazawa/src/CountDonuts.java index 7ba9077..5a617e1 100644 --- a/kkanazawa/src/CountDonuts.java +++ b/kkanazawa/src/CountDonuts.java @@ -13,7 +13,7 @@ public class CountDonuts { * 入力値の行数と列数を入力した後、入力値に含まれているドーナツを検出し、その数を表示する. * */ - public static void main(String[] args) { + public static void main(final String[] args) { DonutsFeature feature = new DonutsFeature(); // ドーナツを構成する要素のクラスオブジェクト -- GitLab From 1362427994ebc30ea72284cf3663e0bdb12cd156 Mon Sep 17 00:00:00 2001 From: kkanazawa Date: Thu, 3 Jul 2025 15:27:07 +0900 Subject: [PATCH 3/3] =?UTF-8?q?paiza=E3=81=AE=E5=95=8F=E9=A1=8CB138?= =?UTF-8?q?=E3=81=AE=E5=9B=9E=E7=AD=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{CountDonuts.java => DonutsCounter.java} | 58 +++++++++++-------- 1 file changed, 35 insertions(+), 23 deletions(-) rename kkanazawa/src/{CountDonuts.java => DonutsCounter.java} (62%) diff --git a/kkanazawa/src/CountDonuts.java b/kkanazawa/src/DonutsCounter.java similarity index 62% rename from kkanazawa/src/CountDonuts.java rename to kkanazawa/src/DonutsCounter.java index 5a617e1..b703570 100644 --- a/kkanazawa/src/CountDonuts.java +++ b/kkanazawa/src/DonutsCounter.java @@ -7,7 +7,7 @@ import java.util.Scanner; * * @author 金澤継心 */ -public class CountDonuts { +public class DonutsCounter { /** * 入力値の行数と列数を入力した後、入力値に含まれているドーナツを検出し、その数を表示する. @@ -18,8 +18,8 @@ public class CountDonuts { DonutsFeature feature = new DonutsFeature(); // ドーナツを構成する要素のクラスオブジェクト Scanner sc = new Scanner(System.in); - int lineAmount = sc.nextInt(); // 入力値の行の数 - int columnAmount = sc.nextInt(); // 入力値の列の数 + final int lineAmount = sc.nextInt(); // 入力値の行の数 + final int columnAmount = sc.nextInt(); // 入力値の列の数 String[] pictureRow = new String[lineAmount]; // 入力値を保存する配列 for (int i = 0; i < lineAmount; i++) { @@ -47,36 +47,48 @@ public class CountDonuts { // まず上の行から順にドーナツの構成要素1が含まれているか検索 // ドーナツは3行必要なので、繰り返し数は(行の総数-2) for (int i = 0; i < lineAmount - 2; i++) { - int j = 0;// これから検索する列の先頭インデックス + int searchIndex = 0;// これから検索する列の先頭インデックス // ドーナツは3列必要なので、(検索するインデックス+2)が列の総数を超えたらその行の検索終了 - while (columnAmount >= j + 2) { + while (columnAmount >= searchIndex + 2) { // 構成要素1があるインデックスを返す // 構成要素がなければ-1を返す - int featureIndex = pictureRow[i].indexOf(feature.getFeature1(), j); - - // ドーナツの構成要素1がヒットした場合、その下の列にも構成要素があるか調べる - if (-1 != featureIndex) { - // 1つ下の行のうち、構成要素1がヒットした列と同じ範囲の部分文字列 - String secondLine = pictureRow[i + 1].substring(featureIndex, featureIndex + 3); - // 2つ下の行のうち、構成要素1がヒットした列と同じ範囲の部分文字列 - String thirdLine = pictureRow[i + 2].substring(featureIndex, featureIndex + 3); - // 1つ下の行、2つ下の行で構成要素と合致していればドーナツを検出したとしてカウント - if (feature.isFitFeature2(secondLine) && feature.isFitFeature3(thirdLine)) { - donutsAmount++; - // 検索する列の先頭を(ドーナツを検出した列+1)に更新 - j = featureIndex + 1; - } else { - j++; // 構成要素2または構成要素3が見つからなければ検索する列の先頭を進める - } - // 構成要素1が現在の行で見つからなければ次の行の検索に移行 - } else { + int featureIndex = pictureRow[i].indexOf(feature.getFeature1(), searchIndex); + + // 構成要素1が現在の行で見つからなければ次の行の検索に移行 + if (featureIndex == -1) { break; } + // 1つ下の行、または2つ下の行で構成要素が見られなかったら次の列からの検索に移行 + if (!isDetectionDonuts(i, pictureRow, featureIndex, feature)) { + searchIndex++; + continue; + } + // 全ての構成要素が見られた場合、ドーナツの検出としてカウント + donutsAmount++; + searchIndex = featureIndex + 1; } } return donutsAmount; } + + /** + * 1つ下の行で2列目の構成要素と合致、かつ2つ下の行での3列目の構成要素と合致」の真偽値を返す + * + * @param lineAmount 配列の要素数 二次元の行の数に相当 + * @param columnAmount 配列の要素一つあたりの文字数 二次元の列の数に相当 + * @param pictureRow 文字列の配列 + * @param ドーナツを構成する要素のクラスオブジェクト + */ + public static boolean isDetectionDonuts(final int lineIndex, final String[] pictureRow, + final int columnIndex, final DonutsFeature feature) { + // 1つ下の行のうち、構成要素1がヒットした列と同じ範囲の部分文字列を取得 + String secondLine = pictureRow[lineIndex + 1].substring(columnIndex, columnIndex + 3); + // 2つ下の行のうち、構成要素1がヒットした列と同じ範囲の部分文字列を取得 + String thirdLine = pictureRow[lineIndex + 2].substring(columnIndex, columnIndex + 3); + + return (feature.isFitFeature2(secondLine) && feature.isFitFeature3(thirdLine)); + } } -- GitLab