野球ピッチ文字列を生成する


11

ゴール

正の整数を取り、nlengthの正当な一連のピッチ(以下、ピッチストリングと呼ぶ)をランダムに生成するプログラムまたは関数を作成しnます。

入力

ゼロ以外の正の整数n<= 100

出力

長さの可能な有効なピッチ文字列を表すランダム文字列または文字のリストを返しnます。使用される文字は次のとおりです。

  • B-ボール。これらの4つを蓄積する場合、打者は歩き、打撃を終えた。
  • S-ストライク。これらのうち3つを蓄積すると、打者は出てバッティングを終了します。
  • F-ファウル。また、ストライク数を増やしますが、打者を出すことはできません。つまり、有効な文字列の最後のピッチをファウルにすることはできません。2回のストライク/ファウルを過ぎたファウルは、ストライクカウントを増加させません(打者はその時点ですでに2回のストライクをしており、3回目は彼を追い出します)。
  • H-ヒット。バッターはボールをインプレーに打ち込み、バッティングを終了しました。

(これは少し簡略化されていますが、心配する必要はありません)

有効なピッチ文字列は、ストライクアウト、ウォーク、またはヒットで終わるものです。

つまり、無効なピッチ文字列には次のいずれかがあります

  • 4番目のボール、3番目のストライク、またはヒット後の追加のピッチ
  • 4番目のボール、3番目のストライク、またはヒットを生成する前に終了しました。

ルール

  • プログラムは、指定された入力に対してすべての可能な結果を​​生成できる必要があります。
  • プログラムは一様にランダムである必要はありませんが、前の規則に従う必要があります。
  • これはです。

Input => Possible Outputs
1 => [H] #Can only end with a hit
2 => [S,H], [B,H], [F,H] #Can only end with a hit
3 => [S,S,S], [F,F,S], [B,B,H], ... #Can now strike-out, otherwise must end with a hit
4 => [B,B,B,B], [S,B,S,S], [B,F,S,S], [B,B,B,H], ... #Can now be walked, struck-out, or get a hit
6 => [S,B,S,B,B,H], [F,F,F,F,F,S], ... #Can now have a full-count (3 balls, 2 strikes) before finishing 

Input => Invalid Outputs
1 => [S], [B]    #Not enough for a strike-out/walk
2 => [S,S]       #Not enough for a strike-out/walk
2 => [H,H]       #Batter has already scored a hit
3 => [S,S,F]     #Fouls will not cause a strike-out
4 => [S,S,S,H]   #Batter has already struck out
5 => [B,B,B,B,B] #Batter has already walked

1
それで、1から無限大のFのどこでも生成できなければなりませんか?
Quintec

文字列の長さは最大100文字です。ファウルは、このような長いピッチングストリングを可能にするものです。たとえば、99 F秒やa Sはストライクアウトです
ヴェスカー

ああ、わかった、それを見逃した
Quintec

@Quintecは、念のためもう少し明確になるように書き直した
ベスカ

回答:


4

Python 2、128バイト

from random import*
def g(n):
 x=i=S=0;r=''
 while(S>2)+x<3>=i-S:x=randint(0,3);r+='BFSH'[x];S+=x>0;i+=1
 return(i==n)*r or g(n)

オンラインでお試しください!

バッターが完了するまでピッチ文字列をランダムに生成し、正しい長さになったら出力し、そうでなければ最初からやり直します。


Python 2、136バイト

from random import*
def g(n):
 B=H=F=S=0;r=''
 while(F+S<3or'S'>x)>B/4+H:x=choice('BHFS');r+=x;exec x+"+=1"
 return(len(r)==n)*r or g(n)

オンラインでお試しください!


これをケビンが移植したことで、これが数字が大きくなると壊れることに気付きました。最後n=8Fsのチェーンを生成できます
ヴェスカー

2
@Veskahナイスキャッチ。ストライクカウント(ファウルのカウント)を6まで増やしS/3(S>2)修正するように変更したことは考慮していませんでした。
xnor

4

05AB1E 44  50 44 バイト

取り消し線&nbsp;44&nbsp;は44ではありません:)

