AtCoder:7 ABC088B – Card Game for Two

25/12/2020

https://atcoder.jp/contests/abs/tasks/abc088_b
問題文は上記リンクを参照。

KotlinではListの並べ替えメソッドが便利に拡張されています。
またListを使ったfor文処理ではwithIndexを使えば添え字とデータを同時に扱えますね。

for ((index, value) in list.withIndex()) {}
for ((i, item) in list.withIndex()) {
    if (i % 2 == 0) {
        alice += item
    } else {
        bob += item
    }
}
println(alice - bob)

ここで行っている処理を見ると、偶数のデータと奇数のデータを抽出しているだけとも言えます。
つまり、このロジックは条件に合うデータを抽出するfilter、その添え字付きのfilterIndexedでも同様に書くことができます。
どちらも条件にあうデータをリスト形式で返します。

list.filterIndexed{ index, value -> 実行したい処理 }

これを使えば下記のようにfor文で回さなくても各要素に対して処理を書くことができますね。

val alice = list.filterIndexed{index, value -> index % 2 == 0}.sum()
val bob = list.filterIndexed{index, value -> index % 2 != 0}.sum()

ここまでは一旦aliceのカードとbobのカードをそれぞれ加算していき、最後に差分を求めるため減算していました。
ですがbobに割り振られたカードはまとめずに、その都度aliceのカードから減算しても意味は同じですね。

各要素に対して何らかの処理を行うmap関数にも添え字付きのmapIndexedがありますので、これを使えばListの要素に添え字を付けながら処理を書くことができます。

list.mapIndexed { index, value -> 実行したい処理 }

その結果mapIndexedを使えばbobのカードを取得することなく、以下のように1行で書くことができます。

val alice = list.mapIndexed { index, value -> if(index % 2 == 0) value else -value }.sum()

可読性をどう考えるかは人それぞれですが、だいぶ短くなりましたね。

参考

Kotlinのコレクションクラスの各メソッドをまとめて紹介している情報がありましたので参考までに。
Kotlin のコレクション使い方メモ
https://qiita.com/opengl-8080/items/36351dca891b6d9c9687

Advertisements