Pontuação válida de badminton?


27

Introdução:

Vi que havia apenas mais um desafio relacionado ao badminton no momento . Já que eu jogo badminton (nos últimos 13 anos), imaginei que adicionaria alguns desafios relacionados ao badminton. Aqui o primeiro:

Desafio:

Entrada: Dois números inteiros
Saída: Uma das três saídas distintas e exclusivas de sua própria escolha. Um indicando que a entrada é uma pontuação válida de badminton E o set terminou com um vencedor; um indicando que a entrada é uma pontuação válida de badminton E o conjunto ainda está em jogo; um indicando que a entrada não é uma pontuação válida de badminton.

No badminton, os dois (pares de) jogadores começam com 0 pontos, e você para quando um dos dois (pares de) jogadores atinge 21 pontos, com pelo menos 2 pontos de diferença, até um máximo de 30-29.

Portanto, todos esses pares de entradas possíveis (em qualquer ordem) indicam que é uma pontuação válida de badminton E o conjunto terminou:

[[0,21],[1,21],[2,21],[3,21],[4,21],[5,21],[6,21],[7,21],[8,21],[9,21],[10,21],[11,21],[12,21],[13,21],[14,21],[15,21],[16,21],[17,21],[18,21],[19,21],[20,22],[21,23],[22,24],[23,25],[24,26],[25,27],[26,28],[27,29],[28,30],[29,30]]

E todos esses pares de entradas possíveis (em qualquer ordem) indicam que é uma pontuação válida de badminton, MAS o conjunto ainda está em jogo:

