ต้องการเห็น Magic Card Trick ไหม?


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]

The Shuffling

จากนั้นหลังจากการสับ:

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

นี่เป็นเอาต์พุตที่ถูกต้องที่ให้อินพุตว่าง

อินพุตเด็ค

แต่ตรงกันข้ามเมื่อโปรแกรมของเราได้รับการส่งออกดังกล่าวข้างต้นเป็น input 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 การ์ดที่กลับด้านเป็นอินพุตควรส่งผลให้การ์ดที่กลับด้าน
  • ปัจจัยการผลิตอื่น ๆ อาจส่งผลให้ลามะระเบิดขี่ segways ผ่านหลอดอนาคต
    • หรือสิ่งอื่นใดสำหรับเรื่องนั้น
  • ทั้งการ์ดที่เลือกและคำสั่งสับจะต้องสุ่มอย่างสม่ำเสมอ
    • IE การ์ดทั้งหมดมีโอกาสเท่ากันที่จะถูกเลือกให้กลับรายการ
    • IE การ์ดทั้งหมดที่มีโอกาสปรากฏเท่ากัน
  • คุณสามารถใช้SHCDหรือshcdสำหรับชุดสูท แต่ต้องสอดคล้อง:
    • หากคุณเลือกชุดตัวพิมพ์ใหญ่ ( SHCD) คุณต้องใช้TJQKAด้วย
    • หากคุณเลือกชุดตัวพิมพ์เล็ก ( shcd) คุณต้องใช้tjqkaด้วย
  • นี่คือผู้ชนะคือไบต์ต่ำสุด

2
@ labela - gotoa มี FAR หลายรูปแบบมากเกินไป ฉันจำพ่อของฉันทำให้ฉันลืมใจโดยใช้บัตรสมมาตรในแนวตั้งและใช้กลอุบายที่แตกต่างกัน แต่ทำให้ฉันคิดว่ามันเป็นแบบนี้
Magic Octopus Urn

13
"ลามะระเบิดได้ขี่เซกเวย์ผ่านท่อแห่งอนาคต" - ฉันรอคอยที่จะท้าทายศิลปะ ASCII ต่อไปของคุณ ...
Level River St

3
การหมุนสำรับทั้งหมดโดยการสุ่มออฟเซ็ตจาก 0 ถึง 51 เป็นไปตามเงื่อนไขที่ว่า "ไพ่ทุกใบมีโอกาสเท่ากันที่จะปรากฏที่ใดก็ได้ในสำรับที่สับ" แต่อาจไม่ถือว่าเป็นการสับแบบสุ่ม คุณหมายความว่าคำสั่งซื้อ (52!) ทั้งหมดมีแนวโน้มที่เท่ากันหรือไม่?
aschepler

1
เพียงเพื่อขยายสิ่งที่ @aschepler กล่าว: ด้วยระยะเวลาของ PRNG เริ่มต้นในหลาย ๆ ภาษาส่วนใหญ่เป็น 52! shuffles ที่เป็นไปได้มีความน่าจะเป็นที่ปรากฏขึ้นเท่ากับศูนย์ (แม้ว่ามันอาจจะดีขึ้นหรือแย่ลงขึ้นอยู่กับอัลกอริทึมการสับ)
Arnauld

1
ลามะไลลาเป็นรูปแกะสลักบนดอลลี่หรือไม่? ฉันออกจากเซกเวย์และวัตถุระเบิด แต่ฉันมีลูกกวาดหนอน ... i.imgur.com/gEkVR5P.gif
Tschallacka

คำตอบ:


7

Retina , 61 60 59 ไบต์

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

ลองออนไลน์! แก้ไข: บันทึกแล้ว1 2 ไบต์ขอบคุณ @MartinEnder คำอธิบาย:

G`[HCDS].

ลบการ์ดที่ไม่ได้กลับมาทั้งหมด ควรทิ้งการ์ดที่กลับด้านหนึ่งใบหรือไม่มีการ์ด

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

หากการป้อนข้อมูลว่างเปล่า (ตอนนี้) สร้างการ์ดแพ็ค

@V`

สุ่มเลือกไพ่หนึ่งใบแล้วย้อนกลับ

O?`

สุ่มการ์ด


4

05AB1E , 29 ไบต์

Y9ŸJ.•§®т•«.•öB•âsKDgiëDΩÂ:.r

ลองออนไลน์!


. •Āk {? Öw•9LJì # `จะประหยัดไม่กี่ไบต์ในการบีบอัดทั้งสองเข้าด้วยกัน
Magic Octopus Urn

@MagicOctopusUrn: หลังจากลบ 1 และ 2 นั่นจะกลายเป็น bytecount เดียวกันใช่ไหม?
Emigna


@MagicOctopusUrn: น่าเสียดายที่ไม่ใช่ คุณมีทั้งใน1และที่aนั่น
Emigna

ปล่อยให้ฉันไปตีความผิดY9ŸJเป็น9LJ
เมจิกปลาหมึกโกศ

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

> <> , 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 ยอมรับรายการของอักขระ (stub ของ 0 การ์ดหรือเต็มสำรับ 52 ใบพร้อมกับไพ่หนึ่งใบที่กลับด้าน) และส่งคืนรายการของอักขระ (stub ของไพ่ 1 ใบที่กลับด้าน แต่เต็มไปข้างหน้าหรือเต็ม - ตรวจสอบด้วยการสุ่มการ์ดหนึ่งอันที่ตรงกันข้าม)

ลองออนไลน์! (ส่วนท้ายเพื่อให้การแทนค่าอินพุตและเอาต์พุตตรงกัน - ในฐานะโปรแกรมเต็มรูปแบบของรหัสเยลลี่ 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(บางทีฉันสามารถแก้ไขสำหรับศูนย์ไบต์แทน) แต่จะต้องทำมันในภายหลัง ...
โจนาธานอัลลัน

เนื่องจากนี่เป็นฟังก์ชั่นฉันไม่แน่ใจว่าคุณสามารถส่งคืน[[number, suit]]แทนที่จะ[number, suit]แสดงการ์ดเดียวเมื่ออินพุตไม่ว่างเปล่า
Erik the Outgolfer

นอกจากนี้ไม่ฉันไม่คิดว่ามีการแก้ไข 0 ไบต์สำหรับสิ่งนั้น
Erik the Outgolfer

@EriktheOutgolfer ฉันไม่เห็นเหตุผลที่ไม่เป็นเช่นนั้นการ์ดเหงาคือต้นขั้ว (ไพ่สั้น) เพียงใบเดียว
Jonathan Allan

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

R , 177 171 ไบต์

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และย้อนกลับ


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.