🌟
カラオケマシン問題をやってみた
動機
Rubyのリハビリがてらにカラオケマシン問題をやってみました。
実装
lib/karaoke_machime.rb
# frozen_string_literal: true
class KaraokeMachine
KEYBOARD_PATTERN = %w[C C# D D# E F F# G G# A A# B].freeze
def initialize(melody)
@melody = melody
end
def transpose(key)
@melody.scan(/\|| |[ACDFG]#|[A-G]/).map do |pattern|
if ['|', ' '].include?(pattern)
pattern
else
KEYBOARD_PATTERN[(KEYBOARD_PATTERN.find_index(pattern) + key) % KEYBOARD_PATTERN.length]
end
end.join
end
end
spec/karaoke_machime_spec.rb
# frozen_string_literal: true
RSpec.describe KaraokeMachine do
let(:karaoke_machine) { described_class.new(melody) }
describe '#transpose' do
subject { karaoke_machine.transpose(key) }
context '|を入力した場合' do
let(:melody) { '|' }
let(:key) { 1 }
it { is_expected.to eq '|' }
end
context '半角スペースを入力した場合' do
let(:melody) { ' ' }
let(:key) { 1 }
it { is_expected.to eq ' ' }
end
context '1キーを上げる場合' do
let(:melody) { 'C#' }
let(:key) { 1 }
it { is_expected.to eq 'D' }
end
context '1キーを下げる場合' do
let(:melody) { 'D' }
let(:key) { -1 }
it { is_expected.to eq 'C#' }
end
context '1オクターブを上げる場合' do
let(:melody) { 'C#' }
let(:key) { 12 }
it { is_expected.to eq 'C#' }
end
context '1オクターブを下げる場合' do
let(:melody) { 'C#' }
let(:key) { -12 }
it { is_expected.to eq 'C#' }
end
end
end
感想
地味ですがString#scan
に対してmap
しているところが実装の工夫ポイントです。
Discussion