生成棒球音高字符串


11

目标

编写一个程序或函数,该程序或函数需要一个正整数,n并随机生成一系列合法的长度的音高(此后称为音高字符串)n

输入值

非零正整数n<= 100

输出量

返回一个随机字符串或字符列表,这些字符串或字符串表示可能的有效音调字符串length n。使用的字符将是:

  • B-球。如果您累积了其中的4个,击球手就会走动并击球。
  • S-罢工。如果您累积了其中的3个,击球手就没电了,击球完毕。
  • F-犯规。也将增加打击次数,但无法击退击球员。即,您不能让Foul成为有效字符串中的最后一个音调。超过两次罢工/犯规的任何犯规都不会增加罢工的次数(击球手此时已经有2次罢工,而第3次将使他退出)。
  • H-命中。击球手将球击中并完成击球。

(这被略微简化,但是您不必担心)

有效的音高字符串是指以三振,步行或击球结尾的字符串。

即,无效的音高字符串具有

  • 在第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 '19

该字符串最长为100个字符。犯规是允许如此长的FS
音调

哦,知道了,错过了
Quintec '19

@Quintec将其改写为更明确一些,以防万一
Veskah '19

Answers:


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)

在线尝试!


凯文(Kevin)的观点使我意识到,这种情况会随着数量的增加而分解。n=8可以F在末尾生成s 链
Veskah

2
@Veskah不错的收获。我没有考虑罢工次数(计入犯规)可能会增加到6,并S/3进行(S>2)修正来解决它。
xnor19年

4

05AB1E 44  50 44 字节

划掉&nbsp;44&nbsp;不再是44 :)

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

@xnor的Python 2答案的端口,因此,如果您喜欢此答案,请确保也对他进行投票
+6个字节(由于错误修复),此后-6个字节(再次感谢@xnor)与我的临时解决方法相比,通过移植他的方式比我的临时解决方案更有效。;)

在线尝试验证更多随机输出

说明:

[                # 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/3为来像我一样修复它X>2
xnor19年

@xnor谢谢,再次回到44字节。我知道你会发现更短的东西。; p
Kevin Cruijssen

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和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}}->->

在线尝试!

大概还是高尔夫。

取消高尔夫(轻度重新格式化)

=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. 修复了一个错误,该错误会在不正确的地方导致删除线,这要归功于@veskah(+1字节)

1
根据记录和输出,似乎没有考虑到正确增加警示数的犯规行为
Veskah

1
@veskah发现好,应该立即修复,谢谢
Sara J


1

木炭,57字节

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

在线尝试!链接是详细版本的代码。说明:

≔⁰η≔⁰ζ

从0个球和0个打击开始。

F⊖N«

循环除最后一次以外的所有交货。

≔‽⁺²‹ζ³ι

如果少于三个球,则生成一个从0到2的随机数,否则只需在0和1之间进行硬币翻转。

¿›ι¹≦⊕ζ≦⊕η

随机值2是一个球,否则会增加打击次数。

§SFB∨ι›η²»

值0到2映射为罢工,犯规和球,除了如果将发生三击,则打印犯规。(上面不包括四个球。)

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

确定是击球还是击球,然后适当选择击球或击球。


1

Perl 5,122个字节

map{$B=$S=$H=0;while($B<4&&$S<3&&!$H&&/./g){${$&}++;$S+=$&eq F&&$S<2}y///c>pos||push@a,$_}glob"{B,F,H,S}"x<>;say$a[rand@a]

在线尝试!


1
@Veskah我错过了那部分。固定它。
Xcali

1

C(海湾合作委员会)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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.