Десять штифтов для боулинга - издание World Bowling

20

Мировой боулинг

Многие люди пошли в свой местный боулинг-центр, чтобы поиграть в несколько игр в боулинг, и многие продолжают бороться, чтобы подсчитать свои очки. World Bowling ввел упрощенную систему подсчета очков, чтобы привлечь больше людей к спорту. Эта система начисления очков используется в международных играх.

Система подсчета очков работает следующим образом (из Википедии ):

Система подсчета очков World Bowling, описываемая как «текущий подсчет кадров» [32], предусматривает следующие выводы:

  • Удар: 30 (независимо от результатов последующих бросков)
  • запасной: 10 плюс штырь на первом броске текущего кадра
  • open: общее количество ошибок для текущего кадра

Если вы не знакомы с боулингом с десятью булавками, вот резюме.

В конце дорожки для боулинга есть 10 кеглей, цель которых - сбить их всех шаром для боулинга. Вы получаете 2 броска шара, чтобы попытаться сбить их всех с ног, предпочтительно сбить их всех с первого броска (известный как удар ). Если вы получили удар, то этот кадр завершен, и вам не нужно катать мяч во второй раз. Удар стоит 30.

Если не сбить все десять, вы получите еще один бросок. Если вы сбиваете все оставшиеся булавки, это называется запасным . Счет стоит 10 пинов + количество пинов, сбитых при первом броске. Например, если я сбил 7 пинов, то сумел сбить оставшиеся 3, это стоило бы 17.

Если после второго броска вам не удастся сбить все десять, это называется открытой рамой . Оценка соответствует общему количеству пинов, сбитых за этот кадр.

В игре 10 кадров . Если вы знакомы с традиционным боулингом, вы не получите дополнительный бросок в 10-м кадре с World Bowling Scoring. При традиционном подсчете боулинга для достижения идеального результата в 300 ударов требуется 12 ударов подряд, тогда как для подсчета очков в боулинге мира требуется всего 10 ударов подряд.

Вызов

Ваша задача состоит в том, чтобы вычислить заданные значения баллов из таблицы результатов.

На оценочном листе промах обозначается тире ( - ), ударом с X и запасным с косой чертой ( / ). Если это не применимо, то количество выпадений просто указывается числом (1-9). Фолы и расколы также записываются на листах результатов, но вам не нужно беспокоиться об этом.

вход

Вам будет предоставлена ​​строка, состоящая из баллов за каждый кадр, и в общей сложности будет десять кадров. Каждый кадр будет иметь до двух значений или всего 1 значение, если произошел удар. Ваш ввод может быть строковым параметром для функции, читать из файла или из STDIN.

Например, если я сбил 1 булавку на своем первом броске, а затем сбил 2, рамка будет выглядеть как «12». Это не означает 12 (двенадцать), но означает 1 и 2, всего 3.

Если бы я пропустил каждый штифт с обоими рулонами (желобными шариками), это выглядело бы так: «-» (оценка 0).

Каждый кадр будет разделен пробелом.

Пример ввода

-- 9- -9 X -/ 8/ 71 15 44 X

Чтобы сломать этот пример,

  • Кадр 1 (-) - оба рулона пропущены. набрал 0
  • Кадр 2 (9-) - сбил 9 на первом броске, пропустил на втором броске. Оценка 9
  • Кадр 3 (-9) - пропустил всех на первом, получил 9 на втором. Оценка 9
  • Кадр 4 (X) - Ударь, сбил все десять. Оценка 30
  • Кадр 5 (- /) - Запасной, пропустил все по первому, сбил все со 2-го броска. Оценка 10 + 0 = 10
  • Кадр 6 (8 /) - Запасной, 8 штифтов на первом броске, сбил 2 других с помощью второго броска. Оценка 10 + 8 = 18
  • Рама 7 (71) - открытая рама, 7 штифтов на первом рулоне, 1 штифт на втором рулоне. Счет 7 + 1 = 8
  • Кадры 8, 9, 10 следуют тем же примерам, что и выше.

Выход

Выводом будет просто значение, которое имеет сумму баллов по всем 10 кадрам. Используя пример ввода, выведите 128. Ваш вывод может быть строковым или числовым типом. Это может быть возвращаемое значение функции или записанное в STDOUT.

правила

  • Предположим, что ввод всегда будет действительным. Например, недопустимый кадр будет "/ 8", "XX", "123", "0" и т. Д.
  • Вам не нужно беспокоиться о расколах или фолах.
  • Ваш код может быть полной программой или функцией, которая принимает строку и возвращает результат.
  • Ваш код не должен выдавать никаких исключений.
  • Это код гольф, ответ с наименьшим количеством выигранных байтов.
  • Языки, которые используют, включают или импортируют, должны включать операторы импорта как часть своего кода и подсчитывать количество байтов.

