यादृच्छिक इनपुट का उपयोग करके एक फेरबदल डेक आउटपुट


9

इनपुट आउटपुट:

इनपुट : एक समान रूप से यादृच्छिक, असीम रूप से लंबा, '0' और '1' का तार, जिसे स्टड से लिया गया है। स्ट्रिंग को सही मायने में यादृच्छिक माना जाता है, न कि छद्म यादृच्छिक। यह समान है कि प्रत्येक वर्ण समान रूप से '0' या '1' होने की संभावना है।

सावधान! इनपुट अनंत रूप से लंबा है, इसलिए आप अजगर में कच्चे_input () जैसे फ़ंक्शन का उपयोग करके मेमोरी में यह सब स्टोर नहीं कर सकते। यदि मैं गलत नहीं हूं, तो गोल्फस्क्रिप्ट अनंत इनपुट के साथ विफल हो जाएगा, क्योंकि यह चलने से पहले स्टैक पर पूरे इनपुट को धक्का देता है।

आउटपुट : जोकर के बिना एक समान रूप से यादृच्छिक फेरबदल मानक डेक। यह समान है कि सभी आदेश समान रूप से होने की संभावना है।

आउटपुट में प्रत्येक कार्ड यह रैंक, ए, 2-9, टी, जे, क्यू या के है, यह सूट, सी, डी, एच या एस के साथ है। उदाहरण के लिए, हुकुम का 10 हैTs

डेक के कार्ड को रिक्त स्थान द्वारा अलग किया जाना चाहिए।

आप अंतर्निहित रैंडम लाइब्रेरी या फ़ंक्शंस का उपयोग नहीं कर सकते क्योंकि वे वास्तव में यादृच्छिक नहीं हैं, केवल छद्म यादृच्छिक हैं।

उदाहरण इनपुट

आप अपने प्रोग्राम में इनपुट करने के लिए निम्न पायथन लिपि का उपयोग कर सकते हैं:

import sys, random
try:
    while True:
        sys.stdout.write(str(random.randint(0,1)))
except IOError:
    pass

यदि आप स्क्रिप्ट को rand.py के रूप में सहेजते हैं, तो अपने प्रोग्राम का परीक्षण करें python rand.py | your_program

अजगर 3 में यह अपेक्षा के अनुसार चलता है, लेकिन अजगर 2.7 में मुझे अपने प्रोग्राम के आउटपुट के बाद एक त्रुटि संदेश मिलता है, लेकिन सब कुछ पूरा होने के बाद, इसलिए केवल त्रुटि संदेश को अनदेखा करें।

उदाहरण आउटपुट:

यहां बताया गया है कि अगर छंटनी क्रम में फेरबदल किया जाना हो तो डेक को कैसे प्रिंट किया जाना चाहिए:

Ac 2c 3c 4c 5c 6c 7c 8c 9c Tc Jc Qc Kc Ad 2d 3d 4d 5d 6d 7d 8d 9d Td Jd Qd Kd Ah 2h 3h 4h 5h 6h 7h 8h 9h Th Jh Qh Kh As 2s 3s 4s 5s 6s 7s 8s 9s Ts Js Qs Ks

स्कोरिंग:

यह एक कोड गोल्फ है। सबसे छोटा कोड जीतता है।

उदाहरण कार्यक्रम:

यहां एक अजगर 2.7 समाधान है, न कि गोल्फ।

import sys
def next():
    return int(sys.stdin.read(1))==1
def roll(n):
    if n==1:
        return 0
    if n%2==0:
        r=roll(n/2)
        if next():
            r+=n/2
        return r
    else:
        r=n
        while(r==n):
            r=roll(n+1)
        return r
deck = [rank+suit for suit in 'cdhs' for rank in 'A23456789TJQK']
while len(deck)>0:
    print deck.pop(roll(len(deck))),

