Open12
アルゴリズム学習

squeeze
重複した文字を一つに squeeze('-')
・・・()中の重複している箇所を1つにしてくれる
input = '---PA--I-ZA--'
puts input.squeeze('-')
#=> '-PA-I-ZA-'

sub
, gsub
文字列の置換 sub("A","B")
・・・ 1つ目の"A"という文字列を"B"に置き換える
gsub("A","B")
・・・ 全ての"A"という文字列を"B"に置き換える
S = "phpを私は学習する!php大好き!"
puts S.sub("php","ruby")
#=> rubyを私は学習する!php大好き!
puts S.gsub("php","ruby")
#=> rubyを私は学習する!ruby大好き!

times
, map
複数行の入力を配列にする # 入力
3 # n=入力が与えられる数
111
222
333
# よく書くコード
n = gets.chomp.to_i
W = []
n.times do
W << gets.chomp.to_s
end
p W
#=> ['111', '222', '333']
# かっこいいコード
n = gets.chomp.to_i
W = n.times.map { gets.chomp }
p W
#=> ['111', '222', '333']

sort
, sort_by
配列の中身を並び替え
sort
の基本
昇順、降順に並び替え
array = [300, 200, 150, 400, 100]
p array.sort
#=> [100, 150, 200, 300, 400]
p array.sort.reverse
#=> [400, 300, 200, 150, 100]
文字列も並び替え
array = ["C", "Z", "A", "E"]
p array.sort
#=> ["A", "C", "E", "Z"]
新たな配列を返り値とするので、破壊的メソッドsort!
を定義すると自分自身の配列をソートする
array = [300, 200, 150, 400, 100]
# "--- sort (非破壊メソッド) ---"
array.sort
p array
#=> [300, 200, 150, 400, 100]
# "--- sort! (破壊的メソッド) ---"
array.sort!
p array
#=> [100, 150, 200, 300, 400]
構造化データの並び替え
array = [
{"name" => "うどん", "price" => "300"},
{"name" => "パスタ", "price" => "700"},
{"name" => "ラーメン", "price" => "500"},
]
p array.sort {|x, y| x["price"] <=> y["price"] }
#=> [{"name"=>"うどん", "price"=>"300"}, {"name"=>"ラーメン", "price"=>"500"}, {"name"=>"パスタ", "price"=>"700"}]
Ruby特有の比較メソッド <=> について
self <=> otherのような条件であった場合、selfが大きい時に正、等しい時は0、小さい時に負の整数を返す。
Rubyではこの<=>メソッドを使うことにより、大小比較の条件を非常にシンプルに記述できる。
sort_by
を使用する(処理速度が速いため)
基本的にはeach文のように回してあげるイメージ
array = [300, 200, 150, 400, 100]
p array.sort_by {|value| value}
#=> [100, 150, 200, 300, 400]
回しているもののkeyを取得するイメージ
array = [
{"name" => "うどん", "price" => "300"},
{"name" => "パスタ", "price" => "700"},
{"name" => "ラーメン", "price" => "500"},
]
p array.sort_by {|x| x["price"] }
#=> [{"name"=>"うどん", "price"=>"300"}, {"name"=>"ラーメン", "price"=>"500"}, {"name"=>"パスタ", "price"=>"700"}]
3つの要素を順に多い順に並べる
array = [
{:kin=>28, :gin=>33, :dou=>59},
{:kin=>14, :gin=>18, :dou=>28},
{:kin=>28, :gin=>36, :dou=>38},
{:kin=>2, :gin=>42, :dou=>73},
{:kin=>22, :gin=>52, :dou=>81},
{:kin=>21, :gin=>58, :dou=>71},
{:kin=>23, :gin=>57, :dou=>82},
{:kin=>28, :gin=>33, :dou=>59},
{:kin=>16, :gin=>16, :dou=>19},
{:kin=>16, :gin=>47, :dou=>92}
]
# ソート処理
sorted_array = array.sort_by { |hash| [-hash[:kin], -hash[:gin], -hash[:dou]] }

gets.chomp.split.map(&:to_i)
入力 1 2 3をひとつずつ変数に代入
HWM = gets.chomp.split(' ')
H = HWM[0].to_i
W = HWM[1].to_i
M = HWM[2].to_i
1行で記述できる
H, W, M = gets.chomp.split.map(&:to_i)

0がN個ある配列を作る
seki = []
N.times do
seki << 0
end
1行で記述できる
seki = Array.new(N, 0)

each_slice
(1..10).each_slice(3) {|a| p a}
# => [1, 2, 3]
# [4, 5, 6]
# [7, 8, 9]
# [10]

rotate
配列の指定したインデックスの要素を先頭にする先頭に来るものを指定して、後ろの並びは変わらないイメージ
a = [ "a", "b", "c", "d" ]
a.rotate # => ["b", "c", "d", "a"]
# 指定しない場合rotate(1)とする
a # => ["a", "b", "c", "d"]
a.rotate(2) # => ["c", "d", "a", "b"]
a.rotate(-1) # => ["d", "a", "b", "c"]
a.rotate(-3) # => ["b", "c", "d", "a"]

reject
各要素に対してブロックを評価し、その値を抜いた要素を集めて配列に# 偶数を除外する (奇数を集める)
(1..6).reject {|i| i % 2 == 0 } # => [1, 3, 5]

size
, count
, length

transpose
二次元配列の行と列を入れ替えるp [[1,2],
[3,4],
[5,6]].transpose
# => [[1, 3, 5], [2, 4, 6]]
p [].transpose
# => []
p [1,2,3].transpose
# => -:1:in `transpose': cannot convert Fixnum into Array (TypeError)
# from -:1
p [[1,2],
[3,4,5],
[6,7]].transpose
# => -:3:in `transpose': element size differ (3 should be 2) (IndexError)

any?
, all?
, one?
, none?
各要素の条件を満たすか判定 Array#any?
配列に1つ以上、条件を満たす要素があるか調べるにはArray#any?を使う。
p [1, 2, 3].any?{|i| i % 2 == 0} #=> true
p [1, 3, 5].any?{|i| i % 2 == 0} #=> false
Array#all?
配列のすべての要素が、条件を満たしているか調べるにはArray#all?を使う。
p [1, 2, 3].all?{|i| i % 2 == 0} #=> false
p [2, 4, 6].all?{|i| i % 2 == 0} #=> true
Array#one?
配列に1つだけ、条件を満たす要素があるか調べるにはArray#one?を使う。
p [1, 2, 3].one?{|i| i % 2 == 0} #=> true
p [2, 4, 6].one?{|i| i % 2 == 0} #=> false
Array#none?
配列のすべての要素が、条件を満たしていないことを調べるにはArray#none?を使う。
p [1, 2, 3].none?{|i| i % 2 == 0} #=> false
p [1, 3, 5].none?{|i| i % 2 == 0} #=> true