Тестовые случаи

"-- 9- -9 X -/ 8/ 71 15 44 X" -> 128
"-- -1 2- 12 22 5- 42 61 8- 72" -> 45
"X X X 1/ 2/ 3/ 4/ 5/ -- 9/" -> 174
"X X X X X X X X X X" -> 300
"-- -- -- -- -- -- -- -- -- --" -> 0
Makotosan
источник
21
Я разочарован, это не вызов боулинга
Джо Кинг,
13
Ваш первый запасной пример говорит, что счет будет 13, но я думаю, что он должен быть 17.
Джо.
@Джо. Хороший улов. Я обновил вопрос, чтобы исправить эту ошибку.
Макотосан
@JoKing Когда я впервые увидел название, я подумал, что это сложный боулинг, состоящий из 10 подзадач.
Вейцзюнь Чжоу,
1
Одна из лучших задокументированных и письменных проблем, которые я видел.
Джошуа

Ответы:

7

05AB1E , 12 11 байт

Код

S'/T:'X30:O

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

объяснение

S             # Split the string into a list of characters
 '/T:         # Replace '/' with 10
     'X30:    # Replace 'X' with 30
          O   # Sum up the array (ignoring non-number elements)
Аднан
источник
7

JavaScript, 43 байта

f=([c,...s])=>c?({'/':10,X:30}[c]|c)+f(s):0

Как это устроено

Мы конвертируем каждый символ в его точку:

  • «Х» стоит 30 баллов
  • '/' стоит 10 баллов
  • '1' .. '9' стоит 1 .. 9 баллов
  • другие персонажи стоят 0 очков

Затем сложите все очки.

Конвертировать

Побитовый оператор ИЛИ| преобразует свой операнд в Int32 перед операцией. При преобразовании в Int32 значение сначала преобразуется в формат Number (64-разрядное число с плавающей запятой), а затем транк в Int32 (или преобразуется в 0, если он недействителен).

  • ToInt32({'/':10,X:30}[c]) может быть прочитано как:
    • если c == '/': результат равен 10;
    • если c == 'X': результат равен 30;
    • в противном случае: результат ToInt32(undefined)-> ToInt32(NaN)-> 0;
  • ToInt32(c) может быть:
    • если c == '1' ... '9': результат равен 1 .. 9;
    • если c == '': Number(c)равно 0, результат равен 0;
    • иначе: Number(c)есть NaN, результат равен 0;
  • Побитовый или здесь такой же, как «добавить», так как один из его операндов будет 0

сумма

  • [c,...s] = sпусть c = s[0]и s = s.slice(1);
    • если s пустая строка, c не определено ;
    • в противном случае c - это первая буква s
  • undefined - ложь, непустая строка (включая пробел) - правда
ТТГ
источник
1
Можете ли вы объяснить свой код? выглядит очень хорошо
Луис Фелипе Де Иисус Муньос
@LuisfelipeDejesusMunoz Только что добавил.
ч. В
5

Stax , 13 байт

─*âⁿ┴8òt↨HÉ÷8

Запустите и отладьте его

Распаковано, расклеено и прокомментировано так.

F               for each character in input, execute...
 9R$'/20*+'X+   build the string "123456789////////////////////X"
 I              get the index of the current character in string
 ^+             increment and add to running total
                (index is -1 when no match; space and dash are 0 score)

Запустите этот

рекурсивный
источник
3

Java 8, 64 59 46 байт

s->s.map(c->c<46?0:c<48?10:c>87?30:c-48).sum()

-5 байт благодаря @Neil .
-13 байт благодаря @ OlivierGrégoire .

Объяснение:

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

s->               // Method with an IntStream parameter and integer return-type
  s.map(c->       //  Loop over the characters
          c<46?   //   If the character is a space or '-':
           0      //    Count it as 0
          :c<48?  //   Else-if it's a '/':
           10     //    Count it as 10
          :c>87?  //   Else-if it's an 'X':
           30     //    Count it as 30
          :       //   Else (it's a digit):
           c-48   //    Count it as the value of the digit
       ).sum()    //   And sum everything
Кевин Круйссен
источник
1
("123456789//"+1e6+1e6+"X")кажется, чтобы сохранить 5 байтов.
Нил
Это умная техника для создания строки наполнителя.
Макотосан
1
46 байтов
Оливье Грегуар,
3

