LoginSignup
0
3

More than 3 years have passed since last update.

AtCoder Beginner Contest 175 Task A - Rainy Season の鮮やかな解答(Python)

Last updated at Posted at 2020-08-16

経緯

A問題なので楽勝かと思いきや、自分はパッと鮮やかな解答が思いつきませんでした。
(時間がかかるのも嫌なので結局、8通りの場合分けをベタ書きするというセンスないコードを提出してしまいました、無念……。)

ヒントを得ようと上位者のSubmissionを眺めていると、itertoolsを使用した鮮やかな解答が多く見られましたが、最近Pythonを触り始めた私にはgroupbyがチンプンカンプンでした。今回、理解したので内容を記しておきます。

問題

AtCoder 町の、ある連続した$3$日間の天気の記録があります。天気の記録は長さ$3$の文字列$S$で表され、$i(1\leq i\leq 3)$日目の天気は$i$文字目が'S'のとき晴れ、'R'のとき雨でした。
天気が雨である日が連続していた最大の日数を求めてください。

制約
$\left| S \right| = 3$
$S$の各文字は'S'または'R'である

要求は非常にシンプルですが、単純に'R'の個数で判定すると'RSR'のパターンでNGとなります。

しょぼい解答

拡張性が皆無な書き方をすれば以下のようになります。ゴリ押しですね。

しょぼい解答
s = input()
if s == 'RRR':
  res = 3
elif s =='SRR':
  res = 2
elif s =='RSR':
  res = 1
elif s =='RRS':
  res = 2
elif s =='RSS':
  res = 1
elif s =='SRS':
  res = 1
elif s =='SSR':
  res = 1
else:
  res = 0
print(res)

普通の解答

おそらくこの程度が期待されているコードだと思われます。

普通の解答
s = input()
if 'RRR' in s:
    res = 3
elif 'RR' in s:
    res = 2
elif 'R' in s:
    res = 1
else:
    res = 0
print(res)

上位者の解答例

morio__さんという方が下記のようなコードを提出されていました。
黄コーダーの方で、Pythonで最速の開始36秒でのACということで完全にレベチです。

#15907417
from itertools import groupby
res = 0
s = input()
for k, v in groupby(s):
    if k == 'R':
        res = max(res, len(list(v)))
print(res)

汎用性が非常に高くて美しいですね。
指定するキーの部分を書き換えるだけで常に与えられた文字列の中の最長の連続数を取得できます。
コードとはかくあるべきと感じます。

groupbyについて

groupbyの公式ドキュメントです。
itertools.groupby(iterable, key=None)

多次元入力に対して任意のカラムでグルーピングも出来るようですが、今回は1次元配列で見てみます。
こんな挙動のようです。

# itertoolsからgroupbyをインポート(itertoolsには他にも便利なツールがたくさんありました)
from itertools import groupby

# groupbyする1次元配列
mylist = [0,0,0,1,1,2,2,2,1,1,1]

# groupbyはイテラブルでkeyとgroupが返る
for key, group in groupby(mylist):
  # groupの各要素をリストにキャストして出力
  print(key, list(group))

# 出力
# 0 [0, 0, 0]
# 1 [1, 1]
# 2 [2, 2, 2]
# 1 [1, 1, 1]

groupbyで得られるgroupはあくまでイテラブルな'オブジェクト'なので、扱う際にはリストにキャストしてあげないといけないみたいです。

ちなみにgroupの型をtype(group)で出力すると<class 'itertools._grouper'>でした。

理解した内容

キーが'R'のグループに対し、len(list(v))でグループの要素数を取得していき、最大のものを出力しているということですね。
非常に鮮やかで勉強になりました。自分ももっと精進します。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3