LoginSignup
1
0

More than 3 years have passed since last update.

野球のボールカウント(どう書く)

Last updated at Posted at 2020-12-14

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)を定義しておいてあります。

1
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
1
0