二十一点胸围计算器


12

二十一点(也称为二十一点)是您自己与发牌人之间的比较纸牌游戏,其中每个玩家依次与发牌人竞争,但玩家不互相对抗。

玩法如下,发牌人为您发牌。然后,发牌人自己将一张卡片面朝下。然后,发牌人再发给您一张卡。最后,发牌人面朝上给自己发卡。

挑战

您面临的挑战是编写一个程序(或函数),该程序在运行(或调用)时输出(或返回)发牌者给您的下一张纸牌会让您破产的概率,这意味着您之后手中的纸牌累计得分庄家给您另外一张超过21的卡。

输入值

正在播放的三张可见牌。它们是您手中的两张卡,并且是您在经销商手中可以看到的一张卡。您可以使用任何适合您的应用程序的格式。

一副牌中有52张牌(下面每张卡中的4张)。卡的价值如下:

Symbol(Case Insensitive)  Name     Value
2                         Two      2
3                         Three    3
4                         Four     4
5                         Five     5
6                         Six      6
7                         Seven    7
8                         Eight    8
9                         Nine     9
T                         Ten      10
J                         Jack     10
Q                         Queen    10
K                         King     10
A or 1                    Ace      1 

在二十一点中,一张ace可以计为1或11。在我们的挑战中,仅将其计为1

输出量

下一张发牌的概率(比率或百分比)会让我们破产。

您可以输出百分比,分数或仅分数的分子。

例子

在此示例中,前两张卡在我们手中,第三张卡是经销商可见的卡

 Input          ->       Output

 A 2 Q          ->       0.00%  or  0/49 or 0
 A 2 3          ->       0.00%  or  0/49 or 0
 T T T          ->       91.84% or 45/49 or 91.84 
 T J K          ->       91.84% or 45/49 or 45
 9 7 3          ->       61.22% or 30/49 ...
 9 7 Q          ->       59.18% or 29/49 ...

规则

不允许出现标准漏洞

这是,因此每种语言的最短代码(以字节为单位)获胜!


2
我们是否可以将ace设为1,将face card设为10s,还是将输入格式拉伸得太远?

那么,我们可以将面孔卡设为10吗?
wastl

1
@Arnauld谢谢你的收获。我更新了比率,但没有更新概率。至于您的输出问题,没关系。您不必在每个答案上添加/ 49。
DevelopingDeveloper

1
“ TJK-> 91.84%或45/49 或45等等...”-因此我们可以简单地输出分子?如果可以的话,您可以在文字中注明吗?
乔纳森·艾伦

1
@JonathanAllan更新
DevelopingDeveloper

Answers:


7

果冻 26  24 字节

O%48«⁵µ13R«⁵ẋ4œ-+ṖS$>21S

接受字符列表(使用小写选项或带1for 的大写选项A)的单子链接,该字符串返回中的分子(第49 数字)[0,49]

在线尝试!或查看测试套件

怎么样?

请注意,通过使用小写字母,最小值10和以48为模的普通数给出卡的值。这同样适用于大写TJQK1对于一个王牌,如右图所示(但大写A不工作):

     card:   a   2   3   4   5   6   7   8   9   t   j   q   k   |   1   T   J   Q   K
  ordinal:  97  50  51  52  53  54  55  56  57 116 106 113 107   |  49  84  74  81  75
   mod 48:   1   2   3   4   5   6   7   8   9  20  10  17  11   |   1  36  26  33  27
min(_,10):   1   2   3   4   5   6   7   8   9  10  10  10  10   |   1  10  10  10  10

O%48«⁵µ13R«⁵ẋ4œ-+ṖS$>21S - Link: list of characters   e.g. "q3a"
O                        - ordinals (of the input list)    [113, 51, 97]
 %48                     - modulo by 48                    [17,3,1]
     ⁵                   - ten
    «                    - minimum                         [10,3,1]
      µ                  - start a new monadic chain
       13R               - range of 13                     [1,2,3,4,5,6,7,8,9,10,11,12,13]
           ⁵             - ten                             10
          «              - minimum                         [1,2,3,4,5,6,7,8,9,10,10,10,10]
            ẋ4           - repeat four times               [1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10]
              œ-         - multi-set difference            [1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10  ,2  ,4,5,6,7,8,9   ,10,10,10]
                   $     - last two links as a monad:
                 Ṗ       -   pop                           [10,3]
                  S      -   sum                           13
                +        - add (vectorises)                [14,15,16,17,18,19,20,21,22,23,23,23,23,14,15,16,17,18,19,20,21,22,23,23,23,23,14,15,16,17,18,19,20,21,22,23,23,23,23,15,17,18,19,20,21,22,23,23,23]
                    >21  - greater than 21?                [0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1]
                       S - sum                             19

诱惑全力以赴窃取mod-48技术的加剧
Magic Octopus Urn

如果我最终使用mod-48做出了回答,那么我将悬赏200英镑,以进行史诗般的观察。
魔术章鱼缸

4

JavaScript(ES6),73 62字节

