是否想看魔术牌戏法?


16

我小时候学到的第一个魔术纸牌技巧是:

  • 有1张纸牌,背面的图案不是垂直对称的。
  • 将所有卡组织成一个方向。
  • 要求个人“拿起一张卡片,任何一张卡片,记住并退还给您”。
  • 继续将其放入甲板(方向错误)。
  • 大力洗牌,给人一种幻觉,即您不知道他们的牌在哪里。
  • 出示他们的卡片使他们惊讶。

如今,这种技巧显然在本质上有些缺乏光泽,但是它却带来了巨大的挑战。编写一个程序,该程序在没有输入的情况下将输出随机洗牌的纸牌,其中一张纸牌是随机选择的,并且反转了。但是,如果输入的是一副纸牌,其中一张纸牌已反转,则必须输出反转的纸牌(以正确的顺序)。


卡片组

一副纸牌定义为:

[2S,3S,4S,5S,6S,7S,8S,9S,TS,JS,QS,KS,AS,
 2D,3D,4D,5D,6D,7D,8D,9D,TD,JD,QD,KD,AD,
 2H,3H,4H,5H,6H,7H,8H,9H,TH,JH,QH,KH,AH,
 2C,3C,4C,5C,6C,7C,8C,9C,TC,JC,QC,KC,AC]

卡的定义是其号码,然后是其西装的第一个字母。卡片的反面正好相反,其西装的第一个字母后跟一个数字。

抽奖卡

例如,如果我们随机选择反转的牌是4 of Clubs (4C),我们最终会(显然没有混洗):

[2S,3S,4S,5S,6S,7S,8S,9S,TS,JS,QS,KS,AS,
 2D,3D,4D,5D,6D,7D,8D,9D,TD,JD,QD,KD,AD,
 2H,3H,4H,5H,6H,7H,8H,9H,TH,JH,QH,KH,AH,
 2C,3C,C4,5C,6C,7C,8C,9C,TC,JC,QC,KC,AC]

洗牌

然后,在改组后:

[2H,2C,6S,4D,QH,6C,TD,8C,7H,5H,C4,3D,7S,7C,KC,QD,QC,JS,7D,6D,2S,5C,KD,3C,3S,2D,8H,KH,6H,AH,8S,JH,TS,AD,5D,9H,4H,JD,QS,4S,JC,3H,8D,TC,AS,TH,KS,AC,9C,9S,5S,9D]

给定空输入,这是有效的输出。

甲板输入

但是,相反,当我们的程序收到上述输出作为输入时,它应该输出4C。也就是说,输入以下内容:

[2H,2C,6S,4D,QH,6C,TD,8C,7H,5H,C4,3D,7S,7C,KC,QD,QC,JS,7D,6D,2S,5C,KD,3C,3S,2D,8H,KH,6H,AH,8S,JH,TS,AD,5D,9H,4H,JD,QS,4S,JC,3H,8D,TC,AS,TH,KS,AC,9C,9S,5S,9D]

您反复进行遍历,直到找到反转的卡,然后将其返回,然后反转回到正常状态。因此,在这里我们将找到C4,知道C不是数字,然后将其返回为4C,这是正确的。


规则

  • 您不得从任何外部来源加载卡座。
  • 空的输入应导致随机洗牌的甲板,其中有1张随机卡片被撤消。
  • 一副纸牌中有1张纸牌作为输入反转的结果应该会导致纸牌反转。
  • 任何其他输入都会导致爆炸性的骆驼在未来派的电子管中骑行。
    • 或其他任何事情。
  • 所选卡和洗牌顺序必须一致地随机。
    • IE浏览器所有卡都有被选择被撤销的同等机会。
    • IE浏览器的所有组合卡都有相同的出现机会。
  • 您可以使用SHCDshcd用于西装,但要保持一致:
    • 如果选择大写西装(SHCD),则还必须使用TJQKA
    • 如果选择小写字母西服(shcd),则还必须使用tjqka
  • 这是,获胜者是最低字节。

