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 3 years have passed since last update.

Rubyでカラオケマシン問題のコードを書いてみた

Posted at

##はじめに
この記事は以下のサイトにあった問題を解いてみたものです。Rubyのアウトプットを目的として作成しました。
[アウトプットのネタに困ったらこれ!?Ruby初心者向けのプログラミング問題を集めてみた(全10問)]
(https://blog.jnito.com/entry/2019/05/03/121235)

##問題

CodeIQに「カラオケマシン問題」を出題しました。みんなチャレンジしてね!より引用。

みなさんには、「かえるのうた」を自由自在にキーチェンジするプログラムを作成してもらいます。

かえるのうたのメロディは以下のような文字列で表現されます。

"C D E F |E D C |E F G A |G F E |C C |C C |CCDDEEFF|E D C "

縦棒( | )は小節の区切りです。
半角スペースは休符です。
音符と休符が8つ集まると1小節になります。

このメロディ(文字列)を変更するKaraokeMachineというクラスを作ります。
このクラスはインスタンス作成時にメロディを受け取ります。
transposeというメソッドに変化させたいキーの量を渡すと、その分だけキーを上げたり下げたりしたメロディが返却されます。

コード

class KaraokeMachine
  def initialize(melody)
    @melody = melody
  end
  def transpose(amount)
    melody_line = %w(C C# D D# E F F# G G# A A# B)
    changed_melody = ""
    calc_amount = amount % -12  

    @melody.each_char do |m|
      if m =~ / |\|/            
        changed_melody = changed_melody + m
      else                      
        new_key = melody_line.index(m) + calc_amount
        changed_melody = changed_melody + melody_line[new_key] 
      end
    end
    return changed_melody
  end
end
melody = "C D E F |E D C   |E F G A |G F E   |C   C   |C   C   |CCDDEEFF|E D C   "
karaoke = KaraokeMachine.new(melody)

方針

音階は全部で12種類あります。そこで、音の配列を用意してやり、1音ずつ変換させていけば、目的が達成できそうです。変換については、当初12で割ったあまりを利用する予定でしたが、問題が発生したので-12で割ったあまりを利用することで問題を解決しました。

##解説
まずは音階を用意します。

melody_line = %w(C C# D D# E F F# G G# A A# B)

例えばドの音はCと表されますが、Cはこの配列のインデックスの0にあたります。
音を変換する際に、インデックスの値を利用するためにそれぞれの音に対して
indexメソッドを利用しました。
今回用意した配列のインデックスは-11~11の値を取りうることができます。当初は12で割った余をindexメソッドを使った後の値に足していたのですが、これだと用意した配列のインデックスの取りうる値の範囲から逸脱することがある問題が発生しました。そこで-12で割った余を利用することでこの問題を回避しています。

あとは、melodyに出てくる音以外の文字列の処理です。
これには" "と"|"が含まれます。これらはそのまま表示させたいので、

  m =~ / |\|/ #" "または"|"にマッチする正規表現

が含まれる際はそのままとしました。

##参考にしたサイト
Array#find_index (Ruby 3.0.0 リファレンスマニュアル)
String#each_char (Ruby 3.0.0 リファレンスマニュアル)

0
0
0

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?