3
"अगर मैं गलत नहीं हूं, तो गोल्फस्क्रिप्ट अनंत इनपुट के साथ विफल हो जाएगा, क्योंकि यह चलने से पहले स्टैक पर पूरे इनपुट को धक्का देता है।" खैर, यह एक तरीका है इसे चलाने का।
dmckee --- पूर्व-मध्यस्थ ने बिल्ली का बच्चा

मैं थोड़ा उलझन में हूं, मुझे माफ कर दो। इनपुट का वास्तविक डेक फेरबदल के साथ क्या करना है? शायद मुझे बस थोड़ा स्पष्टीकरण चाहिए।
17st में jdstankosky

1
आप अपने कोड में छद्म यादृच्छिक कार्यों का उपयोग नहीं कर सकते हैं, इसलिए आपको यादृच्छिकता उत्पन्न करने के लिए इनपुट (जिसे हम सही मायने में यादृच्छिक मान रहे हैं ) का उपयोग करने की आवश्यकता है। उदाहरण के लिए, अजगर में आप एक यादृच्छिक बूलियन प्राप्त करने के लिए (sys.stdin.read (1) == '1') का उपयोग कर सकते हैं, लेकिन आप (random.randint (0,1) == 1) का उपयोग नहीं कर सकते, क्योंकि यह केवल छद्म यादृच्छिक है।
कार्डबोर्ड_बॉक्स

जवाबों:


7

रूबी, 89 87 वर्ण

l=*0..51;l.map{l-=[i=l[gets(6).to_i 2]||redo];$><<'A23456789TJQK'[i/4]+'cdhs'[i%4]+' '}

संपादित करें: पिछला संस्करण

l=*0..51;(l-=[i=l[gets(6).to_i 2]];i&&$><<'A23456789TJQK'[i/4]+'cdhs'[i%4]+' ')while l[0]

3

पायथन 122

import sys
D=[R+S for S in'cdhs'for R in'A23456789TJQK']
while(D):
    x=int(sys.stdin.read(6),2)
    if x<len(D):print D.pop(x)

स्पष्टीकरण:

अप्रयुक्त कार्ड डी में संग्रहीत किए जाते हैं। यह बस इनपुट स्ट्रीम से अगला वैध यादृच्छिक सूचकांक प्राप्त करता है और डी से उस तत्व को पॉप करता है।

जब तक मुझे कुछ याद नहीं आ रहा है, तब तक पूर्वाग्रह नहीं होना चाहिए। स्क्रिप्ट किसी भी अमान्य सूचक> को बाहर फेंक देगी len(D), लेकिन इससे कम संख्या के लिए पूर्वाग्रह नहीं होता है क्योंकि प्रत्येक क्रमिक पॉप प्रत्येक तत्व के सूचकांक को i से कम कर देगा।


तो आप अधिकांश (अनंत) यादृच्छिक इनपुट को त्याग देते हैं? यानी आपके पास एक बार "अप्रयुक्त" कार्ड नहीं होने से आप फेरबदल करना बंद कर देंगे?
Leigh

3

पर्ल, 80 वर्ण

यहाँ एक और कार्यान्वयन है जो पूर्वाग्रह से ग्रस्त नहीं है और दो वर्णों से छोटा है:

$/=1x9;$_=A23456789TJQK;s/./$&s$&c$&d$&h/g;%h=map{<>.$_,"$_ "}/../g;say values%h

पुराना कार्यान्वयन (82 वर्ण):

$/=1x9;$_=A23456789TJQK;s/./$&s$&c$&d$&h/g;say map/..$/&&$&.$",sort map<>.$_,/../g

पुराना कार्यान्वयन विवरण:

# set input record separator (how internal readline() delimits lines) to "11111111"
$/ = 1x9; 

# constructs a string representation of all 52 cards: "AsAc(...)KdKh"
$_ = A23456789TJQK; s/./$&s$&c$&d$&h/g;

# for each pair of characters (each card) in the string $_
foreach $card (/../g)
{
    # read from STDIN until $/ is found (this may NEVER occur!), which
    # results in a random string of 1s and 0s
    $weight = <>; 

    # append the card identifier onto the random string
    $card = $weight . $card;

    # add this new card identifier to a new list
    push @cards, $card;
}