2
@ labela--gotoa这个哈哈的FAR太多了。我记得我父亲使用垂直对称的卡片动了我的脑筋,并做了另一种花样,但让我觉得是这样。
魔术章鱼缸

13
“爆炸性的骆驼骑着摩托车穿越未来派的地铁”-我很期待您的下一个ascii艺术挑战……
Level River St

3
将整个牌组从0到51(包括0和51)之间随机偏移即可满足以下条件:“所有牌都有相同的机会出现在改组后的牌组中的任何地方”,但不应视为随机改组。您是说所有(52!)订单的可能性差不多吗?
aschepler '18

1
只是要扩展@aschepler所说的内容:在许多语言中,默认PRNG的周期长度都是52 种中的大多数!可能的混洗出现的概率正好等于零(尽管根据混洗算法可能会更好或更糟)。
Arnauld

1
达赖喇嘛在多莉车上骑喇嘛也可以接受吗?我没装过赛格威和炸药了,但我身上有糖果蠕虫... i.imgur.com/gEkVR5P.gif
Tschallacka

Answers:


7

视网膜61 60 59字节

G`[HCDS].
^$
23456789TJQK
/^2/&L$`.
$&H¶$&D¶$&C¶$&S
@V`
O?`

在线尝试!编辑:由于@MartinEnder,节省了1 2字节。说明:

G`[HCDS].

删除所有未撤销的卡。这应该留下一张反向卡或不留卡。

^$
23456789TJQK
/^2/&L$`.
$&H¶$&D¶$&C¶$&S

如果输入(现在)为空,则创建一包纸牌。

@V`

随机选择一张卡并将其反转(不反转单张反转的卡)。

O?`

随机播放卡。



3

PowerShell v2或更高版本,175字节

%{$s=[char[]]'SDHC';if($_){$_|?{$s-contains$_[0]}|%{$_[1]+$_[0]}}else{$d=$s|%{$e=$_;[char[]]'23456789TJQKA'|%{$_+$e}}|random -c 52;$r=random 52;$d[$r]=$d[$r][1]+$d[$r][0];$d}}

长版:

ForEach-Object {
    $s = [char[]]'SDHC'                         # Create a character array with the suits
    if ($_) {                                   # If there's pipeline input ...
        $_ |                                    # ... write it to the output pipeline ...
            Where-Object {$s -contains $_[0]} | # ... but let only those input elements pass where the first letter appears in the suits ...
            ForEach-Object {$_[1] + $_[0]}      # ... and swap the two elements
    } else {
        $d = $s | ForEach-Object {              # Assign $d to the output of the suits, processing each element first.
                $e = $_                         # Store the current suit element for use in the inner loop
                [char[]]'23456789TJQKA' | ForEach-Object {$_ + $e}  # Process each of the numbers, joining it with the current suit, ...
            } | Get-Random -Count 52            # ... and the resulting 2-char-strings goes back into the output to be shuffled
        $r = Get-Random -Maximum 52
        $d[$r] = $d[$r][1] + $d[$r][0]          # Swap the two chars of a random array element in $d
        $d                                      # Write $d to the output pipeline
    }
}

用法:

创建一个随机播放的牌组并将其存储在变量中:

$Deck = %{$s=[char[]]'SDHC';if($_){$_|?{$s-contains$_[0]}|%{$_[1]+$_[0]}}else{$d=$s|%{$e=$_;[char[]]'23456789TJQKA'|%{$_+$e}}|random -c 52;$r=random 52;$d[$r]=$d[$r][1]+$d[$r][0];$d}}

随意检查变量,例如

$Deck -join ','

将套牌通过管道传递回脚本中:

$Deck | %{$s=[char[]]'SDHC';if($_){$_|?{$s-contains$_[0]}|%{$_[1]+$_[0]}}else{$d=$s|%{$e=$_;[char[]]'23456789TJQKA'|%{$_+$e}}|random -c 52;$r=random 52;$d[$r]=$d[$r][1]+$d[$r][0];$d}}

2

Python 2,175字节

