Javaってこんな面倒くさい言語だっけ?
ココ最近(直近2~3念ぐらい)、
型定義はあれど比較的制限ユルユルなJavaScriptやTypeScriptばかりやってたお陰で、
Javaで問題解くのにめっちゃ時間かかってしまってる。。。
ほんと、何なんだよこのクソ言語。。。(実力不足
チェック処理とかは端折ってる
/** ここから定型文 */
ここで記載したクラスについては、
こっちの記事に書いてある、標準入力をList化したりしてるMainクラスから呼び出す予定だし・なんか継承したりしてるYO!!
ちな、Mainを実行して標準入力から入力するのクソ面倒くさいので、
Java編については問題の入力例をパラメータにしたテストクラスとかも作って公開するYO!!
開発・実行環境はこんな感じ
- VSCode
- Java 17
- jUnit 5.9
- maven
pom.xmlはこんな感じ
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jp.co.asil</groupId>
<artifactId>paiza202408</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
実装クラス
package jp.co.asil.paiza202408;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
public class LongTable extends Question {
public LongTable(List<String> list) {
super(list);
}
/**
* 東京の下町に長テーブルで有名な老舗うなぎ屋がありました。
*
* そのうなぎ屋にはとても大きい長テーブルがあり、テーブルの周りにn個の座席が配置されています。
* 座席には、時計回りに1, 2, …, nと番号が振られています。
* 座席はテーブルの周りに配置されているので、座席番号nの座席と1の座席は隣接しています。
*
* 今、m個のグループの人達が座席に順番に座りに来ます。i番目(1≦i≦m)のグループの人数をa_i人とします。
* 彼らは、長テーブルに並んだ座席の内、ある連続するa_i個の座席に一斉に座ろうとします。
*
* ただしお客さんは江戸っ子なので、それら座席のうち、いずれか一つでも既に先客に座られている座席があった場合、
* 一人も座らずにグループ全員で怒って帰ってしまいます。江戸っ子は気が早いんでぃ。
*
* 入力では、i番目のグループが座ろうとする連続した座席の位置は、整数b_iにより指定されます。
* i番目のグループは、座席番号b_iの座席を始点として、そこから時計回りにa_i個分の座席に座ろうとします。
*
* 最後のグループが座りに来た後、無事に長テーブルの座席に着席出来ている人数を出力するプログラムを作成してください。
*/
@Override
public List<String> answer() {
int[] cond = List.of(list.get(0).split(" ")).stream().mapToInt(Integer::parseInt).toArray();
// 座席情報(true:着席済み, false:空いとる)
Boolean[] seats = IntStream.range(0, cond[0]).mapToObj(i -> Boolean.FALSE).toArray(Boolean[]::new);
List<String> custList = list.subList(1, list.size());
root: for (String cust : custList) {
int[] c = List.of(cust.split(" ")).stream().mapToInt(Integer::parseInt).toArray();
// チェック
for (int i = 0; i < c[0]; i++)
if (seats[(c[1] - 1 + i) >= cond[0] ? 0 : c[1] - 1 + i])
continue root;
// 座らせる
for (int i = 0; i < c[0]; i++)
seats[(c[1] - 1 + i) >= cond[0] ? 0 : c[1] - 1 + i] = true;
}
return List.of(String.valueOf(Arrays.stream(seats).filter(v -> v).count()));
}
}
テストクラス
package jp.co.asil.paiza202408;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List;
import org.junit.jupiter.api.Test;
public class LongTableTest {
@Test
void testAnswer1() {
LongTable testClass = new LongTable(List.of("6 3",
"3 2",
"1 6",
"2 5"));
assertEquals(testClass.answer().get(0), "4");
}
@Test
void testAnswer2() {
LongTable testClass = new LongTable(List.of("12 6",
"4 6",
"4 8",
"4 10",
"4 12",
"4 2",
"4 4"));
assertEquals(testClass.answer().get(0), "12");
}
}
toArrayの直前
33行目のList.of(list.get(0).split(" ")).stream().mapToInt(Integer::parseInt).toArray();
だったり、
36行目のIntStream.range(0, cond[0]).mapToObj(i -> Boolean.FALSE).toArray(Boolean[]::new);
だったり、
何かと配列に変換してから処理をしたかった今回。
toArrayの引数で結構ダダハマってました。
33行目はtoArray前の処理でmapToInt
を実行しているため、中身が【intで確定】しているため、toArrayするとint[]
が生成されますが、
36行目では直前処理がmapToObj
となっているため、いくらmapToObj(i -> Boolean.FALSE)
と明らかなBooleanを設定したところで、toArrayで生成されるのはObject[]となってしまう動きらしいです。
型をキチンと設定するのであれば、toArrayの引数にきちんとした型のインスタンスを設定しないとダメよっていうお話。
てっきり33行目のノリで「toArrayしたらBoolean[]が出来るんやろ?」と思って以下のように実装したらClassCastException発生して発狂モンだったもん。
Boolean[] seats = (Boolean[])IntStream.range(0, cond[0]).mapToObj(i -> Boolean.FALSE).toArray();