https://qiita.com/Nabetani/items/ebd8a56b41711ba459f9
連続する入力(種類はストライク・ボール・ファウル・ヒット・ピッチャーフライ)が与えられたとき、ボールカウント・アウトカウントの遷移を出力する問題です。
Ruby
module BallCount
def self.solve(input)
out = strike = ball = 0
sb_zero = ->{ strike = ball = 0 }
input.each_char.map {|c|
case c
when "s"
strike += 1
if strike == 3
sb_zero.()
out += 1
end
when "b"
ball += 1
sb_zero.() if ball == 4
when "h"
sb_zero.()
when "p"
out += 1
sb_zero.()
when "f"
strike += 1 if strike <= 1
end
out = strike = ball = 0 if out == 3
"#{out}#{strike}#{ball}"
}.join(",")
end
end
if __FILE__ == $0
require 'minitest/autorun'
describe 'BallCount' do
[
["s", "010"],
["sss", "010,020,100"],
["bbbb", "001,002,003,000"],
["ssbbbb", "010,020,021,022,023,000"],
["hsbhfhbh", "000,010,011,000,010,000,001,000"],
["psbpfpbp", "100,110,111,200,210,000,001,100"],
["ppp", "100,200,000"],
["ffffs", "010,020,020,020,100"],
["ssspfffs", "010,020,100,200,210,220,220,000"],
["bbbsfbppp", "001,002,003,013,023,000,100,200,000"],
["sssbbbbsbhsbppp", "010,020,100,101,102,103,100,110,111,100,110,111,200,000,100"],
["ssffpffssp", "010,020,020,020,100,110,120,200,210,000"]
].each do |input, expect|
it input do
assert_equal BallCount.solve(input), expect
end
end
end
end
一文字の入力c
に出力"#{out}#{strike}#{ball}"
ひとつが対応する、つまりは写像(map)なので、素直にEnumerable#map
を使っています。対応にはこれも素直に case ~ when を使います。
それから、ストライクとボールを共に 0 にする操作は頻出するので、あらかじめクロージャとして lambda 関数(sb_zero
)を定義しておいてあります。