from random import*
s='SHCD';c='23456789TJQKA'
d=input()
if d:print[b+a for a,b in d if a in s];q
k=sample
r=k(c,1)+k(s,1)
print k([(a+b,b+a)[r==a+b]for a in c for b in s],52)

在线尝试!空输入表示为[]


2

> <> 215个 193字节

i:0)?\~"CHSD":"2"$:"3"$:"4"$:"5"$:"6"$:"7"$:"8"$:"9"$:"T"$:"J"$:"Q"$:"K"$:"A"$&105&"S"=?.~~~{c0.
=+i$?\i$:::"B")$"I"(*$"S"
_oo$~/;
x0
x0
x0
x0
x0
x0
x0
x0
x0
x0
\l&>?!<
>&"3"%:?\~$>o<
\  }}&-1/

在线尝试!

将输入视为未分隔的卡,并将输出视为相同的卡(例如KCAC5C6S...

为了使测试更容易,这是一个版本该版本以逗号分隔输入,而以换行分隔输出。

所有x0s只是尝试制作一个半均匀随机数生成器。它们越多,可能值的范围越大,反之则越少。我认为其中10个足够随机。

请注意,它遵循以下规则:

  • 所有卡都有相等的机会被选择为可逆的。
  • 所有牌都有相同的机会出现在洗牌后的任何地方。

但是并非所有经过改组的组合都是可能的输出(实际上,绝大多数不是)。


2

果冻,26 个字节

9ḊṾ€;“AJKQT”p“CDHS”ḟ⁸ẊU-¦Ẋ

Monadic链接,该列表接受字符列表(0张卡的存根或52张卡的全副牌,其中一张卡已反转)并返回字符列表(1张反向卡的存根但正向或完整的卡) -甲板,其中一张随机卡被颠倒了)。

在线尝试!(使输入和输出表示形式匹配的页脚-作为完整的程序,Jelly代码使用Python使参数无效,并将字符粉碎在一起作为输出)

怎么样?

