0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

RubyでAtCoder ABC299(A, B, C)を解いてみた

Last updated at Posted at 2023-04-23

はじめに

Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC299のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

A - Treasure Chest

a-299.rb
gets
s = gets.chomp.chars
l = s.index("|")
r = s.rindex("|")
mid = s.index("*")
puts l < mid && mid < r ? "in" : "out"

<追記>
コメントでいただいた別解になります。

別解
gets
str = gets.chomp

puts /\|(.*)\|/.match(str)[1].include?("*") ? "in" : "out"

解説

|は2回しか出現しないことを利用して、indexメソッドとrindexメソッドを使うことで右側と左側それぞれの|の位置を取得することができます。後は、*の位置が取得した|の間にあればin、なければoutを出力します。

B - Trick Taking

b-299.rb
n, t = gets.split.map(&:to_i)
c = gets.split.map(&:to_i)
r = gets.split.map(&:to_i)

if c.include?(t)
    array = []
    c.each_with_index do |factor, index|
        next if factor != t
        array << index
    end

    val = 0
    array.each do |index|
        val = [val, r[index]].max
    end
    puts r.index(val) + 1
else
    array = []
    c.each_with_index do |factor, index|
        next if factor != c[0]
        array << index
    end

    val = 0
    array.each do |index|
        val = [val, r[index]].max
    end
    puts r.index(val) + 1
end

<追記>
コメントでいただいた別解になります。

別解
Card = Struct.new(:player, :color, :value)

n, t = gets.split.map(&:to_i)
cs = gets.split.map(&:to_i)
rs = gets.split.map(&:to_i)

cards = (1..n).zip(cs, rs).map { |i, c, v| Card.new(i, c, v) }
find_player = ->(color) {
  cards.select { _1.color == color }.max_by(&:value).player
}
puts cs.include?(t) ? find_player.(t) : find_player.(cs[0])

解説

cにtが含まれているかどうかにより場合分けします。valとして最大となる値を順次更新しておき最後に出力することで実装することができます。

C - Dango

c-299.rb
# 修正前
gets
s = gets.chomp
if s.include?("-") && s.include?("o")
    s = s.split("-")
    puts s.max.size
else
    puts -1
end
c-299.rb
# 修正後(コメントありがとうございます!)
n, t = gets.split.map(&:to_i)
c = gets.split.map(&:to_i)
r = gets.split.map(&:to_i)

define_method(:find_player) do |color|
    array = []
    c.each_with_index do |factor, index|
        next if factor != color
        array << index
    end

    val = 0
    array.each do |index|
        val = [val, r[index]].max
    end
    r.index(val) + 1
end

puts c.include?(t) ? find_player(t) : find_player(c[0])

<追記>
コメントでいただいた別解になります。

別解
n = gets.to_i
str = gets.chomp

bou = (0...n).select { str[_1] == "-" }
search = ->(bou) {
  return -1 if bou.size < 1
  ary = ([-1] + bou).each_cons(2).map { _2 - _1 }.select { _1 >= 2 }
  ary.max&.pred || -1
}
tmp1 = search.(bou)
tmp2 = search.(bou.map { n - _1 - 1 }.reverse)
puts [tmp1, tmp2].max

解説

sが-oを含んでいるかどうかで場合分けをします。含んでいれば連結しているoの最大の大きさを出力し、含んでいなければ-1を出力します。

0
0
3

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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?