はじめに
僕は数年前、競プロをかじっていました。一応水色までは行きましたが、それ以降はあまり振るわず、現在はほとんどやることがなくなってしまっています。
僕は水色になるまでほとんどの問題をRubyで解いていました。
その時に使っていたライブラリが誰かの役にたつかもと思ったので、この記事でそのライブラリの解説を行って使っていたライブラリの供養をしようと思います。
昔解いていた問題は https://github.com/getty104/AtCoder に残しています。コードを見た方が使い方のイメージがつきやすいかもしれません。
ライブラリ一覧
はじめに使っていたスニペットをそのまま貼っておきます。これらのライブラリの使い方や使うシーンについて説明していきます
require 'prime'
require 'set'
require 'tsort'
include Math
ALP = ('a'..'z').to_a
INF = 0xffffffffffffffff
def max(a,b); a > b ? a : b end
def min(a,b); a < b ? a : b end
def gif; gets.to_i end
def gff; gets.to_f end
def gsf; gets.chomp end
def gi; gets.split.map(&:to_i) end
def gf; gets.split.map(&:to_f) end
def gs; gets.chomp.split.map(&:to_s) end
def gc; gets.chomp.split('') end
def pr(num); num.prime_division end
def pr?(num); Prime.prime?(num) end
def digit(num); num.to_s.length end
def array(s,ini=nil); Array.new(s){ini} end
def darray(s1,s2,ini=nil); Array.new(s1){Array.new(s2){ini}} end
def rep(num); num.times{|i|yield(i)} end
def repl(st,en,n=1); st.step(en,n){|i|yield(i)} end
入出力系
競プロでは標準入力で問題のデータを受け取ると思います。問題の入力形式はだいたいパターンが決まっているので、シュッと実装できるようにいくつか関数を用意していました。それらについて解説していきます
gif
gif
は、入力を1つの整数として受け取る関数です。
入力の形式が1つの整数だった場合に使えます。
利用例
N
n = gif
gff
gff
は`gifのFloat版です。入力をFloatとして扱いたい時に使います
R
r = gff
gsf
gsf
は、入力を1つの文字列として受け取りたい時に使う関数です。この関数は受け取った文字列をクエリとして扱う場合によく使います。
受け取る文字列を操作する場合は後述するgc
を使います。
S
s = gsf
gi
gi
が一行で複数の整数を受け取る時に使う関数です。一番よく使う関数な気がします。
A B
a, b = gi
N1 N2 ... Nk
n = gi
gf
gi
のFloat版です。一行で複数の値をFloatとして受け取りたい時に使います。
r1 r2
r1, r2 = gf
gs
gi
のString版です。一行で複数の値をStringとして受け取りたい時に使います。
S1 S2
s1, s2 = gs
gc
文字列を配列として受け取りたい時(Charのような感じ)に使える関数です。
C
c = gc
その他
入出力以外でも、記述を減らすために用意していた関数が色々あったので紹介していきます。
max, min
rubyでは 配列のメソッドとしてmax
、min
があるのですが、AtCoderでは2値の比較をよく行うので、min
,max
というメソッドを用意していました。
digit
digit
は数字の桁数を取得できる関数です。
digit(100) # => 3
pr
pr
は与えた値を素因数分解してくれる関数です。Rubyの標準モジュールのprime
にあるInteger#prime_division
のエイリアスです。
pr(100) #=> [[2, 2], [5, 2]]
pr?
pr?
は与えた値の素数判定をしてくれる関数です。
pr?(2) #=> true
array, darray
競プロをやっていると初期値を設定した配列を用意する必要があるときがあると思います。
array
、darray
はそういう時に使える関数です。array
は一次元配列、darray
は二次元配列を用意したい時に使えます。
dp = darray(100, 100, INF)
rep, repl
rep
, repl
は競プロをやっているとおなじみの関数のような気がします。
これはfor文を簡潔に書けるようにした関数です。
rep 10000 do |i|
# 何かしらの処理
end
repl 1, 10 do |i|
# 何かしらの処理
end
INF, ALP
INF
は無限大の値のエイリアスです。初期値で使うことが多いです。
ALP
はアルファベットの配列です。たまに使います。
まとめ
Rubyで競プロをやるのはパフォーマンス的な部分やライブラリ的な部分で不利なところも多いですが、もしRubyで競プロをやる機会があれば参考にしてもらえれば幸いです。