AtCoderをやって10

問題1

高橋君は胃が強いので、賞味期限を X 日まで過ぎた食品を食べてもお腹を壊しません。 賞味期限を X+1 日以上過ぎた食品を食べると、お腹を壊します。

また、賞味期限を過ぎずに食べると、おいしく感じます。そうでない場合、おいしく感じません。

高橋君は、賞味期限の A 日前に食品を買ってきて、買ってから B 日後に食べました。

高橋君が食品をおいしく感じた場合 delicious を、おいしくは感じなかったがお腹は壊さなかった場合 safe を、お腹を壊した場合 dangerous を出力するプログラムを作成してください。

自分の回答

x, a, b = gets.split.map(&:to_i)
eat_day = ( 0 - a ) + b
if eat_day <= 0
  puts "delicious"
elsif 0 < eat_day && eat_day <= x
  puts "safe"
else
  puts "dangerous"
end

その他の回答

賞味期限を0とか設けないでも良かったやつですね

X,A,B = gets.chomp.split(' ').map(&:to_i)
 
if B <= A
  puts 'delicious'
elsif B <= A + X
  puts 'safe'
else
  puts 'dangerous'
end

問題2

直角三角形 ABC があります。∠ABC=90° です。

三角形 ABC の三辺の長さである ∣AB∣,∣BC∣,∣CA∣ が与えられるので、直角三角形 ABC の面積を求めて下さい。

ただし、三角形 ABC の面積は整数となることが保証されています。

atcoder.jp

自分の回答

これは簡単でした。

ab, bc, ca = gets.split.map(&:to_i)
puts (ab * bc) / 2

問題3(Collats Problem)

問題文が複雑だったので下記参照下さい

atcoder.jp

自分の回答(他の方回答参照)

問題文を理解するのに時間がかかりました。 要するに与えられた数字(n)が偶数ならn/2、奇数なら3n+1をしていき、数字が重複した段階の配列のlengthを出力すれば良いのですね。 if文の処理を繰り返す訳ですが、while文で配列aの要素が重複したらuniqメソッドで重複している要素を取り除きます。 uniqメソッドを使用した配列aと何もメソッドを使っていない配列aが同じ間はifの処理を繰り返すようにします。

要素が重複したらこの条件から外れるので処理が終わります。

n = gets.to_i
a = [n]
while a.uniq == a
  if n % 2 == 0
    n = n / 2
    a << n
  else
    n = 3 * n + 1
    a << n
  end
end
puts a.length

他の回答

untilで条件がtrueになるまで繰り返すパターン。難しい。。。

s = gets.to_i
nums = {}
answer = 1

until nums[s]
  nums[s] = true
  s = s.even? ? (s / 2) : (3 * s + 1)
  answer += 1
end

puts answer