読者です 読者をやめる 読者になる 読者になる

ちくわ

ちくわにきゅうりを入れるとうまい

AtCoder ABC #035 の B「ドローン」をやってみた

今回はこれをやりました。 問題文などはリンク先をご参照ください。

abc035.contest.atcoder.jp

この問題で最初に躓いたのは、

入力
入力は以下の形式で標準入力から与えられる。

S
T
1 行目にドローンに与えられた命令を表す文字列 S(1≦|S|≦105) が与えられる。ここで、 |S| は文字列 S の長さを表す。
S はL、R、U、D、?の 5 種類の文字のみからなる。
2 行目に求める値の種類を表す整数 T(1≦T≦2) が与えられる。

という、「入力」の部分でした。
改行コードで split する方向で考え始めましたが、何を持って入力終了とするのかと悩み、そんな難しい事は無いだろうと行き着いて、単純に STDIN.gets を 2 つ用意したらあっさり意図どおりに動きました。なるほどこれでよかったのか...

s = STDIN.gets.chomp.split("")
t = STDIN.gets.to_i

また、この問題は部分点が設定されており、

T=1 のデータセットに全て正解した場合 100 点が与えられる。
追加制約のないデータセットに正解した場合、追加で 1 点が与えられ、合計 101 点が得られる。

というものです。
T=1 のケースにおいては ? が出たらとりあえず 1 足しておけば最大値になるのではと考えてすぐに Score 100 は達成する事が出来ましたが、T=2 が思ったよりもケースが別れてしまい、手間取りました。 最終的に Score101 で Accepted となった回答はこんな感じです。

s = STDIN.gets.chomp.split("")
t = STDIN.gets.to_i
 
raise 'error' unless s.length >= 1 || s.length <= 1_000_000
raise 'error' unless t == 1 || t == 2
 
class B
  attr_reader :s, :t
  def self.result(s, t)
    ans = 0
    x = s.count("R") - s.count("L") 
    y = s.count("U") - s.count("D") 
    z = s.count("?")
    ans = x.abs + y.abs
    if t == 1
      ans = ans + z
    else
      if ans == z
        ans = 0
      elsif ans > z
        ans = ans - z
      else
        z = ans - z
        z % 2 == 0 ? ans = 0 : ans = 1
      end
    end
    p ans.abs
  end
end
 
B.result(s, t)

うーむ。すごいリファクタ出来る感が...とりあえず今の自分にはここまでということで、記録します。初心大事。

手間取った部分は幾つかのケースが別れており、何度か修正をしているとテストの必要性を身を持って体感しました。 次は、テストの書き方と、テストされやすい class の書き方を学ぼう。

A 「テレビ」はこちらで記録 AtCoder ABC #035 の A 「テレビ」をやってみた - ちくわ