Générer une chaîne de pitch de baseball

11

Objectif

Écrivez un programme ou une fonction qui prend un entier positif net génère aléatoirement une série légale de pas (désormais appelée chaîne de pas) de longueur n.

Contribution

Un entier positif non nul n<= 100

Production

Renvoie une chaîne aléatoire ou une liste de caractères qui représentent une chaîne de longueur de pas valide et possible n. Les caractères utilisés seront:

  • B - Balle. Si vous en accumulez 4, le frappeur est promené et a terminé le bâton.
  • S - Strike. Si vous en accumulez 3, le frappeur est retiré et a terminé le bâton.
  • F - Faute. Augmentera également le nombre de frappes mais ne pourra pas retirer le frappeur. C'est à dire, vous ne pouvez pas avoir un Foul être le dernier pitch d'une chaîne valide. Toute faute au-delà de deux frappes / fautes n'augmentera pas le nombre de frappes (le frappeur a déjà 2 frappes à ce moment-là et une troisième le ferait sortir).
  • H - Frappé. Le frappeur a frappé une balle en jeu et a terminé le bâton.

(Ceci est légèrement simplifié, mais ne vous inquiétez pas à ce sujet)

Les chaînes de pitch valides sont celles qui se terminent par un retrait, une marche ou un coup.

Autrement dit, une chaîne de hauteur non valide a soit

  • lancers supplémentaires après la 4e balle, la 3e frappe ou la frappe
  • terminé avant de générer une 4e balle, une 3e frappe ou un coup.

Règles

  • Votre programme doit être capable de produire tous les résultats possibles pour une entrée donnée.
  • Votre programme ne doit pas être uniformément aléatoire mais doit toujours suivre la règle précédente.
  • C'est du .

Exemples

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
Veskah
la source
1
Nous devons donc être en mesure de produire de 1 à l'infini F?
Quintec
La chaîne comportera au plus 100 caractères. Les fautes sont ce qui permet de si longues cordes de tangage, par exemple 99 Fs et a Sest une grève
Veskah
Oh, j'ai compris, manqué ça
Quintec
@Quintec reformulé pour être un peu plus explicite au cas où
Veskah

Réponses:

4

Python 2 , 128 octets

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)

Essayez-le en ligne!

Générez aléatoirement la chaîne de pitch jusqu'à ce que le batteur soit fait, sortez-la si elle s'avère avoir la bonne longueur, et sinon essayez à nouveau à partir de zéro.


Python 2 , 136 octets

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)

Essayez-le en ligne!

xnor
la source
Le portage de Kevin de cela m'a fait réaliser que cela tombe en panne pour des nombres plus élevés. n=8peut générer une chaîne de Fs à la fin
Veskah
2
@Veskah Nice catch. Je n'avais pas pris en compte le nombre de coups (comptage des fautes) pouvant aller jusqu'à 6 et changer S/3pour le (S>2)corriger.
xnor
4

05AB1E ,  44  50 44 octets

Biffé &nbsp;44&nbsp;n'a plus 44 ans :)

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

Port de la réponse Python 2 de @xnor , alors assurez-vous de lui aussi voter positivement si vous aimez cette réponse!
+6 octets en raison d'une correction de bogue, et après cela -6 octets encore grâce à @xnor en portant son correctif plus efficace par rapport à ma solution temporaire, comme je m'y attendais. ;)

Essayez-le en ligne ou vérifiez d'autres sorties aléatoires .

Explication:

[                # 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)
Kevin Cruijssen
la source
1
@Veskah J'ai fait une correction simple pour l'instant. J'ai l'impression que xnor est capable de faire un correctif plus court, donc je vais probablement porter son correctif pour économiser quelques octets plus tard. :)
Kevin Cruijssen
1
Vous pouvez le réparer comme je l'ai fait en passant X/3à X>2.
xnor
@xnor Merci, de nouveau à 44 octets. Je savais que tu trouverais quelque chose de plus court. ; p
Kevin Cruijssen
3

R , 148 octets

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}

Essayez-le en ligne!

Génère la chaîne, en utilisant l'inclusion conditionnelle dans les jeux de données d'échantillonnage pour garantir que le résultat est une séquence de pas possible.

Il est possible que l'échantillonnage de rejet (comme le fait la réponse en python de xnor ) soit plus court.

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.

Référence aléatoire "F et S" qui continuait à jouer dans ma tête chaque fois que je tapais une de ces lettres ...

Giuseppe
la source
2

Pyth, 53 octets

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

Essayez-le en ligne ici .

Cela semble beaucoup trop long, je pense qu'une autre approche peut être nécessaire.

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
Sok
la source
2

JavaScript (ES6),  107 106  99 octets

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])

Essayez-le en ligne!

Commenté

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
Arnauld
la source
2

Encre , 120 119 116 117 octets

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

Essayez-le en ligne!

Probablement encore jouable au golf.

Non golfé (légèrement reformaté)

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

Modifications

  1. Enregistré un octet en terminant avec ->->au lieu de->END .
  2. Enregistré trois octets en décrémentant nplus tôt.
  3. Correction d'un bug qui provoquait des barrages à des endroits incorrects, grâce à @veskah pour l'avoir repéré (+1 octet)
Sara J
la source
1
Sur la base de la rédaction et des sorties, il semble que cela ne
prenne
1
@veskah Bien repéré, devrait être corrigé maintenant, merci
Sara J
1

Fusain , 57 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

≔⁰η≔⁰ζ

Commencez avec 0 balles et 0 frappe.

F⊖N«

Boucle sur toutes les livraisons sauf la dernière.

≔‽⁺²‹ζ³ι

Si le nombre de balles a été inférieur à trois, générez un nombre aléatoire de 0 à 2, sinon faites simplement un coinflip entre 0 et 1.

¿›ι¹≦⊕ζ≦⊕η

Une valeur aléatoire de 2 est une balle, sinon elle augmente le nombre de coups.

§SFB∨ι›η²»

Les valeurs 0 à 2 correspondent à la frappe, à la faute et au ballon, sauf que s'il y a trois frappes, la faute est imprimée à la place. (Quatre balles sont exclues ci-dessus.)

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

Déterminez si une frappe ou une balle ferait sortir le frappeur et choisissez parmi celles-ci ou un coup comme approprié.

Neil
la source
1

Perl 5 , 122 octets

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]

Essayez-le en ligne!

Xcali
la source
1
@Veskah J'ai raté cette partie. A corrigé.
Xcali
1

C (GCC) 164 145 142 octets

-3 octets plafondcat

#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)}}}

Essayez-le en ligne

rtpax
la source
Suggérer &nau lieu detime(0)
plafond