F #, 106 103 байта

let s c=Seq.sumBy(fun x->if x=' '||x='-'then 0 elif x='X'then 30 elif x='/'then 10 else int(string x))c

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

Я думаю, что эта головоломка (без игры в гольф) была бы отличным вопросом для руководства "Функциональное программирование для начинающих". И я должен знать!

-3 от Кевина Круйссена, за то, что он заметил, что пробел между 'и "тогда" может быть удален. Благодарность!

Stax решение рекурсивного использования строковых индексов очень и очень хорошо. Если вы перенесете его на F #, вы можете получить его за 77 байт :

let s c=Seq.sumBy(fun x->"123456789/???????????????????X".IndexOf(char x)+1)c

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

Ciaran_McCarthy
источник
1
Я не очень хорошо знаю F #, но, кажется, вы можете отбросить пробелы после '-3 байтов.
Кевин Круйссен
И я нет! Но вы правы, хорошо заметили! Благодарность!
Ciaran_McCarthy
2
@Ciaran_McCarthy: Я не против, если вы скопируете мое решение, если вы хотите включить его также. Люди здесь, как правило, довольно открыто говорят о подобных вещах. Это совместная попытка найти весь самый маленький код, даже если это формально соревнование.
рекурсивный
1
Спасибо рекурсивное. Я включу его тогда, потому что это очень хорошее решение, и интересно посмотреть, как оно выглядит на разных языках.
Ciaran_McCarthy
2

Желе , 17 байт

ḟ⁾ -“X0/⁵”yV€o30S

Монадическая ссылка, принимающая список символов и возвращающая целое число

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

Как?

ḟ⁾ -“X0/⁵”yV€o30S - Link: list of characters
 ⁾ -              - literal list of characters [' ','-']
ḟ                 - filter discard
    “X0/⁵”        - literal list of characters ['X','0','/','⁵']
          y       - translate (change 'X's to '0's and '/'s to '⁵'s)
           V€     - evaluate €ach character as Jelly code (the '⁵'s become 10s)
             o30  - logical OR with 30 (change all instances of 0 to 30)
                S - sum

Также в 17:

”/ẋ20ØD;;”XḊiЀ⁸S

Попробуй это

Джонатан Аллан
источник
2

Сетчатка , 17 байт

X
///
/
55
\d
*
_

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

Я не совсем в курсе последних изменений Retina. Я буду больше изучать их, когда у меня будет шанс, и посмотреть, есть ли какие-нибудь новые хитрости для игры в гольф. Код превращает все штрихи в три запасных части, все запасные части в десять точек, а затем все указывает на соответствующее число подчеркиваний. Затем он считает количество подчеркиваний.

PunPun1000
источник
2

Perl 5 -pF , 30 27 байтов

-3 байта благодаря Xcali

#!/usr/bin/perl -pF
$\+=m%/%+3*/X/.0+$_ for@F}{

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

Тон Хоспел
источник
Вы можете сократить два байта, используя /X/вместо, y/X//и еще один, используя m%/%вместо y%/%%: Попробуйте онлайн!
Xcali
@Xcali Ах, конечно. Классическая близорукость гольфа, я все еще думал о том, y///когда я делал их вне петли. Спасибо
Тон Хоспел
1

05AB1E , 14 байтов

þ`I…/aXS¢ƶT*`O

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

объяснение

þ`              # Push the digits of the input on the stack (removes everyting that isn't a digit)
  I…/aXS        # Push the input and the array "/","a","X" on the stack
        ¢       # Index of each element in the input ...
         ƶT*    # ... multiplied by its index (a could be anything that can't be found in the input), multiplied by 10.
            `O  # Sum the stack, implicit display
Kaldo
источник
1

J , 33 байта

1#.31|('-123456789',20 1#'/X')i.]

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

Объяснение:

] вход

('-123456789',20 1#'/X')добавляет 20 /и один Xк строке-123456789

i. находит индексы ввода в приведенной выше строке

31| по модулю 31 - чтобы избавиться от пробелов - они не найдены в строке, поэтому i. возвращает 31 для них

1#. находит сумму показателей

Гален Иванов
источник
Поскольку J и Red - два совершенно разных языка, лучше опубликовать два отдельных ответа, даже если они могут делать то же самое. Вы можете добавить ссылку из ответа Red к этому ответу J, указав, что это порт вашего ответа J.
Кевин Круйссен
@Kevin Cruijssen - Хорошо, спасибо - я сделаю это. Причиной их совместного размещения является то, что очевидно, что решение Red неконкурентоспособно (хотя и очень читабельно :))
Гален Иванов
1

