GenerateメソッドがC#っぽいところかな。
Program.cs
using System;
using System.Collections.Generic;
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Calculate("s"));
        Console.WriteLine(Calculate("sss"));
        Console.WriteLine(Calculate("bbbb"));
        Console.WriteLine(Calculate("ssbbbb"));
        Console.WriteLine(Calculate("hsbhfhbh"));
        Console.WriteLine(Calculate("psbpfpbp"));
        Console.WriteLine(Calculate("ppp"));
        Console.WriteLine(Calculate("ffffs"));
        Console.WriteLine(Calculate("ssspfffs"));
        Console.WriteLine(Calculate("bbbsfbppp"));
        Console.WriteLine(Calculate("sssbbbbsbhsbppp"));
        Console.WriteLine(Calculate("ssffpffssp"));
    }
    static string Calculate(string input)
    {
        return string.Join(",", Count.Generate(input));
    }
}
struct Count
{
    public int Outs;
    public int Strikes;
    public int Balls;
    public void Take(char action)
    {
        switch (action)
        {
            case 's':
                this.IncreaseStrikes();
                break;
            case 'f':
                if (this.Strikes < 2) this.IncreaseStrikes();
                break;
            case 'b':
                this.IncreaseBalls();
                break;
            case 'h':
                this.Advance();
                break;
            case 'p':
                this.IncreaseOuts();
                break;
            default:
                break;
        }
    }
    private void IncreaseStrikes()
    {
        this.Strikes++;
        if (this.Strikes == 3) this.IncreaseOuts();
    }
    private void IncreaseOuts()
    {
        this.Strikes = 0;
        this.Balls = 0;
        this.Outs++;
        if (this.Outs == 3) this.Outs = 0;
    }
    private void IncreaseBalls()
    {
        this.Balls++;
        if (this.Balls == 4) this.Advance();
    }
    private void Advance()
    {
        this.Strikes = 0;
        this.Balls = 0;
    }
    public override string ToString()
    {
        return string.Concat(this.Outs, this.Strikes, this.Balls);
    }
    public static IEnumerable<Count> Generate(string input)
    {
        var current = new Count();
        foreach (var action in input)
        {
            current.Take(action);
            yield return current;
        }
    }
}