2019/05/12

ひきつづき。

アウトプットのネタに困ったらこれ!?Ruby初心者向けのプログラミング問題を集めてみた(全10問) - give IT a try

カラオケマシン問題

やってみた

  • できた!と思ったらテストふたつNGだった!テストすごいな。
  • 直した。テストも通ったけど、ゴミみたいな出来だな、、泣ける。
  • 1文字ずつ見るより良い書き方ありそう。
class KaraokeMachine
  def initialize(melody)
    @code = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
    @melody = melody
  end

  def transpose(amount)
    code = @code.rotate(amount)
    ans = ''
    @melody.chars.each_with_index do |m, i|
      next if m == '#'
      if m.include?(' ') || m.include?('|')
        ans += m
      else
        ans += @melody[i + 1] == '#' ? code[@code.index(m) + 1] : code[@code.index(m)]
      end
    end
    ans
  end
end

こたえあわせ

読んでみる
  • SCALE = %w(C C# D D#[中略] A A# B).freeze
  • 定数は定数として定義する。配列の定義の仕方も忘れてた。
  • `%w: 配列を作る。式展開はされない。
  • freeze: オブジェクトを凍結する。変更不可にする。
def initialize( melody)
  @melody = melody
end
インスタンス変数
  • アクセスできるのがinitializeメソッドとインスタンスメソッドだけ。
  • initializeメソッドで初期化されて、その後各インスタンスメソッドから参照される使い方が多い。→今回のはまさにこれかな
  • 変数名の前に@を付けて定義する
クラス変数
  • そのクラスのすべてのインスタンスで共有される
  • 定数と似ているが値を変更できる
  • @@変数名で定義する

  • クラスインスタンス変数ってのもあるけど今回は無視で。わかんない。

def transepose(amount)
  converter = [SCALE, SCALE.rotate(amount)].transpose.to_h
@melody.gsub(//),converter)
  • ……簡単にしてみる。
SCALE = %w(a b c d e).freeze
=> ["a", "b", "c", "d", "e"]
 [SCALE, SCALE.rotate(3)]
=> [["a", "b", "c", "d", "e"], ["d", "e", "a", "b", "c"]]
 [SCALE, SCALE.rotate(3)].transpose
=> [["a", "d"], ["b", "e"], ["c", "a"], ["d", "b"], ["e", "c"]]
 [SCALE, SCALE.rotate(3)].transpose.to_h
=> {"a"=>"d", "b"=>"e", "c"=>"a", "d"=>"b", "e"=>"c"}
  • ふむ、理解。
  • この形になるのはわかったけど、この形にするとどう都合がいいのか?
melody='a |    b| ||c  ||d|e' #適当に
=> "a |    b| ||c  ||d|e"

melody.gsub(/[a-e]#?/,converter)
=> "d |    e| ||a  ||b|c"
  • おお!!!
  • gsubの置換方法(gsub(pattern, replacement)replacement)にはいろいろな方法が指定できる。単純な文字列、ハッシュ、ブロック。今回はハッシュを使っている。
  • ハッシュを用いた方法は、{ マッチした文字列 => 置換文字列}で指定できる。
  • ブロックを用いた方法は、文字列中の該当語を取り出してブロックを実行する。 s.gsub(/\w+/) { |word| word.capitalize }これは英単語の先頭を大文字にしている。
  • 正規表現\w+で英単語(アルファベット数字_がつながっているもの)を取り出して、capitalizeで先頭を大文字にしている。
感想
  • 正規表現を使えばA#みたいなシャープ付きをまとめて変換できたのか。
  • 変換用のハッシュを作るという発想は、自分じゃ絶対出てこなかったな。こうやって知れるのも本当にうれしいけど、普段からこういう方にレビューしてもらえたらしあわせだよなあ……。
関連記事よんだ
tap
  • tapしらなかった。最後にreturnするためだけに変数書く必要がないらしい。スマート。
配列の連結に*(splat)を使う
  • 見たことある!!!
numbers = [1, 2, 3]
numbers_new = [0] + numbers +[100]
# => [0, 1, 2, 3, 100]
  • まずそもそもこうやって配列連結できるんだ。本題はこれじゃなく、以下のように書けるってこと。
numbers = [1, 2, 3]
numbers_new = [0, *numbers, *100]
  • 変数に入れた配列をフラットに展開できるということだよね。*を入れないと展開されない。↓
  • [0, numbers, 100] # => [0, [1, 2, 3], 100]
ハッシュのキーにシンボルを使う理由
  • 簡潔に書ける(だよね)
  • 文字列よりも速い。
  • 文字列よりもメモリの使用効率がいい。

内部的にはintegerか何かでうごいてるんだっけ。あらためて使うべきと認識。

一度に全部は読み切れない
  • 一気によめる文量じゃないのでまたこんど
  • こういうのをためておくいい場所が未だに見つからない。いつもためっぱなし。

標準APIを使いこなす

標準APIを使いこなすことが重要なのであれば、いつでも標準APIを検索できる状態にしておくことが大事ですよね | mah365
  • ruby-doc.orgを繰り返し読む。
  • そうだよね…………
  • →読むのめんどくさいなら、Alfredでできるとのこと。課金するとalfred workflowなるものが使えて、それがあればローカルで確認できるらしい。
ダイアログデザイン