9ḊṾ€;“AJKQT”p“CDHS”ḟ⁸ẊU-¦Ẋ - Link: list of lists of characters, Z
9Ḋ                         - nine dequeued = [2,3,4,5,6,7,8,9]
  Ṿ€                       - unevaluate €ach = ['2','3','4','5','6','7','8','9']
     “AJKQT”               - literal list of characters = ['A','J','K','Q','T']
    ;                      - concatenate = ['2','3','4','5','6','7','8','9','A','J','K','Q','T']
             “CDHS”        - literal list of characters = ['C','D','H','S']
            p              - Cartesian product = [['2','C'],['2','D'],...,['T','S']]
                           -   a full deck of forward cards
                    ⁸      - chain's left argument, Z
                   ḟ       - filter discard
                           -   leaving either that deck or the 1 reversed card in the input
                     Ẋ     - shuffle
                        ¦  - sparse application...
                       -   - ...to index: -1 (which doesn't exist when the length is only 1)
                      U    - ...do: upend (reverses the penultimate card of the deck)
                         Ẋ - shuffle

这似乎总是逆转十颗心。难道不是随机卡吗?
Emigna

嗯,谢谢,是的,这里有一个错误-可以U((我可以修复零字节)之前用一个额外的东西修复它,但是以后必须这样做...
Jonathan Allan

由于这是一项功能,因此我不确定输入非空时是否可以返回[[number, suit]]而不是[number, suit]代表一张卡。
Erik the Outgolfer '18

此外,不,我不认为有任何 0字节修复了点。
Erik the Outgolfer

@EriktheOutgolfer我不明白为什么不这么做,一张寂寞的卡毕竟是一张卡的存根(短卡)。
乔纳森·艾伦,

1

Ruby,95(或100)字节

->n{s=(0..51).map{|i|"A23456789TJQK"[i/4]+"HCDS"[i%4]}
n[0]?s-n:s[rand 52].reverse!&&s.shuffle}

给定一个空数组作为输入,将卡片组作为字符串数组返回。给定一个非空数组作为输入,将翻转的卡作为包含单个字符串的数组返回。如果翻转卡被要求作为一个字符串,而不是含有一个字符串的单个元素数组,以下添加5个字节:改变s-n(s-n)[0]

在线尝试!

第一行生成一个标准牌组。第二行分解如下

 n[0]?                  #If the input array is not empty (contains a truthy first element)
  s-n:                  #Find the contents of s with the contents of n removed. The only card remaining from the standard deck corresponds to the flipped card in the input.
                        #ELSE 
  s[rand 52].reverse!&& #Flip one card in place in the array s. As the result is truthy, whatever is next will be returned.
 s.shuffle              #shuffle the deck and return the shuffled deck with one element flipped
}

1

Java的8,275个 274 259字节

import java.util.*;s->{if(s==null){List l=new Stack();char i=52,r=i,x,y;for(r*=Math.random();i-->0;y="23456789TJQKA".charAt(i%13),l.add(i==r?x+""+y:y+""+x))x="HSDC".charAt(i&3);Collections.shuffle(l);return l;}return s.replaceAll(".*,(.)([^HSDC]).*","$2$1");}

输入是一个字符串,输出是一个字符串或java.util.List取决于输入。

说明:

在线尝试。

import java.util.*;          // Required import for List, Stack and Collections
s->{                         // Method with String parameter and Object return-type
  if(s==null){               //  If the input is `null`:
    char i=52,               //   Index-integer
         r=i,                //   Random-integer
         x,y;                //   Temp characters
    List l=new Stack();      //   Create a List
    for(r*=Math.random();    //   Determine the random integer in the range (0;52]
        i-->0                //   Loop `i` 52 times:
        ;                    //     After every iteration:
         y="23456789TJQKA".charAt(i%13)
                             //      Set `y` to one of 23456789TJQKA based on `i` modulo-13
         ,l.add(i==r?        //      If the random integer equals the current `i`
                 x+""+y      //       Add the current card reversed
                :            //      Else:
                 y+""+x))    //       Add the current card as is
      x="HSDC".charAt(i&3);  //    Set `x` to one of HSDC based on `i` bitwise-AND 3
    Collections.shuffle(l);  //   Shuffle the generated Deck
    return l;}               //   And return this Deck as result
                             //  If the input was a Deck instead:
  return s.replaceAll(".*,(.)([^HSDC]).*",
                             //   Get the reversed card from the Deck,
            "$2$1");}        //   and output it non-reversed

1

Pyth,45个字节

J"CDHS"KO52=NsM.S*+c"AKQJT"1S9J|f}hTJQXNK_@NK

取空​​列表作为空输入。
在线尝试

说明

J"CDHS"KO52=NsM.S*+c"AKQJT"1S9J|f}hTJQXNK_@NK
J"CDHS"                                        Save the suits as J.
       KO52                                    Save a random index as K.
           =NsM.S*+c"AKQJT"1S9J                Save a shuffled deck as N.
                                f}hTJQ         Find all cards with suit first.
                               |      XNK_@NK  If there aren't any, flip a card.

1

R177171字节

function(l=1,F="(.)(.)",R="\\2\\1",S=sample)if(l>1)sub(F,R,grep("^[SDHC]",l,v=T))else{m=S(outer(c(2:9,"T","J","Q","K"),c("S","D","H","C"),paste0))
m[1]=sub(F,R,m[1])
S(m)}

在线尝试!

给定空输入(f无输入的调用),我们默认使用l=1,从而创建m牌组的随机排列。假设sample确实是随机的,则任何一张卡在此列表中的可能性均等。因此,我们修改第一个,然后再次随机播放,返回列表。

反转它,我们寻找以开头的卡,SDHC然后反转它。


1

Python 2,135个字节

from random import*
s=shuffle
d=zip('A23456789TJQK'*4,'SCDH'*13)
s(d)
D=input()
if D:d=list(set(D)-set(d))
d[0]=d[0][::-1]
s(d)
print d

在线尝试!

卡是元组 (value,suit)

空输入为 []

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.