Mind boggling card trick: Difference between revisions
Content added Content deleted
(Added Wren) |
Not a robot (talk | contribs) (Add C) |
||
Line 160: | Line 160: | ||
return |
return |
||
;==========================================================</lang> |
;==========================================================</lang> |
||
=={{header|C}}== |
|||
<lang C>#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <stdint.h> |
|||
#define SIM_N 5 /* Run 5 simulations */ |
|||
#define PRINT_DISCARDED 1 /* Whether or not to print the discard pile */ |
|||
#define min(x,y) ((x<y)?(x):(y)) |
|||
typedef uint8_t card_t; |
|||
/* Return a random number from an uniform distribution (0..n-1) */ |
|||
unsigned int rand_n(unsigned int n) { |
|||
unsigned int out, mask = 1; |
|||
/* Find how many bits to mask off */ |
|||
while (mask < n) mask = mask<<1 | 1; |
|||
/* Generate random number */ |
|||
do { |
|||
out = rand() & mask; |
|||
} while (out >= n); |
|||
return out; |
|||
} |
|||
/* Return a random card (0..51) from an uniform distribution */ |
|||
card_t rand_card() { |
|||
return rand_n(52); |
|||
} |
|||
/* Print a card */ |
|||
void print_card(card_t card) { |
|||
static char *suits = "HCDS"; /* hearts, clubs, diamonds and spades */ |
|||
static char *cards[] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"}; |
|||
printf(" %s%c", cards[card>>2], suits[card&3]); |
|||
} |
|||
/* Shuffle a pack */ |
|||
void shuffle(card_t *pack) { |
|||
int card; |
|||
card_t temp, randpos; |
|||
for (card=0; card<52; card++) { |
|||
randpos = rand_card(); |
|||
temp = pack[card]; |
|||
pack[card] = pack[randpos]; |
|||
pack[randpos] = temp; |
|||
} |
|||
} |
|||
/* Do the card trick, return whether cards match */ |
|||
int trick() { |
|||
card_t pack[52]; |
|||
card_t blacks[52/4], reds[52/4]; |
|||
card_t top, x, card; |
|||
int blackn=0, redn=0, blacksw=0, redsw=0, result; |
|||
/* Create and shuffle a pack */ |
|||
for (card=0; card<52; card++) pack[card] = card; |
|||
shuffle(pack); |
|||
/* Deal cards */ |
|||
#if PRINT_DISCARDED |
|||
printf("Discarded:"); /* Print the discard pile */ |
|||
#endif |
|||
for (card=0; card<52; card += 2) { |
|||
top = pack[card]; /* Take card */ |
|||
if (top & 1) { /* Add next card to black or red pile */ |
|||
blacks[blackn++] = pack[card+1]; |
|||
} else { |
|||
reds[redn++] = pack[card+1]; |
|||
} |
|||
#if PRINT_DISCARDED |
|||
print_card(top); /* Show which card is discarded */ |
|||
#endif |
|||
} |
|||
#if PRINT_DISCARDED |
|||
printf("\n"); |
|||
#endif |
|||
/* Swap an amount of cards */ |
|||
x = rand_n(min(blackn, redn)); |
|||
for (card=0; card<x; card++) { |
|||
/* Pick a random card from the black and red pile to swap */ |
|||
blacksw = rand_n(blackn); |
|||
redsw = rand_n(redn); |
|||
/* Swap them */ |
|||
top = blacks[blacksw]; |
|||
blacks[blacksw] = reds[redsw]; |
|||
reds[redsw] = top; |
|||
} |
|||
/* Verify the assertion */ |
|||
result = 0; |
|||
for (card=0; card<blackn; card++) |
|||
result += (blacks[card] & 1) == 1; |
|||
for (card=0; card<redn; card++) |
|||
result -= (reds[card] & 1) == 0; |
|||
result = !result; |
|||
printf("The number of black cards in the 'black' pile" |
|||
" %s the number of red cards in the 'red' pile.\n", |
|||
result? "equals" : "does not equal"); |
|||
return result; |
|||
} |
|||
int main() { |
|||
unsigned int seed, i, successes = 0; |
|||
FILE *r; |
|||
/* Seed the RNG with bytes from from /dev/urandom */ |
|||
if ((r = fopen("/dev/urandom", "r")) == NULL) { |
|||
fprintf(stderr, "cannot open /dev/urandom\n"); |
|||
return 255; |
|||
} |
|||
if (fread(&seed, sizeof(unsigned int), 1, r) != 1) { |
|||
fprintf(stderr, "failed to read from /dev/urandom\n"); |
|||
return 255; |
|||
} |
|||
fclose(r); |
|||
srand(seed); |
|||
/* Do simulations. */ |
|||
for (i=1; i<=SIM_N; i++) { |
|||
printf("Simulation %d\n", i); |
|||
successes += trick(); |
|||
printf("\n"); |
|||
} |
|||
printf("Result: %d successes out of %d simulations\n", |
|||
successes, SIM_N); |
|||
return 0; |
|||
}</lang> |
|||
{{out}} |
|||
<pre>Simulation 1 |
|||
Discarded: 10D 9S 7S KD 4S JS 6H 2D 2S 7H JH 5S AD AC 7D 5C 7C KH QD 4D 5H 2C 2H QS AH 3H |
|||
The number of black cards in the 'black' pile equals the number of red cards in the 'red' pile. |
|||
Simulation 2 |
|||
Discarded: AC 10D QC 4H 2D AD 8D 10C 9D 2C QS 3S JC KS 6S AS 2S 6C 6D 6H 3D 8C 2H QH 7D 5D |
|||
The number of black cards in the 'black' pile equals the number of red cards in the 'red' pile. |
|||
Simulation 3 |
|||
Discarded: 5D 2C JC 5C 5H 10D KD 4H KC 4S 8C 9S 6H 4D 2H 9H QS 10C 2S 3C AC 7H QD 7D JD 6S |
|||
The number of black cards in the 'black' pile equals the number of red cards in the 'red' pile. |
|||
Simulation 4 |
|||
Discarded: 6S 4C KS AD 4S QS 9C 7D JD AC KH 10S KD QD 3S 5C QH 9D 2H 5S QC KC 7C 3D 9S AH |
|||
The number of black cards in the 'black' pile equals the number of red cards in the 'red' pile. |
|||
Simulation 5 |
|||
Discarded: AD KH AC 8C 3C 5S KD QS 4C 2H 10C 2C JC 8D 6D JS 7C 4H 6H 6C 3S QC 6S KS 8H 7H |
|||
The number of black cards in the 'black' pile equals the number of red cards in the 'red' pile. |
|||
Result: 5 successes out of 5 simulations</pre> |
|||
=={{header|Crystal}}== |
=={{header|Crystal}}== |