# sort the cards with their random string prefix
sort @cards;

# for each card in the "randomly sorted" list
foreach $card (@cards)
{
    # capture the final two characters from the card (the rank and suit), 
    # and append a space onto them
    $card =~ /..$/;  
    $card = $card . $";

    print $card;
}

बस जिज्ञासु: क्या कोई दिखा सकता है कि यह दृष्टिकोण कार्ड के प्रत्येक डेक को एक ही संभावना के साथ पैदा करता है?
हॉवर्ड

2
यदि मैं यह सही (IANAPH) पढ़ रहा हूं, तो यह प्रत्येक कार्ड को यादृच्छिक 'वेट' प्रदान करता है, और फिर वजन के आधार पर छांटता है। जब दो कार्डों को एक ही भार सौंपा जाता है, तो उन्हें क्रम से छोड़ दिया जाएगा sort, जिसके परिणामस्वरूप अल्फ़ाबेटिक ऑर्डरिंग के लिए पूर्वाग्रह हो जाएगा।
बूंदी

आप सही कह रहे हैं, @boothby। सॉर्ट इस समाधान को एक पूर्वाग्रह के साथ छोड़ देता है कि मामले में कई कार्डों में समान "वजन" होता है। यह भी गारंटी नहीं दी जा सकती है कि यह समाधान कभी भी परिणाम देगा। मैं इसका वर्णन करता हूं कि यह कैसे काम करता है ताकि कोई मुझसे अधिक होशियार हो इसका विश्लेषण कर सके
ardnew

यह पूरी तरह से ठीक है अगर कुछ इनपुट प्रोग्राम को कभी समाप्त नहीं करते हैं, तो जब तक कि संभावना 1 को समाप्त कर देती है, जब तक कि समय अनंत तक पहुंच जाता है। उदाहरण कार्यक्रम कभी भी सभी 1 'के इनपुट पर समाप्त नहीं होता है। मुझे पूरा यकीन है कि एक निश्चित संख्या में बिट्स पढ़ने के बाद आपके कार्यक्रम को समाप्त करते समय एकरूप यादृच्छिकता प्राप्त करना वास्तव में असंभव है।
कार्डबोर्ड_बॉक्स

1
आप बिट्स की परिमित संख्या के साथ 1 और 3 के बीच समान रूप से यादृच्छिक संख्या कैसे चुन सकते हैं? आपको यह करने की आवश्यकता होगी कि फिशर-येट्स फेरबदल के अंत में, और फैक्टरियल (52) 3 से विभाज्य है, इसलिए यह उसी समस्या को साझा करता है।
कार्डबोर्ड_बॉक्स

3

सी, 197 178 161 चार्ट

संपादित करें : एक नया यादृच्छिक फ़ंक्शन का उपयोग करना, जो बहुत कम है - एक 4-अंकीय पूर्णांक पढ़ता है sऔर उपयोग करता है s%64। केवल 0 और 1 से बना प्रत्येक 6-अंकीय दशमलव संख्या %64एक अद्वितीय परिणाम में परिणाम लेती है, इसलिए यादृच्छिकता अच्छी है।
यह दृष्टिकोण बहुत अधिक यादृच्छिक बिट्स का उपभोग करता है, लेकिन काफी कम है।

B[52],t,s,i=104;
r(){scanf("%6d",&s);s%=64;s>i&&r();}
main(){
    for(;i--;)B[i%52]=i<52
        ?r(),t=B[s],B[s]=B[i],printf("%c%c\n","23456789ATJQK"[t/4],"cdhs"[t%4]),t
        :i-52;
}

