有效的羽毛球得分?


27

介绍:

我看到现在只有另一个与羽毛球有关的挑战。自从我自己打羽毛球以来(至今已有13年),我认为自己会增加一些与羽毛球有关的挑战。这里是第一个:

挑战:

输入:两个整数
输出:您自己选择的三个不同且唯一的输出之一。表示输入的内容是有效的羽毛球得分,并且该组以获胜者结束;一个表示输入的羽毛球得分有效并且该集合仍在进行中;表示输入的羽毛球得分无效。

使用羽毛球时,两个(两对)球员都从0分开始,并且当两个(两对)球员中的一个得分达到21,且相差至少2分,最高为30-29时,您停止。

因此,这些都是可能的输入对(以任意顺序),表明其是有效的羽毛球得分,并且该组已经结束:

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

这些都是可能的输入对(以任意顺序),表明它是有效的羽毛球得分,但该组仍在起作用:

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

任何其他整数对都将是无效的羽毛球得分。

挑战规则:

  • I / O是灵活的,因此:
    • 您可以将输入作为两个数字的列表。通过STDIN或函数参数将两个数字分开;两根弦;等等
    • 输出将是您自己选择的三个不同且唯一的值。可以是整数(即[0,1,2][1,2,3][-1,0,1]等); 可以是布尔值(即[true,false,undefined/null/empty]);可以是字符/字符串(即["valid & ended","valid","invalid"]);等等
    • 请指定您在答案中使用的I / O!
  • 允许您按照从最低到最高的顺序对输入整数进行排序,反之亦然。
  • 输入整数可以为负,在这种情况下,它们当然是无效的。

一般规则:

  • 这是,因此最短答案以字节为单位。
    不要让代码高尔夫球语言阻止您发布使用非代码高尔夫球语言的答案。尝试针对“任何”编程语言提出尽可能短的答案。
  • 标准规则适用于具有默认I / O规则的答案,因此允许您使用STDIN / STDOUT,具有适当参数的函数/方法以及返回类型的完整程序。你的来电。
  • 默认漏洞是禁止的。
  • 如果可能的话,请添加一个带有测试代码的链接(即TIO)。
  • 另外,强烈建议为您的答案添加说明。

测试用例:

这些测试用例有效,并且设置已经结束:

0 21
12 21
21 23
28 30
29 30

这些测试用例有效,但仍在使用中:

0 0
0 20
12 12
21 21
21 22

这些测试用例无效:

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

Answers:


1

Stax,20 个字节

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

运行并调试

它采用与示例相同的格式输入。 0表示有一个有效的赢家。1表示游戏正在进行中。-1表示无效的分数。

在伪代码中,输入为x和时y,算法为

sign(clamp(x + 2, 21, 30) - y) | (x < 0 || x >= 30 ? 0 : -1)
  • sign指数字符号(-10,或1
  • clamp 强制其第一个参数进入指定的半开间隔

6

Python 2中97 95 75 72 71 70 69 64 55 54个 52 51 50 48字节

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

在线尝试!

将输入作为预购商品a,b

返回-2-10endedin playinvalid

-1个字节,感谢Kevin Cruijssen


左侧(b-61<~a<a>b/22*b-3)是有效性检查,右侧(19<b-(b<30)>a)是游戏结束的检查。


6

Python 2,47个字节

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

在线尝试!

输出两个布尔值的列表。感谢TFeld他们的答案中编写了一个测试套件,使检查我的解决方案变得容易。

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

关键的见解是,如果增加较高的值b会使得分无效,则有效得分将完全结束游戏。所以,我们只码了有效条件,并检查是否有(a,b+1)除了(a,b)看,如果比赛已经结束。

通过链接在一起的三个条件检查有效性:

  • b<3+max(19,a)b使用b<=21b<=a+2(以2获胜)检查更高的分数是否未曾获胜
  • 60-a>b:等同于a+b<=59,确保得分不高于(29,30)
  • 61>60-a:等于a>=0,确保较低的分数为非负数

Python 2,44字节

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

在线尝试!

TFeld改进的有效性检查可节省3个字节。主要思想是基于“加班” b>21b/22*b将低于21的得分有效地设置为零,而我a>19则以更长的时间为准max(19,a)


Python 2,43个字节

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

在线尝试!

输出:

ended: 0
going: -1
invalid: 1

假设输入不低于。299


1
使用我最新的有效性检查(b-61<~a<a>b/22*b-3),您可以节省3个字节。
TF于

1
+1字节使您的第二个解决方案适用于所有输入:lambda a,b:-(a<0)|cmp(2+max(19,a)%30-a/29,b)
TF于

4

JavaScript(ES6), 55 53  48字节

感谢@KevinCruijssen注意到我没有完全假设(节省5个字节)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

在线尝试!



4

果冻,25个字节

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

在线尝试!

左参数:最小值。正确的论点:最大值。
无效:0。进行中:1。已结束: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]

