Task: Mind boggling card trick

C: #include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define SIM_N           5  
#define PRINT_DISCARDED 1  

#define min(x,y) ((x<y)?(x):(y))

typedef uint8_t card_t;


unsigned int rand_n(unsigned int n) {
    unsigned int out, mask = 1;
    
    while (mask < n) mask = mask<<1 | 1;
    
    do {
        out = rand() & mask;
    } while (out >= n);
    return out;
}


card_t rand_card() {
    return rand_n(52);
}


void print_card(card_t card) {
    static char *suits = "HCDS"; 
    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]);
}


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;
    }
}


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;
   
    
    for (card=0; card<52; card++) pack[card] = card;
    shuffle(pack);
    
    
#if PRINT_DISCARDED
    printf("Discarded:"); 
#endif
    for (card=0; card<52; card += 2) {
        top = pack[card]; 
        if (top & 1) { 
            blacks[blackn++] = pack[card+1];
        } else {
            reds[redn++] = pack[card+1];
        }
#if PRINT_DISCARDED
        print_card(top); 
#endif
    }
#if PRINT_DISCARDED
    printf("\n");
#endif

    
    x = rand_n(min(blackn, redn));
    for (card=0; card<x; card++) {
        
        blacksw = rand_n(blackn);
        redsw = rand_n(redn); 
        
        top = blacks[blacksw];
        blacks[blacksw] = reds[redsw];
        reds[redsw] = top;
    }
    
    
    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;
    
    
    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);
    
    
    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;
}







Python: import random


n = 52
Black, Red = 'Black', 'Red'
blacks = [Black] * (n // 2) 
reds = [Red] * (n // 2)
pack = blacks + reds

random.shuffle(pack)


black_stack, red_stack, discard = [], [], []
while pack:
    top = pack.pop()
    if top == Black:
        black_stack.append(pack.pop())
    else:
        red_stack.append(pack.pop())
    discard.append(top)
print('(Discards:', ' '.join(d[0] for d in discard), ')\n')



max_swaps = min(len(black_stack), len(red_stack))

swap_count = random.randint(0, max_swaps)
print('Swapping', swap_count)

def random_partition(stack, count):
    "Partition the stack into 'count' randomly selected members and the rest"
    sample = random.sample(stack, count)
    rest = stack[::]
    for card in sample:
        rest.remove(card)
    return rest, sample

black_stack, black_swap = random_partition(black_stack, swap_count)
red_stack, red_swap = random_partition(red_stack, swap_count)


black_stack += red_swap
red_stack += black_swap


if black_stack.count(Black) == red_stack.count(Red):
    print('Yeha! The mathematicians assertion is correct.')
else:
    print('Whoops - The mathematicians (or my card manipulations) are flakey')