Python 2 , 67 байт

-3 байта благодаря @KevinCruijssen

lambda I,p='-123456789/'+20*'X':sum(p.rfind(i)for i in I if i in p)

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

Мертвый Опоссум
источник
1
Вы можете сэкономить 3 байта, изменив '-123456789'+'/'*20+'X':sum(p.index(i)на'-123456789/'+'X'*20:sum(p.rfind(i)
Кевин Круйссен
@KevinCruijssen спасибо, хорошо!
Мертвый опоссум
1

Желе , 12 байт

⁾/X,“½œ‘y|0S

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

Как это устроено

⁾/X,“½œ‘y|0S  Main link. Argument: s (string)

⁾/X,“½œ‘      Literal; yield [['/', 'X'], [10, 30]].
        y     Transliterate; replace '/' with 10, 'X' with 30.
         |0   Bitwise OR with 0. Bitwise operators attempt to cast to int, mapping 
              '0', ..., '9' to 0, ..., 9. All other characters map to 0.
           S  Take the sum.
Деннис
источник
1

Котлин , 50 байтов

x->x.sumBy{"123456789/_${Math.E}_X".indexOf(it)+1}

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

Надеюсь, это не противоречит правилам, чтобы ответить на ваш собственный вопрос, но я хотел присоединиться к веселью.

Math.Eпроизводит значение 2.718281828459045. Я использую его для создания какой-либо строки-заполнителя, чтобы переместить X в положение 30.

indexOfполучает позицию (на основе 0) символа в строке «12345 ...». Если он не найден, он возвращает -1. Мы добавляем 1, чтобы сделать эти 0, и это также делает позицию на основе 0 значением строки.

Makotosan
источник
1

PHP 119 109 байт

-10 байт благодаря @KevinCruijssen

<?foreach(explode(" ",$argv[1])as$f){[$a,$b]=str_split($f);$n+=$f==X?30:(int)$a+($b=='/'?10:(int)$b);}echo$n;

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

Джо.
источник
Вы можете изменить ($b=='/'?10+(int)$a:((int)$a+(int)$b))в (int)$a+($b=='/'?10:(int)$b)течение -10 байт.
Кевин Круйссен
@KevinCruijssen Спасибо, выглядит хорошо! Хотя, глядя на другие ответы, похоже, я иду по этому неправильному / долгому пути. :)
Джо.
0

Древесный уголь , 23 байта

IΣEχΣES⎇№-/Xλ×χ⌕-//XλIλ

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

  Eχ                    Map over 10 frames
      S                 Input the frame
     E                  Map over the characters
            λ           Current character
        №-/X            Search the literal string `-/X`
                    λ   Current character
               ⌕-//X    Find position in literal string `-//X`
             ×χ         Multiply by predefined variable 10
                      λ Current character
                     I  Cast to integer
       ⎇                Ternary
    Σ                   Sum for each frame
 Σ                      Sum over frames
I                       Cast to string for implicit print
Нил
источник
0

SNOBOL4 (CSNOBOL4) , 169 151 147 байт

	F =INPUT ' '
R	F '-' =0	:S(R)
T	F 'X' ='_'	:S(T)
S	F LEN(1) . X ARB . Y ' ' REM . F	:F(O)
	X '_' =30
	Y '/' =10
	S =S + X + Y	:(S)
O	OUTPUT =S
END

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

	F =INPUT ' '					;* read input and append a space
R	F '-' =0	:S(R)				;* replace - with 0
T	F 'X' ='_'	:S(T)				;* replace X with _
S	F LEN(1) . X ARB . Y ' ' REM . F	:F(O)	;* set first character to x, remainder up to ' ' to y, and remainder to F
	X '_' =20					;* replace _ in x with 20
	Y '/' =10					;* replace / in y with 10
	S =S + X + Y	:(S)				;* else X and Y are their values so we can sum them
O	OUTPUT =S					;* output the sum
END
Giuseppe
источник
0

Clojure , 70 байт

#(reduce(fn[s i](+ s(case i\- 0\/ 10\X 30\space 0(bigint(str i)))))0%)

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

Когда reduceнад строкой, каждый символ фактически превращается в символ - кто бы мог подумать. Но об этом я должен написать, \spaceи это ранит больше, чем можно себе представить. Кроме того, при создании фактического числа из символа комбинация bigintиstr представляется единственной полезной комбинацией.

Ну, кроме всего этого: анонимная функция, которая возвращает результат в натуральном выражении.

Джошуа
источник