मूल तर्क सरल है - 0.751, फेरबदल (श्रेणी 0..x से दूसरे के साथ यादृच्छिक रूप से तत्व x को बदलें), प्रिंट स्वरूपित (n / 4 = रैंक, n% 4 = सूट) के साथ 52 ints की एक सरणी को आरंभीकृत करें। ।
एक लूप, जो 104 बार चलता है, आरंभीकरण (पहले 52 रन), फेरबदल और छपाई (अंतिम 52 रन) करता है।
यादृच्छिक संख्या खींचकर एक यादृच्छिक संख्या उत्पन्न की जाती है n, जब तक 1<<nकि कम से कम वांछित अधिकतम न हो। यदि परिणाम अधिकतम से अधिक है - फिर से प्रयास करें।


यह जटिल s>7?"ATJQK"[s-8]:s+50सरल से अधिक लंबा है "A23456789TJQK"[s]। दूसरा आप उपयोग कर सकते हैं t/4और t%4इसके बजाय t%13और t/13
हॉवर्ड

tआउटपुट करते समय अभी भी सरणी में वापस लाने की आवश्यकता नहीं है
l4m2

3

यूनिक्स खोल ~ 350

यह छोटा या सुंदर नहीं है, न ही यह कुशल है, हालांकि मैं सोच रहा था कि मानक यूनिक्स शैल उपयोगिताओं के साथ ऐसा करना कितना कठिन होगा।

यह उत्तर अनंत बाइनरी स्ट्रिंग को 6 बिट लंबाई में काटता है और केवल उन लोगों को चुनता है जो सही सीमा (1-52) में हैं, यहां अनंत द्विआधारी स्ट्रिंग को यूरेनियम और xxd द्वारा सिम्युलेटेड किया गया है:

</dev/urandom xxd -b | cut -d' ' -f2-7 | tr -d ' \n'

चॉपिंग और सिलेक्शन फोल्ड, सेड और bc के साथ किया जाता है:

random_source | {echo ibase=2; cat | fold -w6 | sed -r 's/^/if(/; s/([^\(]+)$/\1 <= 110100 \&\& \1 > 0) \1/'}

इससे लाइनें बनती हैं:

if(101010 <= 110100 && 101010 > 0) 101010

जिसे bc में निर्देशित किया जा सकता है।

संख्याओं की इस धारा से, डेक का क्रम इस तरह चुना जाता है (मैं zsh का उपयोग कर रहा हूं, लेकिन अधिकांश आधुनिक गोले इस के अनुकूल होने चाहिए):

deck=({1..52})
seq_of_numbers | while read n; do 
  if [[ -n $deck[n] ]]; then 
    echo $n; deck[n]=""
    [[ $deck[*] =~ "^ *$" ]] && break
  fi
done

यादृच्छिक संख्या क्रम को अब कार्ड नामों में बदलना होगा। जीएनयू समानांतर के साथ कार्ड नाम अनुक्रम आसानी से उत्पन्न होता है:

parallel echo '{2}{1}' ::: c d s h ::: A {2..9} T J Q K

पेस्ट के साथ पिछले दो कमांड से आउटपुट को संयोजित करना और संख्याओं पर छंटनी:

paste random_deck card_names | sort -n | cut -f2 | tr '\n' ' '

एक राक्षसी एक-लाइनर के रूप में पूरी बात (केवल zsh में परीक्षण):

paste \
  <(deck=({1..52}); \
    </dev/urandom xxd -b | cut -d' ' -f2-7 | tr -d ' \n' |
      {echo ibase=2; fold -w6 | sed -r 's/^/if(/; s/([^\(]+)$/\1 <= 110100 \&\& \1 > 0) \1/'} | 
      bc | 
      while read n; do 
        if [[ -n $deck[n] ]]; then 
          echo $n; deck[n]=""
          [[ -z ${${deck[*]}%% *} ]] && break
        fi
      done) \
  <(parallel echo '{2}{1}' ::: c d s h ::: A {2..9} T J Q K) | 
sort -n | cut -f2 | tr '\n' ' '

संपादित करें - जोड़ा बैश संस्करण