将输入作为3个字符组成的数组,带1for。返回表示要被破坏的概率X / 49的整数X。

a=>([b,c]=a.map(v=>v*4||40)).map(n=>b-=n+b>52,b+=c-32)|b>12&&b

在线尝试!

详尽测试

打高尔夫球的公式不是很直观。因此,证明其一致性的最简单方法可能是将所有可能的输出与基本的非高尔夫实现提供的输出进行比较:

g = a => {
  deck = [...'123456789TJQK'.repeat(4)];
  a.forEach(card => deck.splice(deck.indexOf(card), 1));

  return deck.filter(card =>
    (+a[0] || 10) +
    (+a[1] || 10) +
    (+card || 10) > 21
  ).length;
}

在线尝试!


.map(n=>b-=n+b>52,b+=c-32)一般情况下做什么?我对JS不太熟悉,.map并试图了解逗号在这里的作用。.最初,我虽然是.map(n=>{b-=n+b>52;b+=c-32})或的较短变体。.我知道a=>([b,c]=a.map(v=>v*4||40))可以转换['1','2','Q'][ 4, 8, 40 ],然后在这三个值之间循环,b第一个值在哪里,c第二个(如果我理解正确的话)。但是我有点困惑.map(n=>b+=(n+b<53)-1,b+=c-32)(如果第一个b-=更改为b+=)vs .map(n=>b+=(n+b<53)-33+c).
凯文·克鲁伊森

嗯,或者确实是b=第一个值,c=中的第二个值[4, 8, 40],并且如果是第二次迭代,是否也进行b-=n+b>52修改c?因此,在哪种情况下将b-=b+=合并为一个b+=(或b-=)无效?
凯文·克鲁伊森

1
@KevinCruijssen b+=c-32是的(未使用)参数,map()在第一次迭代之前仅被评估一次。n=>b-=n+b>52是回调函数(的第一个参数map()),并在每次迭代时调用。从技术上讲,map()它确实接受第二个参数(称为thisArg),但这在这里是无关紧要的:我们只希望在循环开始之前执行这段代码。
阿诺尔德

1
@KevinCruijssen 是一些代码,显示正在发生的事情。
阿诺尔德

好的,现在一切都有意义了。谢谢!
凯文·克鲁伊森

2

Pyth,35个字节

Jm?}dGTsdQclf>T-21sPJ.-*4+ST*3]TJ49

将输入作为字符列表(或字符串)。
在这里尝试

说明

Jm?}dGTsdQclf>T-21sPJ.-*4+ST*3]TJ49
Jm?}dGTsdQ                            Convert each input to the appropriate number.
                     .-*4+ST*3]TJ     Remove each from the deck.
           lf>T-21sPJ                 Count how many remaining cards bust.
          c                      49   Get the probability.

1

Perl 5、115字节

map{//;$k{$_}=4-grep$' eq$_,@F}1..9,T,J,Q,K;map{s/\D/10/}@F;$_=grep{$F[0]+$F[1]+$_>21}map{(s/\D/10/r)x$k{$_}}keys%k

在线尝试!


1

Python 2中97 96个字节

def f(s):C=[min(int(c,36),10)for c in s];D=C[0]+C[1];return(4*D-35+sum(v+D<22for v in C))*(D>11)

在线尝试!

将3个字符的字符串作为输入,并使用'1'作为Ace。返回分子。


1

Java 8,109字节

a->{int r=3;for(;r-->0;a[r]=a[r]<59?a[r]*4-192:40);r=a[0]+a[1]-32;for(int v:a)r-=v+r>52?1:0;return r>12?r:0;}

@Arnauld的JavaScript(ES6)Answer的端口。
输入具有三个值的字符数组,Aces为'1'; 输出是概率pp/49

在线尝试。

说明:

a->{                   // Method with integer-array as parameter and integer return-type
  int r=3;for(;r-->0;  //  Loop over the array
    a[r]=a[r]<59?      //   If the current item is a digit:
          a[r]*4-192   //    Multiply it by 4
         :             //   Else:
          40);         //    Change it to 40
  r=a[0]+a[1]-32;      //  Set `r` to the first value, plus the second value, minus 32
  for(int v:a)         //  Loop over the now modified array again
    r-=v+r>52?         //   If the current value plus `r` is larger than 52
        1              //    Decrease the result-integer by 1
       :0;             //   Else: Leave the result-integer the same
  return r>12?         //  If the result-integer is larger than 12
          r            //   Return the result-integer
         :             //  Else:
          0;}          //   Return 0


1

05AB1E23 22 21字节

AST:4-D¨OÐ4@*4*Š+T@O-

在线尝试!

AST:                   # replace all letters in the input with 10
    4-                 # subtract 4 from each card value
      D                # duplicate
       ¨               # drop the last element
        O              # sum (hand value of the player - 8)
         Ð             # triplicate that
          4@*          # set to 0 if it's less than 4
             4*        # multiply by 4
               Š       # 3-way swap
                +      # add the player's hand value to each card value
                 T@O   # count how many are >= 10
                    -  # subtract
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.