A問題・B問題(AtCoder Beginner Contest 164 復習)

4月26日に開催されたAtCoder Beginner Contest 164Rubyで参加しました。

今回は、A問題とB問題の復習です。

各問題の制約や入力・出力例は引用元ページ(AtCoderのサイト)をご覧ください。

A - Sheep and Wolves

問題文
羊が S 匹、狼が W 匹います。
狼の数が羊の数以上のとき、羊は狼に襲われてしまいます。
羊が狼に襲われるならunsafe、襲われないならsafeを出力してください。

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

A - Sheep and Wolves

提出したコード

s, w = gets.split.map(&:to_i)
puts s <= w ? "unsafe" : "safe"

結果:AC(正解) 実行時間:61 ms

考えたことを言語化してみる

これは単純な問題。SWが与えられ、SよりWが大きいときはunsafe、そうでなければsafeを出力すればいいです。if文で書けば以下のようになります。

if s <= w
  puts "unsafe"
else
  puts "safe"
end

elsifを使わないif文は、条件演算子で書くことが推奨されているらしいので、そっちで書きました。自分としてはいいコードかなと思います。

if文:if 条件 (then) trueのときの処理 else falseのときの処理

条件演算子条件 ? trueのときの処理 : falseのときの処理

docs.ruby-lang.org

B - Battle

問題文
高橋君と青木君がモンスターを闘わせます。
高橋君のモンスターは体力が A で攻撃力が B です。 青木君のモンスターは体力が C で攻撃力が D です。
高橋君→青木君→高橋君→青木君→... の順に攻撃を行います。 攻撃とは、相手のモンスターの体力の値を自分のモンスターの攻撃力のぶんだけ減らすことをいいます。 このことをどちらかのモンスターの体力が 0 以下になるまで続けたとき、 先に自分のモンスターの体力が 0 以下になった方の負け、そうでない方の勝ちです。
高橋君が勝つなら Yes、負けるなら No を出力してください。

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

B - Battle

提出したコード

t_hp, t_power, a_hp, a_power = gets.split.map(&:to_f)
puts (a_hp / t_power).ceil <= (t_hp / a_power).ceil ? "Yes" : "No"

結果:AC(正解) 実行時間:55 ms

考えたことを言語化してみる

A, B, C, Dだとわかりにくいので、t_hp(高橋君のモンスターの体力)、a_power(青木君のモンスターの攻撃力)という感じで変数名をつけました。

高橋君のモンスターが青木君のモンスターを倒すのにかかるターン数は、a_hp / t_powerで求められます。a_hp = 11で、t_power = 5だったとすると、必要なターン数は 3 です。11 / 5 は 2.2 ですが、単純に11 / 5をすると、答えは2になってしまいます。これは、整数の計算結果は整数になるというルールがあるからです。そのため、今回は1行目でto_i(整数へ)ではなくto_f(小数へ)を使いました。すると、11.0 / 5.0 #=> 2.2となります。ターン数という性質からして切り上げればいいので、ceil(切り上げ)をつけました。

そして(高橋君のモンスターが青木君のモンスターを倒すのにかかるターン数) <= (青木君のモンスターが高橋君のモンスターを倒すのにかかるターン数)なら "Yes" 、そうでなければ "No" という条件演算子式を作って終了。<ではなく<=とイコールがつくのは、高橋君が先攻だからです。

改善点など

他の参加者の方々のコードを見ると、whileを使っているのも多かったです。解説は上記のような考え方になっていたので、今回はこれでいいかなと思います。

感想

今回は比較的すぐに回答できました。

今度の週末は、土曜日も日曜日もContestがあるみたいです!

レートを上げるチャンスなので頑張ります。