Hasilkan String Lapangan Baseball

11

Tujuan

Tulis program atau fungsi yang mengambil bilangan bulat positif ndan secara acak menghasilkan serangkaian nada (untuk selanjutnya disebut string Pitch) panjangnya n.

Memasukkan

Bilangan bulat nol tidak nol n<= 100

Keluaran

Mengembalikan string acak, atau daftar karakter, yang mewakili string panjang nada yang mungkin dan valid n. Karakter yang digunakan adalah:

  • B - Ball. Jika Anda mengumpulkan 4 dari ini, adonan berjalan dan selesai memukul.
  • S - Strike. Jika Anda mengumpulkan 3 dari ini, adonan keluar dan selesai memukul.
  • F -Foul. Akan juga meningkatkan jumlah Strike tetapi tidak bisa mengeluarkan adonan. Yaitu, Anda tidak dapat memiliki pelanggaran menjadi nada terakhir dalam string yang valid. Setiap pelanggaran melewati dua serangan / pelanggaran tidak akan meningkatkan jumlah Serangan (adonan sudah memiliki 2 serangan pada saat itu dan yang ketiga akan mengeluarkannya).
  • H - Hit. Adonan telah memukul bola untuk dimainkan dan selesai memukul.

(Ini sedikit disederhanakan tapi jangan khawatir tentang itu)

Senar nada yang valid adalah yang berakhir dengan mogok, jalan-jalan, atau pukulan.

Yaitu, string pitch yang tidak valid memiliki salah

  • pitch tambahan setelah Ball 4, Strike ke-3, atau Hit
  • dihentikan sebelum menghasilkan bola ke-4, serangan ke-3, atau Hit.

Aturan

  • Program Anda harus dapat menghasilkan semua hasil yang mungkin untuk input yang diberikan.
  • Program Anda tidak harus acak, tetapi masih harus mengikuti aturan sebelumnya.
  • Ini adalah .

Contohnya

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
sumber
1
Jadi kita harus dapat menghasilkan di mana saja dari 1 hingga tak terhingga F's?
Quintec
Panjang string maksimal 100 karakter. Pelanggaran adalah apa yang memungkinkan senar nada panjang seperti, misalnya 99 Fdetik dan Sa strike-out
Veskah
Oh, mengerti, melewatkannya
Quintec
@ Quintec Memesan ulang untuk menjadi sedikit lebih eksplisit untuk berjaga
Veskah

Jawaban:

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)

Cobalah online!

Secara acak menghasilkan string pitch sampai adonan selesai, output jika ternyata panjang yang tepat, dan jika tidak coba lagi dari awal.


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)

Cobalah online!

Tidak
sumber
Pelabuhan Kevin tentang hal ini membuat saya menyadari bahwa gangguan ini untuk angka yang lebih tinggi. n=8dapat menghasilkan rantai Fs pada akhirnya
Veskah
2
@ Vesah Tangkapan bagus. Saya belum menghitung jumlah mogok (menghitung pelanggaran) mungkin naik ke 6, dan mengubah S/3untuk (S>2)memperbaikinya.
xnor
4

05AB1E ,  44  50 44 byte

Dicoret &nbsp;44&nbsp;tidak lagi 44 :)

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

Pelabuhan @xnor 's Python 2 answer , jadi pastikan untuk menghapusnya juga jika Anda suka jawaban ini!
+6 byte karena perbaikan bug, dan setelah itu -6 byte lagi berkat @xnor dengan porting cara memperbaikinya yang lebih efisien dibandingkan dengan perbaikan sementara saya, seperti yang saya harapkan. ;)

Cobalah secara online atau verifikasi beberapa keluaran acak .

Penjelasan:

[                # 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
sumber
1
@ Vespa Saya telah melakukan perbaikan lurus ke depan untuk saat ini. Saya merasa xnor dapat melakukan perbaikan yang lebih pendek, jadi saya mungkin akan port perbaikannya untuk menghemat beberapa byte nanti. :)
Kevin Cruijssen
1
Anda dapat memperbaikinya seperti yang saya lakukan dengan mengubah X/3ke X>2.
xnor
@xnor Terima kasih, kembali ke 44 byte lagi. Saya tahu Anda akan menemukan sesuatu yang lebih pendek. ; 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}

Cobalah online!

Menghasilkan string, menggunakan inklusi bersyarat dalam dataset pengambilan sampel untuk memastikan bahwa hasilnya adalah urutan pitch yang mungkin.

Kemungkinan melakukan rejection sampling (seperti yang dilakukan oleh xnor's python ) lebih pendek.

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.

Referensi acak "F dan S" yang terus bermain di kepala saya setiap kali saya mengetik salah satu surat itu ...

Giuseppe
sumber
2

JavaScript (SpiderMonkey) , 137 byte

f=(n,o='',i=Math.random()*4|0,r=/^(?!.*((B.*){4}|([SF].*){2}S|H).)/)=>r.test(o)?n?f(n-1,o+'BSFH'[i%4])||i<8&&f(n,o,i+1):!r.test(o+1)&&o:0

Cobalah online!

tsh
sumber
2

Pyth, 53 byte

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

Cobalah online di sini .

Ini terasa terlalu lama, saya pikir pendekatan lain mungkin diperlukan.

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

Cobalah online!

Berkomentar

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
sumber
2

Tinta , 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}}->->

Cobalah online!

Mungkin masih golf.

Tidak disatukan (diformat ulang sedikit)

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

Suntingan

  1. Disimpan byte dengan finishing dengan ->->bukan ->END.
  2. Disimpan tiga byte dengan mengurangi nsebelumnya.
  3. Memperbaiki bug yang menyebabkan pemogokan di tempat yang salah, terima kasih kepada @veskah karena menemukannya (+1 byte)
Sara J
sumber
1
Berdasarkan penulisan dan hasil, sepertinya itu tidak memasukkan pelanggaran yang menambah jumlah serangan dengan benar
Veskah
1
@veskah Terlihat dengan baik, harus diperbaiki sekarang, terima kasih
Sara J
1

APL (Dyalog Unicode) , 77 byte SBCS

{'HBSF'[{⍺←⍬⋄∨/((⊃⌽⍺)=⍳3)∧1,4 3≤(⊃s),+/1↓s←⍺∘(+/=)¨1+⍳3:⍺⋄∇⍨⍺,?4}⍣{i=≢⍺}i←⍵]}

Cobalah online!

voidhawk
sumber
1

Arang , 57 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

≔⁰η≔⁰ζ

Mulailah dengan 0 bola dan 0 serangan.

F⊖N«

Ulangi semua pengiriman kecuali yang terakhir.

≔‽⁺²‹ζ³ι

Jika jumlahnya kurang dari tiga bola, maka hasilkan angka acak dari 0 hingga 2, jika tidak hanya coinflip antara 0 dan 1.

¿›ι¹≦⊕ζ≦⊕η

Nilai acak 2 adalah bola jika tidak maka jumlah serangan akan meningkat.

§SFB∨ι›η²»

Nilai 0 hingga 2 peta untuk menyerang, busuk dan bola, kecuali bahwa jika akan ada tiga pukulan maka pelanggaran dicetak sebagai gantinya. (Empat bola dikecualikan di atas.)

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

Tentukan apakah serangan atau bola akan mengeluarkan adonan dan memilih dari mereka atau pukulan yang sesuai.

Neil
sumber
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]

Cobalah online!

Xcali
sumber
1
@ Veskah saya merindukan bagian itu. Memperbaikinya.
Xcali
1

C (GCC) 164 145 142 byte

-3 byte 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)}}}

Cobalah online

rtpax
sumber
Sarankan &nalih-alihtime(0)
ceilingcat