Генерация строки бейсбольного поля

11

Цель

Напишите программу или функцию, которая принимает положительное целое число nи случайным образом генерирует допустимый ряд шагов (далее называемый строкой высоты звука) длины n.

вход

Ненулевое, положительное целое число n<= 100

Выход

Возвращает случайную строку или список символов, которые представляют возможную, допустимую строку основного тона длины n. Используемые символы будут:

  • Б - мяч. Если вы накопите 4 из них, жидкое тесто пройдено и закончено ватин.
  • S - Страйк. Если вы накопите 3 из них, жидкое тесто закончится и закончите ватин.
  • F - Фол. Также увеличит количество ударов, но не сможет вытащить тесто. То есть, вы не можете иметь Фол, чтобы быть последним шагом в допустимой строке. Любые фолы после двух ударов / фолов не будут увеличивать количество ударов (у бьющего уже есть 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
Veskah
источник
1
Таким образом, мы должны иметь возможность производить от 1 до бесконечности F?
Quintec
Строка будет длиной не более 100 символов. Фолы - это то, что позволяет такие длинные струны качки, например, 99 Fс и а 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)

Попробуйте онлайн!

XNOR
источник
Порт Кевина это заставило меня понять, что это разбивает на более высокие цифры. n=8может генерировать цепочку Fs в конце
Веска
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 байт из-за исправления ошибки, и после этого -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.
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", которые продолжали играть в моей голове каждый раз, когда я набирал одну из этих букв ...

Giuseppe
источник
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
Sok
источник
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
Arnauld
источник
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. Исправлена ​​ошибка, из-за которой вычеркивались в неправильных местах, благодаря @veskah за ее обнаружение (+1 байт)
Сара Дж
источник
1
Судя по
описанию
1
@veskah Хорошо заметили, нужно исправить сейчас, спасибо
Сара 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]

Попробуйте онлайн!

Xcali
источник
1
@Veskah Я пропустил эту часть. Починил это.
Xcali
1

C (GCC) 164 145 142 байта

Потолок -3 байта

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

Попробуйте онлайн

rtpax
источник
Предлагаю &nвместоtime(0)
floorcat