यहाँ एक संस्करण है जो बाश में काम करता है। मैंने इन-शेल को हटा दिया { }और सरणी इंडेक्स शून्य आधारित हैं। एरे खालीपन को पैरामीटर विस्तार के साथ जांचा जाता है, थोड़ा अधिक कुशल और ऊपर के उदाहरण में भी अपनाया जाता है।

paste \
  <(deck=($(seq 52)); \
    </dev/urandom xxd -b | cut -d' ' -f2-7 | tr -d ' \n' | 
      (echo ibase=2; fold -w6 | sed -r 's/^/if(/; s/([^\(]+)$/\1 <= 110100 \&\& \1 > 0) \1/') | 
        bc | 
        while read n; do 
          if [[ -n ${deck[n-1]} ]]; then 
            echo $n
            deck[n-1]=""
            [[ -z ${deck[*]%% *} ]] && break
          fi
        done \
  ) \
  <(parallel echo '{2}{1}' ::: c d s h ::: A {2..9} T J Q K) | 
sort -n | cut -f2 | tr '\n' ' '; echo

2

K & R c - 275

  • सीधे स्ट्रिंग शाब्दिक में v3 सूचकांक
  • v2 स्ट्रिंग्स का उपयोग करने के लिए टिप्पणियों में लूसर ड्रॉग से सुझाव और शेष charशाब्दिक को intशाब्दिक के साथ प्रतिस्थापित किया

golfed:

#define F for(i=52;--i;)
#define P putchar 
M=1<<9-1,i,j,k,t,v,s,a[52];r(){t=0,j=9;while(--j)t=t<<1|(getchar()==49);
return t;}main(){F a[i]=i;F{k=i+1;do{j=r();}while(j>M/k*k-1);j%=i;t=a[i];
a[i]=a[j];a[j]=t;}F{s=a[i]&3;v=a[i]>>2;P(v>7?"TJQKA"[v-8]:v+50);
P("cdhs"[s]);P(32);}}

यहां बहुत ज्यादा क्रूर बल है। मैं सिर्फ एक न्यूनतम RNG आउटपुट बनाने के लिए इनपुट से नौ बिट्स पढ़ता हूं, और एक चयन फेरबदल करने के लिए समान आउटपुट प्राप्त करने के लिए सामान्य रिड्रा-इफ-द-अप्रयुक्त-मान-पर-अंत मापांक में कमी करता हूं।

यह अन-गोल्‍ड वर्जन इस मायने में अलग है कि यह /dev/urandomवर्णित इनपुट फॉर्मेट के बजाय इनपुट से लेता है ।

#include <stdio.h>
M=1<<8-1, /* RANDMAX */
  i, j, k, /* counters */
  t, /* temporary for swapping, and accumulating */
  a[52]; /* the deck */
r(){ /* limited, low precision rand() that depends on a random stream
    of '0' and '1' from stdin */
  t=0,j=9;
  while(--j)t=t<<1|(getchar()&1);
  return t;
}
main(){
  for(i=52;--i;)a[i]=i;  /* initialize the deck */
  for(i=52;--i;){
    /*  printf("shuffling %d...\n",i); */
    k=i+1;
    do { /* draw *unifromly* with a a-unifrom generator */
      j=r(); 
      /* printf("\t j=0x%o\n",j); */
    }while(j>M/k*k-1); /* discard values we can't mod into evently */
    j%=i;
    t=a[i];a[i]=a[j];a[j]=t; /* swap */
  }
  for(i=52;--i;){ /* output the deck */
    j=a[i]&3;
    k=a[i]>>2;
    putchar(k>7?"TJQKA"[k-8]:k+'2');
    putchar("cdhs"[j]);
    putchar(' ');
  }
}

+1 मुझे बहुत कुछ सीखना है। BTW, क्यों नहीं "TJQKA"और "cdhs"?
लूसर ड्रॉ

ओह। सही। intरों। मैं समझ गया। सभी विराम चिह्नों को सहेजने के लिए अभी भी इसके लायक हो सकता है। यहां तक ​​कि एक पागल पेस्टी मैक्रो के charबाहर getcharऔर बाहर कारक हो सकता है putchar...
लूसर