[õ0U.µ["BFSH"3ÝΩ©è«®ĀX+U¼X2›®+3@¾X-3›~#}I¾Q#

@xnorのPython 2回答のポートです。この回答が気に入ったら、必ず彼も賛成してください!
バグ修正のため+6バイト、その後@xnorのおかげで、予想どおり一時的な回避策と比較してより効率的な修正を移植して、再び-6バイトになりました。;)

オンラインそれを試してみてくださいまたはいくつかのより多くのランダムな出力を確認します

説明:

[                # Start an infinite loop:
 õ               #  (Re)set the result-string to an empty string ""
 0U              #  (Re)set variable `X` to 0
               #  Reset the counter_variable to 0
   [             #  Start an inner infinite loop:
    "BFSH"       #   Push string "BFSH"
          3ÝΩ    #   Push a random integer in the range [0,3]
             ©   #   Store this random integer in variable `r` (without popping)
              è  #   Index it into the string "BFSH"
               « #   Append it to the result-string
    ®Ā           #   If `r` is NOT 0:
      X+U        #    Increase `X` by 1
    ¼            #   Increase the counter_variable by 1
    X2›®+        #   Calculate `X`>2 (1 if truthy; 0 if falsey) + `r`
         3@      #   Check if this is larger than or equal to 3
    ¾X-          #   Calculate counter_variable - `X`
       3        #   Check if this is larger than 3
    ~            #   If either of the two checks above is truhy:
     #           #    Stop the inner infinite loop
   }             #  After the inner infinite loop:
    I¾Q          #  If the input and counter_variable are equal:
       #         #   Stop the outer infinite loop
                 # (and output the result-string at the top of the stack implicitly)

1
@Veskah今のところ、簡単な修正を行いました。私はxnorがより短い修正を行うことができると感じているので、おそらくいくつかのバイトを節約するために彼の修正を移植するでしょう。:)
ケビンクルーイッセン

1
私は変更することで行ったようにあなたはそれを修正することができますX/3X>2
xnor

@xnorありがとう、44バイトに戻りました。もっと短いものが見つかると思いました。; p
ケビンクルーッセン

3

R、148バイト

function(n){`~`=paste0
`*`=sample
o=""
while(nchar(o)<n-1){a=c("B"[T<4],"F","S"[F<2])*1
F=F+(a>"E")
T=T+(a<"F")
o=o~a}
o~c("B"[T>3],"H","S"[F>1])*1}

オンラインでお試しください!

結果が可能なピッチシーケンスであることを保証するために、サンプリングデータセットに条件付きで含めることを使用して、文字列を生成します。

xnorのpythonの回答のように)拒否のサンプリングを行う方が短いでしょう

function(n){`~`=paste0		# alias
`*`=sample			# alias
o=""				# empty string for output
while(nchar(o)<n-1){		# do n-1 times:
a=c("B"[T<4],"F","S"[F<2])*1	# sample 1 from the string "BFS", conditionally including B or S if the ball/strike count is 3/2	
F=F+(a>"E")			# increment F (strike count) if sampled character is F or S
T=T+(a<"F")			# increment T (ball count) if sampled character is B
o=o~a}				# append a to output

o~c("B"[T>3],"H","S"[F>1])*1}	# append the sampled "BHS", conditionally including B or S if the ball/strike count is 3/2.

これらの文字のいずれかを入力するたびに頭で遊んでいたランダムな「F and S」参照 ...



2

Pyth、53バイト

