AtCoder に登録したら解くべき精選過去問 10 問を Ruby で解いてみた (しえる版)


Swift/C版のベースとなる実装的に思っていただければ幸いです。特殊な説明以外はSwiftに回します。
あと、私家版なのでところどころ初心者向けでない部分ありますがご了承ください(本家実装リンクにあるRubyはわかりやすい実装です)

実装リンク集 https://qiita.com/drken/items/6edb1c0542d4c3b7179c
問題一覧 https://abs.contest.atcoder.jp/assignments

|私の実装|記事|
|:--|:--|
|Ruby (私家版)|https://qiita.com/cielavenir/items/c0a45b6b87c411b60b93|
|Swift|https://qiita.com/cielavenir/items/b90a94dce60a620fa2dc|
|C|https://qiita.com/cielavenir/items/ee1e47b844d05dcfc66e|
|VB.Net|https://qiita.com/cielavenir/items/7ddf5e9bac02daf72159|
|Pascal|https://qiita.com/cielavenir/items/530270ac4affca435442|
|Perl|https://qiita.com/cielavenir/items/4d16ba1be4ad6847a914|
|MoonScript/Lua|https://qiita.com/cielavenir/items/6553531e230f39cd6a3d|

# 解答

## 例題 PracticeA

https://practice.contest.atcoder.jp/tasks/practice_1

```rb:0.rb
#!/usr/bin/ruby
a=gets.to_i
b,c=gets.split.map &:to_i
d=gets.chomp
puts '%d %s'%[a+b+c,d]
```

### 別解

ddは`$<.read`と同じ意味で、全読みです。1行ずつ読むのが面倒かつまとめて読んで大丈夫な場合は使うことがあります。

```rb:0_1.rb
#!/usr/bin/ruby
a,b,c,d=`dd`.split
puts '%d %s'%[a.to_i+b.to_i+c.to_i,d]
```

## 第１問 ABC086A Product

https://abc086.contest.atcoder.jp/tasks/abc086_a

```rb:1.rb
#!/usr/bin/ruby
a,b=gets.split.map &:to_i
puts a*b%2>0?"Odd":"Even"
```

## 第２問 ABC081A Placing Marbles

https://abc081.contest.atcoder.jp/tasks/abc081_a

数値出力はpでok.

```rb:2.rb
#!/usr/bin/ruby
p gets.count('1')
```

### 別解

全読みして、0の文字コード*3と改行の文字コードの和を引く。

```rb:2.rb
#!/usr/bin/ruby
p`dd`.sum-154
```

## 第３問 ABC081B Shift only

https://abc081.contest.atcoder.jp/tasks/abc081_b

2進文字列にして、サイズから「1の逆インデックス-1」を引く。`~n`は`-n-1`と同義です。

また、

```
`sed 1d`
```

で`gets;ARGF.read`と同じ効果を得られます。

```rb:3.rb
#!/usr/bin/ruby
p`sed 1d`.split.map{|e|s='%b'%e;s.size+~s.rindex(?1)}.min
```

## 第４問 ABC087B Coins

https://abc087.contest.atcoder.jp/tasks/abc087_b

```rb:4.rb
#!/usr/bin/ruby
r=0
a,b,c,x=$<.map &:to_i
(0..x/500).each{|i|(0..(x-500*i)/100).each{|j|
	k=x-500*i-100*j
	r+=1 if k%50==0&&c>=k/50&&a>=i&&b>=j
}}
p r
```

## 第５問 ABC083B Some Sums

https://abc083.contest.atcoder.jp/tasks/abc083_b

10で順番に割らなくても、文字列を数字の配列にすればいいですよね

```rb:5.rb
#!/usr/bin/ruby
n,a,b=gets.split.map &:to_i
p (1..n).select{|i|k=i.to_s.bytes.map{|b|b-48}.reduce(:+);a<=k&&k<=b}.reduce(:+)
```

## 第６問 ABC088B Card Game for Two

https://abc088.contest.atcoder.jp/tasks/abc088_b

```rb:6.rb
#!/usr/bin/ruby
a=`sed 1d`.split.map(&:to_i).sort_by(&:-@)
r=0
a.each_with_index{|e,i|r+=e*(-1)**i}
p r
```

## 第７問 ABC085B Kagami Mochi

https://abc085.contest.atcoder.jp/tasks/abc085_b

```rb:7.rb
#!/usr/bin/ruby
gets;p$<.to_a.uniq.size
```

## 第８問 ABC085C Otoshidama

https://abc085.contest.atcoder.jp/tasks/abc085_c

```rb:8.rb
#!/usr/bin/ruby
n,y=gets.split.map &:to_i
(0..n).each{|i|(0..n-i).each{|j|
	k=n-i-j
	if i*1000+j*5000+k*10000==y
		puts [k,j,i]*' '
		exit
	end
}}
puts '-1 -1 -1'
```

## 第９問 ABC049C Daydream

https://abc049.contest.atcoder.jp/tasks/arc065_a

```rb:9.rb
#!/usr/bin/ruby
T=%w(dream dreamer erase eraser).map(&:reverse)
s=gets.chomp.reverse
c=0
while c<s.size
	k=T.find{|e|s[c,e.size]==e}
	if !k
		puts :NO
		exit
	end
	c+=k.size
end
puts :YES
```

## 第10問 ABC086C Traveling

https://abc086.contest.atcoder.jp/tasks/arc089_a

```rb:10.rb
#!/usr/bin/ruby
gets;puts ([[0,0,0]]+$<.map{|e|e.split.map &:to_i}).each_cons(2).all?{|e,f|
	t=f[0]-e[0];x=f[1]-e[1];y=f[2]-e[2]
	x+y<=t && (t-x-y)%2<1
} ? :Yes : :No
```