说明:

»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字节

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

此函数将分数按升序排列,如果分数无效,则返回空集;如果集完整或有效,则返回包含该集是否完整的集(如果集完整且有效,则返回{true};如果集不完整且返回{false},则返回false)。有效)

完整的程序可能如下所示:

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

说明:

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字节

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

在线尝试!

返回一个Object,分别是Integer 0无效游戏和Booleantruefalse以及有效进行中的游戏和有效的完成游戏的。以排序(和咖喱)的分数为准,从高分开始。

-2 bytes通过反转比赛结束检查。
-11 bytes通过使用位运算符进行逐行扫描和一些返回类型自动装箱的技巧-感谢@KevinCruijssen

不打高尔夫球

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),35 字节SBCS

中止默认功能,结束为2,进行中为1,无效为0,剩下的分数越来越小。

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

在线尝试!

实现Outgolfer的Erik数学公式,将其组合为

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

并直接翻译为APL(严格来说是右关联的,因此我们避免使用括号):

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

只需将替换为,将替换为,就可以将其转换为默认函数,表示左参数和右参数而不是两个变量:xy

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

现在相当于任何缀函数,所以我们可以简化为

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

这是我们的解决方案;(,≡30 31|,)×(⊢<2+X)×1+⊢>X←29⌊20⌈1+⊣

 左参数  加一;  最大值为20,并且;  最小值为29,并且;  将其分配给;  正确的论点是否更大(0/1)?  加一; ...  乘法的由以下;  两个加号;  是小于(0/1)的正确参数; …  将以下乘以;  连接参数;  除以这些数字的余数;x
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)
,≡ 串联的参数是否等于(0/1)?[(x,y)=]


3

x86汇编,42字节

接受输入ECXEDX注册。请注意,该值ECX必须大于EDX
输出到中EAX0表示游戏仍在进行中,1表示游戏结束,并且-1(aka FFFFFFFF)表示无效得分。

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

或者,在英特尔语法中更具可读性:

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

有趣的事实:该函数几乎遵循C调用约定的规则来保存寄存器,除了我不得不笨拙EBX地在堆栈使用中节省一些字节外。


可选(不包括在字节数中)

通过在上面的代码开始之前直接添加以下6个字节,可以传递ECXEDX无序排列:

39 D1 7D 02 87 CA

可读的英特尔语法中的以下内容:

CMP ECX, EDX
JGE check
XCHG ECX, EDX

2

视网膜0.8.2,92字节

\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

在线尝试!链接包括测试用例。以升序输入。说明:第一阶段只是从十进制转换为一进制,以便可以正确比较分数。第二阶段包含六个备用模式,分为三个组,以便可以输出三个不同的值,分别是10获胜,01持续和00非法。模式是:

  • 在0-19的情况下,比分是21
  • 面对20-28,得分+2是胜利
  • 面对29分,胜出30分
  • 在任何(较低)分数下,得分为0-20
  • 在最高28分的情况下,正在进行+1分
  • 其他任何东西(包括负面分数)都是违法的


1

Bash 4 +,97 89 91 88字节

假设输入是递增的。VDM-SL回答中的二手概念。在线尝试
z==0 -游戏进行中
z==1-游戏完成
z==2-无效

凯文·克鲁伊森(Kevin Cruijssen)对逻辑进行了-3的改进,从而(( & | ))条件
+2修正了错误中对括号-8进行了修正

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
您的89字节版本似乎输出1而不是2for 0 30。您的97字节版本正常运行,因此,如果无法修复它,则可以随时回滚。支持该97版本。:)
凯文·克鲁伊森


1
我修复了,但是你的更好!很难跟上:P
抢劫

Bug at 29 30:(应该“完成”
roblogic

1
哎呀.. i>29应该j>29在第二个三元组中修复它。
Kevin Cruijssen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.