[[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[0,10],[0,11],[0,12],[0,13],[0,14],[0,15],[0,16],[0,17],[0,18],[0,19],[0,20],[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[1,11],[1,12],[1,13],[1,14],[1,15],[1,16],[1,17],[1,18],[1,19],[1,20],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[2,10],[2,11],[2,12],[2,13],[2,14],[2,15],[2,16],[2,17],[2,18],[2,19],[2,20],[3,3],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[3,11],[3,12],[3,13],[3,14],[3,15],[3,16],[3,17],[3,18],[3,19],[3,20],[4,4],[4,5],[4,6],[4,7],[4,8],[4,9],[4,10],[4,11],[4,12],[4,13],[4,14],[4,15],[4,16],[4,17],[4,18],[4,19],[4,20],[5,5],[5,6],[5,7],[5,8],[5,9],[5,10],[5,11],[5,12],[5,13],[5,14],[5,15],[5,16],[5,17],[5,18],[5,19],[5,20],[6,6],[6,7],[6,8],[6,9],[6,10],[6,11],[6,12],[6,13],[6,14],[6,15],[6,16],[6,17],[6,18],[6,19],[6,20],[7,7],[7,8],[7,9],[7,10],[7,11],[7,12],[7,13],[7,14],[7,15],[7,16],[7,17],[7,18],[7,19],[7,20],[8,8],[8,9],[8,10],[8,11],[8,12],[8,13],[8,14],[8,15],[8,16],[8,17],[8,18],[8,19],[8,20],[9,9],[9,10],[9,11],[9,12],[9,13],[9,14],[9,15],[9,16],[9,17],[9,18],[9,19],[9,20],[10,10],[10,11],[10,12],[10,13],[10,14],[10,15],[10,16],[10,17],[10,18],[10,19],[10,20],[11,11],[11,12],[11,13],[11,14],[11,15],[11,16],[11,17],[11,18],[11,19],[11,20],[12,12],[12,13],[12,14],[12,15],[12,16],[12,17],[12,18],[12,19],[12,20],[13,13],[13,14],[13,15],[13,16],[13,17],[13,18],[13,19],[13,20],[14,14],[14,15],[14,16],[14,17],[14,18],[14,19],[14,20],[15,15],[15,16],[15,17],[15,18],[15,19],[15,20],[16,16],[16,17],[16,18],[16,19],[16,20],[17,17],[17,18],[17,19],[17,20],[18,18],[18,19],[18,20],[19,19],[19,20],[20,20],[20,21],[21,21],[21,22],[22,22],[22,23],[23,23],[23,24],[24,24],[24,25],[25,25],[25,26],[26,26],[26,27],[27,27],[27,28],[28,28],[28,29],[29,29]]

Qualquer outro par de números inteiros seria uma pontuação de badminton inválida.

Regras do desafio:

  • A E / S é flexível, portanto:
    • Você pode considerar a entrada como uma lista de dois números; dois números separados por meio de STDIN ou parâmetros de função; duas cordas; etc.
    • A saída será três valores distintos e únicos de sua própria escolha. Pode ser inteiros (ou seja [0,1,2], [1,2,3], [-1,0,1], etc.); pode ser booleano (ie [true,false,undefined/null/empty]); pode ser caracteres / strings (ie ["valid & ended","valid","invalid"]); etc.
    • Especifique a E / S que você usou em sua resposta!
  • Você pode levar os números inteiros de entrada pré-ordenados do menor para o maior ou vice-versa.
  • Os números inteiros de entrada podem ser negativos; nesse caso, eles são obviamente inválidos.

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta com as regras de E / S padrão , para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados e programas completos do tipo retorno. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código (ou seja, TIO ).
  • Além disso, é altamente recomendável adicionar uma explicação para sua resposta.

Casos de teste:

Esses casos de teste são válidos e o conjunto foi encerrado:

0 21
12 21
21 23
28 30
29 30

Esses casos de teste são válidos, mas o conjunto ainda está em jogo:

0 0
0 20
12 12
21 21
21 22

Esses casos de teste são inválidos:

-21 19
-19 21
-1 1
12 22
29 31
30 30
42 43
1021 1021

Respostas:


1

Stax , 20 bytes

ÇåπßéD╩¬7▼ß▌ΣU¬í╡S┤╘

Execute e depure

É necessário inserir no mesmo formato que os exemplos. 0significa que há um vencedor válido. 1significa que o jogo está em andamento. -1significa pontuação inválida.

No pseudo-código, com entradas ordenadas xe y, o algoritmo é

sign(clamp(x + 2, 21, 30) - y) | (x < 0 || x >= 30 ? 0 : -1)
  • signsignifica sinal numérico ( -1, 0ou 1)
  • clamp força seu primeiro argumento no intervalo semiaberto especificado

6

Python 2 , 97 95 75 72 71 70 69 64 55 54 52 51 50 48 bytes

lambda a,b:(b-61<~a<a>b/22*b-3)*~(19<b-(b<30)>a)

Experimente online!

Recebe a entrada conforme solicitado a,b .

Retornos -2, -1, 0para ended, in play,invalid .

-1 byte, graças a Kevin Cruijssen


A parte esquerda ( b-61<~a<a>b/22*b-3) é uma verificação de validade e a parte direita ( 19<b-(b<30)>a) é uma verificação do jogo encerrado.


6

Python 2 , 47 bytes

lambda a,b:[61>60-a>b<3+max(19,a)for b in-~b,b]

Experimente online!

Produz uma lista de dois booleanos. Agradeço ao TFeld por escrever uma suíte de testes na resposta que facilitou a verificação da minha solução.

ended: [False, True]
going: [True, True]
invalid: [False, False]

O principal insight é que uma pontuação válida encerra o jogo exatamente se o aumento do valor mais alto btorna a pontuação inválida. Então, apenas codificamos a condição de validade e verificamos (a,b+1)além de(a,b) ver se o jogo terminou.

A validade é verificada através de três condições encadeadas:

  • b<3+max(19,a): Verifica se a pontuação mais alta bnão venceu no passado, com b<=21ou b<=a+2(vitória por dois)
  • 60-a>b: Equivalente a a+b<=59, garantindo que a pontuação não esteja acima(29,30)
  • 61>60-a: Equivalente a a>=0, garante que a pontuação mais baixa não seja negativa

Python 2 , 44 bytes

lambda a,b:[b-61<~a<a>b/22*b-3for b in-~b,b]

Experimente online!

Uma verificação de validade aprimorada do TFeld economiza 3 bytes. A idéia principal é ramificar as "horas extras", b>21com as b/22*bquais efetivamente define as pontuações abaixo de 21 como zero, enquanto eu havia me ramificado por a>19mais tempo max(19,a).


Python 2 , 43 bytes

lambda a,b:a>>99|cmp(2+max(19,a)%30-a/29,b)

Experimente online!

Saídas:

ended: 0
going: -1
invalid: 1

Assume que as entradas não estão abaixo 299 .


1
Usando meu mais novo validity-check ( b-61<~a<a>b/22*b-3), você pode salvar 3 bytes.
TFeld 27/03

1
+1 byte para fazer sua segunda solução funcionar para todas as entradas:lambda a,b:-(a<0)|cmp(2+max(19,a)%30-a/29,b)
TFeld 27/03

4

JavaScript (ES6),  55 53  48 bytes

ab

(a)(b)ab012

a=>b=>a<0|a>29|b>30|b>21&b-a>2?2:b>20&b-a>1|b>29

Experimente online!



4

Gelatina , 25 bytes

»19«28‘<‘×+2>ɗʋ⁹×,%Ƒ“œþ‘ɗ

Experimente online!

Argumento à esquerda: mínimo. Argumento certo: máximo.
Inválido: 0. Ongoing: 1. Terminou: 2.

xy

[a]={a:1¬a:0(a,b)=(amod30,bmod31)x,yZX:=min(max(x+1,20),29)p:=(x,y)([X<y]+1)[X+2>y][p=p]

Explicação:

»19«28‘<‘×+2>ɗʋ⁹×,%Ƒ“œþ‘ɗ Left argument: x, Right argument: y
»19«28‘                   X := Bound x + 1 in [20, 29]:
»19                         X := max(x, 19).
   «28                      X := min(X, 28).
      ‘                     X := X + 1.
       <‘×+2>ɗʋ⁹          X := If X + 2 <= y, then 0, else if X < y, then 2, else 1:
       <                    t := If X < y, then 1, else 0.
        ‘                   t := t + 1.
          +2>ɗ              u := Check if X + 2 > y:
          +2                  u := X + 2.
            >                 u := If u > y, then 1, else 0.
         ×                  X := t * u.
                 ,%Ƒ“œþ‘ɗ z := If x mod 30 = x and y mod 31 = y, then 1, else 0:
                 ,          z := (x, y).
                  % “œþ‘    m := z mod (30, 31) = (x mod 30, y mod 31).
                   Ƒ        z := If z = m, then 1, else 0.
                ×         X * z.

3

VDM-SL , 80 bytes

f(i,j)==if(j-i>2and j>21)or(i<0or i=30or j>30)then{}else{(j>20and j-i>1or j=30)} 

Essa função pega as pontuações ordenadas em ordem crescente e retorna o conjunto vazio se a pontuação for inválida ou o conjunto que contém se o conjunto está completo (então {true} se o conjunto estiver completo e válido e {false} se o conjunto estiver incompleto e válido)

Um programa completo para executar pode ser assim:

functions
f:int*int+>set of bool
f(i,j)==if(j-i>2and j>21)or(i<0or i=30or j>30)then{}else{(j>20and j-i>1or j=30)}

Explicação:

if(j-i>2 and j>21)             /*if scores are too far apart*/
or(i<0 or i=30 or j>30)        /*or scores not in a valid range*/
then {}                        /*return the empty set*/
else{                       }  /*else return the set containing...*/
     (j>20 and j-i>1 or j=30)  /*if the set is complete*/

3

Java (JDK) , 59 48 bytes

a->b->b<0|b>29|a>b+2&a>21|a>30?0:a<21|a<30&a<b+2

Experimente online!

Retorna um Object, que é Integer 0válido para jogos inválidos Booleanes truee falsepara jogos em andamento válidos e para jogos concluídos válidos, respectivamente. Leva a pontuação ordenada (e ao curry), com a pontuação mais alta primeiro.

-2 bytesinvertendo a verificação de final de partida.
-11 bytescurrying, usando operadores bit a bit e alguns truques de tipo de retorno de autobox - graças a @KevinCruijssen

Ungolfed

a->                      // Curried: Target type IntFunction<IntFunction<Object>>
    b->                  // Target type IntFunction<Object>
                         // Invalid if:
            b<0          //    Any score is negative
          | b > 29       //    Both scores above 29
          |   a > b + 2  //    Lead too big
            & a > 21     //        and leader has at least 21 points
          | a > 30       //    Anyone has 31 points
        ? 0              // If invalid, return 0 (autoboxed to Integer)
                         // If valid, return whether the game is ongoing (autoboxed to Boolean)
                         // Ongoing if:
        :   a < 21       //    Nobody has 21 points
          |   a < 30     //    Leader has fewer than 30 points
            & a < b + 2  //        and lead is small

3

APL (Dyalog Unicode) , SBCS de 35 bytes

A função tácita infix onde terminou é 2, em andamento é 1, inválido é 0, pontuações menores e maiores são deixadas.

(,≡30 31|,)×(⊢<2+X1+⊢>X29201+⊣

Experimente online!

Implementa as fórmulas matemáticas de Erik the Outgolfer combinadas em

X:=min(max(x+1,20),29) ([X<y]+1)[X+2>y][(x,y)=(xmod30,ymod31)]

[(x,y)=(x,y)mod(30,31)]×[y<2+X]×(1+[y<(X:=min(29,max(20,1+x)))])

e traduzido diretamente para o APL (que é estritamente associativo à direita, para evitar alguns parênteses):

((x,y)30 31|x,y)×(y<2+X)×1+y>X29201+x

xy

((,)30 31|,)×(<2+X)×1+>X29201+

Agora é equivalente a para qualquer função infix , para que possamos simplificar

(,30 31|,)×(<2+X)×1+>X29201+

qual é a nossa solução; (,≡30 31|,)×(⊢<2+X)×1+⊢>X←29⌊20⌈1+⊣:

 o argumento da esquerda;  um mais que;  máximo de 20 e que;  mínimo de 29 e que;  atribui isso a ;  o argumento correto é maior (0/1) ?;  adicione um; ...  multiplicar o seguinte por isso;  mais dois ;  é o argumento correto menor que esse (0/1); …  multiplique o seguinte por isso;  concatenam os argumentos;  restos quando divididos por esses números; x1 + x máx ( 20 , ) min ( 29 , ) X : = [ y > ] 1 + ( ) × 2 + X [ y < ] ( ) × ( x , y )
1+1+x
20⌈max(20,)
29⌊min(29,)
X←XX:=
⊢>[y>]
1+1+
(()×
2+XX2+X
⊢<[y<]
(()×
,(x,y)
30 31|mod(30,31)
,≡ os argumentos concatenados são idênticos aos (0/1) ?; [(x,y)=]


3

Montagem x86, 42 bytes

Recebe entrada ECXe EDXregistra. Observe que ECXdeve ser maior que EDX.
Saída para EAX, onde 0significa que o jogo ainda está ativo, 1representando o jogo terminado e -1(aka FFFFFFFF) representando uma pontuação inválida.

31 C0 83 F9 1E 77 1F 83 FA 1D 77 1A 83 F9 15 7C 
18 83 F9 1E 74 12 89 CB 29 D3 83 FB 02 74 09 7C 
08 83 F9 15 74 02 48 C3 40 C3

Ou, mais legível na Intel Syntax:

check:
    XOR EAX, EAX
    CMP ECX, 30     ; check i_1 against 30
    JA .invalid     ; if >, invalid.
    CMP EDX, 29     ; check i_2 against 29
    JA .invalid     ; if >, invalid.
    CMP ECX, 21     ; check i_1 against 21
    JL .runi        ; if <, running.
    CMP ECX, 30     ; check i_1 against 30
    JE .over        ; if ==, over.
    MOV EBX, ECX
    SUB EBX, EDX    ; EBX = i_1 - i_2
    CMP EBX, 2      ; check EBX against 2
    JE .over        ; if ==, over.
    JL .runi        ; if <, running.
                    ; if >, keep executing!
    CMP ECX, 21     ; check i_1 against 21
    JE .over        ; if ==, over.
                    ; otherwise, it's invalid.
    ; fallthrough!
    .invalid:
        DEC EAX     ; EAX = -1
        RETN
    .over:
        INC EAX     ; EAX = 1
    ; fallthrough!
    .runi:
        RETN        ; EAX = 0 or 1

Curiosidade: essa função quase segue as regras da Convenção de Chamada C, sobre as quais os registros devem ser preservados, exceto que eu tive que pesar EBXpara salvar alguns bytes no uso da pilha.


Opcional (não incluído na contagem de bytes)

Adicionando os 6 bytes a seguir diretamente antes do início do código acima, você pode transmitir ECXe EDXnão ordenar:

39 D1 7D 02 87 CA

Qual é o seguinte na Intel Syntax legível:

CMP ECX, EDX
JGE check
XCHG ECX, EDX

2

Retina 0.8.2 , 92 bytes

\d+
$*
^(1{0,19},1{21}|(1{20,28}),11\2|1{29},1{30})$|^(1*,1{0,20}|(1{0,28}),1?\4)$|.+
$#1$#3

Experimente online! O link inclui casos de teste. Recebe entrada em ordem crescente. Explicação: O primeiro estágio simplesmente converte de decimal em unário para que as pontuações possam ser comparadas corretamente. O segundo estágio contém seis padrões alternativos, agrupados em três grupos, para que três valores distintos possam ser gerados, que são 10para vitória, 01para contínuo e 00ilegal. Os padrões são:

  • Contra 0-19, 21 pontos é uma vitória
  • Contra 20-28, uma pontuação de +2 é uma vitória
  • Contra 29, uma pontuação de 30 é uma vitória
  • Contra qualquer pontuação (menor), uma pontuação de 0 a 20 está em andamento
  • Contra uma pontuação de até 28, uma pontuação de +1 está em andamento
  • Qualquer outra coisa (incluindo pontuações negativas) é ilegal


1

Bash 4+, 97 89 91 88 bytes

Suponha que as entradas estejam ascendendo. Conceitos usados ​​da resposta do VDM-SL . Experimente Online
z==0 - jogo em andamento
z==1- jogo concluído
z==2- inválido

-8 pela limpeza do suporte das (( & | ))condições
+2 corrigindo um erro, graças a Kevin Cruijssen
-3 melhorias na lógica por Kevin Cruijssen

i=$1 j=$2 z=0
((j-i>2&j>21|i<0|i>29|j>30?z=2:0))
((z<1&(j>20&j-i>1|j>29)?z=1:0))
echo $z

1
Sua versão de 89 bytes parece produzir em 1vez de 2para 0 30. Sua versão de 97 bytes estava funcionando corretamente; portanto, se você não conseguir corrigi-la, poderá reverter. Promovido para a versão 97. :)
Kevin Cruijssen 28/03


1
Eu consertei, mas o seu era melhor! Difícil de acompanhar: P
roblogic 28/03

Bug em 29 30:( ele deve ser "concluído"
roblogic em 3/04

1
Ah, opa .. o i>29deve estar j>29no segundo ternário para corrigi-lo.
Kevin Cruijssen em 3/04
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.