1
मैक्रो सब्स्टीट्यूशन को बहुत अधिक लाभ प्राप्त करने की आवश्यकता है क्योंकि उन्हें #define N एक नई रेखा के साथ शुरू करना और समाप्त करना है जो एक चरित्र के रूप में गिना जाता है और यह 11 है, साथ ही बिट आप प्रतिस्थापित कर रहे हैं। कुछ या सभी चरित्र शाब्दिकों को अंतर शाब्दिक के साथ बदलने में निश्चित रूप से कुछ और चरित्र हैं, लेकिन यहां देर हो चुकी है ... शायद मैं इसे एक और समय करूंगा।
dmckee --- पूर्व-मध्यस्थ ने बिल्ली का बच्चा

@luserdroog Clearer अब अध्यक्षता कर रहा है। बेशक तार बेहतर हैं - हालांकि आपको प्रकार निर्दिष्ट करना होगा - क्योंकि वर्ण केवल छोटे पूर्णांक हैं। इसके अलावा मैं उन्हें जोड़ सकते हैं और ASCII प्रतिस्थापन एक बार में स्ट्रोक का एक गुच्छा मिलता है।
dmckee --- पूर्व-मध्यस्थ बिल्ली का बच्चा

0

PHP, 158 chars

स्क्रॉल ब्लॉक प्राप्त करने वाले कोड ब्लॉक को रोकने के लिए नई लिंक जोड़ी गई हैं, उन्हें सुरक्षित रूप से हटाया जा सकता है।

for($i=52,$x='shdcKQJT98765432A';$i--;$c[]=$x[4+$i%13].$x[$i/13]);
while(ord($i=fgetc(STDIN)))$c[$i]^=$c[$a]^=$c[$i]^=$c[$a=2+($a+++$i)%50];
die(join(' ',$c));

इससे पहले कि मैं एक जोड़ने के लिए कहा जाए <?php, यह जाने कि आप PHP को इस टैग के बिना काफी आसानी से उपयोग कर सकते हैं,cat golf.php | php -a

डी-गोल्फ और टिप्पणी:

// Abuse of the for construct to save a bit of space, and to make things more obscure looking in general.
for (
    // Card suit and number are reversed because we're using a decrementor to count
    // down from 52, instead of up to 52
    $i = 52,
    $x = 'shdcKQJT98765432A';
    // Condition AND per-loop decrement
    $i--;
    // Add a new element to the array comprising of $i mod 13 + 4 (to skip suit ids)
    // followed by simply $i divided by 13 to pick a suit id.
    $c[] =
        $x[4 + $i % 13] .
        $x[$i / 13]
);

while(

    // Assignment inside the condition, a single character from input.
    ord($i = fgetc(STDIN))
)
    // In-place swap. Shorter than using a single letter temporary variable.
    // This is the pseudo-random shuffle.
    $c[$i] ^=
    $c[$a] ^=
    $c[$i] ^=
    $c[
        // We use the input (0 or 1) to identify one of two swap locations at the
        // start of the array. The input is also added to an accumulator (to make
        // the increments "random") that represents a swap destination.
        $a = 2 + ($a++ + $i) % 50
    ];

// Dramatic way of doing "echo" in the same space.
die(
    join(' ', $c)
);

दो अपेक्षित त्रुटियाँ हैं, जो प्रोग्राम के आउटपुट को प्रभावित नहीं करती हैं।

पहला इसलिए $aकि आरंभिक नहीं है, लेकिन NULL 0 में परिवर्तित हो गया है और कार्यक्रम जारी है।

दूसरा कारण यह है कि चरित्र की धारा कहीं से एक नई रेखा प्राप्त करती प्रतीत होती है, भले ही वह आपूर्ति न हो (अच्छा ol 'PHP), और यह सरणी में एक अपरिभाषित सूचकांक है। यह इनपुट का अंतिम चरित्र है, और आउटपुट को प्रभावित नहीं करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.