Genera una stringa di pitch di baseball


11

Obbiettivo

Scrivi un programma o una funzione che accetta un numero intero positivo ne genera in modo casuale una serie legale di passi (d'ora in poi chiamata stringa del passo) di lunghezza n.

Ingresso

Un numero intero positivo diverso da zero n<= 100

Produzione

Restituisce una stringa casuale, o un elenco di caratteri, che rappresentano una possibile stringa di lunghezza valida n. I personaggi utilizzati saranno:

  • B - Palla. Se ne accumuli 4, la pastella viene percorsa e finita la battuta.
  • S - Colpisci. Se ne accumuli 3, la pastella è fuori e ha finito di battere.
  • F - Fallo. Aumenterà anche il conteggio degli Strike ma non riuscirà a far uscire il battitore. Cioè, non puoi avere un Fallo come ultimo passo in una stringa valida. Qualsiasi fallo oltre due colpi / falli non aumenterà il conteggio degli Strike (il battitore ha già 2 colpi in quel punto e un terzo lo farebbe uscire).
  • H - Hit. Il battitore ha colpito una palla in gioco e ha finito di battere.

(Questo è leggermente semplificato ma non ti preoccupare per quello)

Le stringhe di intonazione valide sono quelle che terminano in uno strike-out, una passeggiata o un colpo.

Cioè, una stringa di intonazione non valida ha entrambe

  • tiri supplementari dopo la 4a palla, il 3 ° colpo o il colpo
  • terminato prima di generare una quarta palla, un terzo colpo o un colpo.

Regole

  • Il tuo programma deve essere in grado di produrre tutti i possibili risultati per un dato input.
  • Il tuo programma non deve essere uniformemente casuale ma deve comunque seguire la regola precedente.
  • Questo è .

Esempi

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
Quindi dobbiamo essere in grado di produrre ovunque da 1 a infinito F?
Quintec,

La stringa avrà una lunghezza massima di 100 caratteri. I falli sono ciò che consente stringhe così lunghe, ad esempio 99 se Fa Sè uno strike-out
Veskah

Oh, capito, l'ho perso
Quintec,

@Quintec È stato riformulato per essere un po 'più esplicito, per ogni evenienza
Veskah,

Risposte:


4

Python 2 , 128 byte

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)

Provalo online!

Genera in modo casuale la stringa di intonazione fino a quando il battitore è terminato, emettilo se risulta della lunghezza giusta e prova a riprovare da zero.


Python 2 , 136 byte

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)

Provalo online!


La porta di Kevin di questo mi ha fatto capire che si rompe per numeri più alti. n=8può generare una catena di Fs alla fine
Veskah,

2
@Veskah Bella cattura. Non avevo tenuto conto del conteggio degli scioperi (contando i falli) probabilmente andando a 6 e cambiando S/3per (S>2)risolverlo.
xnor

4

05AB1E ,  44  50 44 byte

Cancellato non &nbsp;44&nbsp;è più 44 :)

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

Porta della risposta Python 2 di @xnor , quindi assicurati di votare anche lui se ti piace questa risposta!
+6 byte a causa di una correzione di bug, e successivamente di nuovo -6 byte grazie a @xnor portando la sua soluzione più efficiente rispetto al mio lavoro temporaneo, come mi aspettavo. ;)

Provalo online o verifica altri output casuali .

Spiegazione:

[                # 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 Per ora ho fatto una correzione diretta. Ho la sensazione che xnor sia in grado di fare una correzione più breve, quindi probabilmente porterò la sua correzione per salvare alcuni byte in seguito. :)
Kevin Cruijssen,

1
Puoi sistemarlo come ho fatto cambiando X/3in X>2.
xnor

@xnor Grazie, torna di nuovo a 44 byte. Sapevo che avresti trovato qualcosa di più corto. ; p
Kevin Cruijssen,

3

R , 148 byte

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}

Provalo online!

Genera la stringa, utilizzando l'inclusione condizionale nei set di dati di campionamento per garantire che il risultato sia una possibile sequenza di tonalità.

Forse il campionamento del rifiuto (come fa la risposta python di xnor ) è più breve.

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.

Riferimento casuale "F e S" che continuava a suonare nella mia testa ogni volta che scrivevo una di quelle lettere ...



2

Pyth, 53 byte

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

Provalo online qui .

Sembra troppo lungo, penso che potrebbe essere necessario un altro approccio.

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 byte

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

Provalo online!

Commentate

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

Inchiostro , 120 119 116 117 byte

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

Provalo online!

Probabilmente ancora golfabile.

Ungolfed (leggermente riformattato)

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

Le modifiche

  1. Salvato un byte finendo con ->->invece di ->END.
  2. Salvato tre byte diminuendo in nprecedenza.
  3. Risolto un bug che causava strikeout in posti errati, grazie a @veskah per averlo individuato (+1 byte)

1
Sulla base del write-up e dei risultati, sembra che non influisca sui falli
nell'aumentare

1
@veskah Ben individuato, ora dovrebbe essere risolto, grazie
Sara J


1

Carbone , 57 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

≔⁰η≔⁰ζ

Inizia con 0 palle e 0 colpi.

F⊖N«

Passa in rassegna tutte le consegne tranne l'ultima.

≔‽⁺²‹ζ³ι

Se sono state meno di tre palline, quindi genera un numero casuale da 0 a 2, altrimenti lancia solo tra 0 e 1.

¿›ι¹≦⊕ζ≦⊕η

Un valore casuale di 2 è una palla, altrimenti aumenta il conteggio degli strike.

§SFB∨ι›η²»

I valori da 0 a 2 sono mappati per colpire, fallo e palla, tranne per il fatto che se ci sarebbero tre colpi, verrà stampato il fallo. (Quattro palle sono escluse sopra.)

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

Determina se un colpo o una palla tirerebbe fuori il battitore e scegli tra quelli o un colpo a seconda dei casi.


1

Perl 5 , 122 byte

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]

Provalo online!


1
@Veskah Ho perso quella parte. Aggiustato.
Xcali,

1

C (GCC) 164 145 142 byte

-3 byte plafoniera

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

Provalo online


Suggerisci &ninvece ditime(0)
ceilingcat il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.