u+GO?H+W<K/G\B3+W<Jl@"SF"G2\F\S\B+WqK3+WgJ2\H\S\B_UQ[

こちらからオンラインでお試しください。

これは長すぎると感じています。別のアプローチが必要かもしれません。

u+GO?H+W<K/G\B3+W<Jl@"SF"G2\F\S\B+WqK3+WgJ2\H\S\B_UQ[   Implicit: Q=eval(input())
                                                 _UQ    Reversed range from Q-1 to 0
u                                                   [   Reduce the above, with initial value G=[], next value as H:
                    @"SF"G                                Keep elements of G which are in "SF"
                   l                                      Length of the above
                  J                                       Store in J - this is the number of strikes and fouls so far
          /G\B                                            Count number of "B"s in G
         K                                                Store in K - this is the number of balls so far
    ?H                                                    If H is not 0 (i.e. not final pitch):
                           \F                               Start with "F" (foul is always available in non-final pitch)
                W<J       2                                 If J<2...
               +             \S                             ... append "S"
       W<K    3                                             If K<3...
      +                        \B                           ... append "B"
                                                          Else:
                                           \H               Start with "H" (hit is always available in final pitch)
                                       WgJ2                 If J >= 2...
                                      +      \S             ... append "S"
                                  WqK3                      If K == 3...
                                 +             \B           ... append "B"
   O                                                      Choose one element at random from the available options
 +G                                                       Append the above to G
                                                        Implicit print the result of the reduce operation

2

JavaScript(ES6)、 107 106  99バイト

f=(n,k=p=s=0,o='')=>p&&p>2|k-s>3|s>2&p<2?k-n?f(n):o:f(n,k+1,o+'FSBH'[p=Math.random()*4|0,s+=p<2,p])

オンラインでお試しください!

コメント済み

f = (                       // f = recursive function taking:
  n,                        //   n = requested length
  k =                       //   k = pitch counter, initialized to 0
  p =                       //   p = last pitch
  s = 0,                    //   s = sum of strikes and fouls
  o = ''                    //   o = output string
) =>                        //
  p &&                      // if the last pitch was not a foul
  p > 2 |                   // AND the last pitch was a hit
  k - s > 3 |               //     OR we have 4 balls (or 3 balls + 1 hit)
  s > 2 & p < 2 ?           //     OR more than 2 strikes or fouls, ending with a strike:
    k - n ?                 //   if k is not equal to n:
      f(n)                  //     valid series but bad timing: try again from scratch
    :                       //   else:
      o                     //     success: return o
  :                         // else:
    f(                      //   do a recursive call:
      n,                    //     n is unchanged
      k + 1,                //     increment k
      o + 'FSBH'            //     append the pitch letter to o
        [ p = Math.random() //     pick a new random pitch
              * 4 | 0,      //     in [0..3]
          s += p < 2,       //     increment s if the pitch is a foul or a strike
          p ]               //     actual index in 'FSBH'
    )                       //   end of recursive call

2

インク120の 119 116 117バイト

=f(n)
->g(n,3,2)
=g(n,b,s)
~n--
{n:{~{b:b->g(n,b-1,s)}|{s:s->g(n,b,s-1)}|}f->g(n,b,s-(s>0))|{~{b:h|b}|{s:h|s}|h}}->->

オンラインでお試しください!

おそらくまだゴルフ可能です。

Ungolfed(穏やかに再フォーマット)

=f(length) // Define a stitch f, with one parameter which specifies the length of the created string. This is the intended entry point.
->g(length,3,2) // Instantly divert to g, defined below, with some extra parameters

=g(length,balls_left,strikes_left) // Define a stitch g, with three parameters.
~ length--                         // Decrement remaining length
{
    - length: // If this is not to be the last character in the string
              // randomly do one of the following:
              // 1. If balls_left is nonzero, print a b and recurse
              // 2. If strikes_left is nonzero, print an s and recurse
              // 3. Do nothing
              // If we did not divert earlier, print an f and recurse.
        {~{balls_left:b->g(length,balls_left-1,strikes_left)}|{strikes_left:s->g(length,balls_left,strikes_left-1)}|}f->g(length,balls_left,strikes_left-(strikes_left>0)) 
    - else: // Randomly do one of the following
            // 1. If a ball would result in a walk, print a b, otherwise an h.
            // 2. If a strike would result in a strikeout, print an s, otherwise an h.
            // 3. Just print an h.
            // And finally, halt.
        {~{balls_left:h|b}|{strikes_left:h|s}|h}}->->

編集

  1. ->->代わりにで終了してバイトを保存しました->END
  2. n前にデクリメントして3バイトを節約しました。
  3. @veskahによる発見(+1バイト)のおかげで、間違った場所でストライクアウトを引き起こすバグを修正しました。

1
評価と出力に基づいて、ストライクカウントが正しく増加するファウルを考慮していないように見えます
ベスカ

1
@veskahよく発見されました。今すぐ修正する必要があります。ありがとうございます
サラJ


1

、57バイト

≔⁰η≔⁰ζF⊖N«≔‽⁺²‹ζ³ι¿›ι¹≦⊕ζ≦⊕η§SFB∨ι›η²»⊞υHF›η¹⊞υSF›ζ²⊞υB‽υ

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

≔⁰η≔⁰ζ

0ボールと0ストライクから始めます。

F⊖N«

最後を除くすべての配信をループします。

≔‽⁺²‹ζ³ι

ボールが3個より少ない場合は、0から2の乱数を生成します。そうでない場合は、0から1の間でコインフリップします。

¿›ι¹≦⊕ζ≦⊕η

ランダムな値2はボールです。それ以外の場合、ストライクカウントが増加します。

§SFB∨ι›η²»

0〜2の値は、ストライク、ファウル、ボールにマップされますが、ストライクが3回ある場合は、ファウルが代わりに印刷されます。(上記の4つのボールは除外されています。)

⊞υHF›η¹⊞υSF›ζ²⊞υB‽υ

ストライクまたはボールが打者を追い出すかどうかを決定し、それらから適切にヒットするかを選択します。



1

C(GCC)164の 145 142バイト

-3バイトのceilingcat

#define A(a)!i&&!r--?puts(#a),++a,--n:0;
b,s,f,h,i,r;p(n){srand(time(0));for(i=n;i--;){for(n=1;n;){r=rand()&3;b>2^!A(b)s+f>1^!A(s)!A(f)A(h)}}}

オンラインで試す


提案する&n代わりにtime(0)
ceilingcat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.