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




Go: package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    
    var pack [52]byte
    for i := 0; i < 26; i++ {
        pack[i] = 'R'
        pack[26+i] = 'B'
    }
    rand.Seed(time.Now().UnixNano())
    rand.Shuffle(52, func(i, j int) {
        pack[i], pack[j] = pack[j], pack[i]
    })

    
    var red, black, discard []byte
    for i := 0; i < 51; i += 2 {
        switch pack[i] {
        case 'B':
            black = append(black, pack[i+1])
        case 'R':
            red = append(red, pack[i+1])
        }
        discard = append(discard, pack[i])
    }
    lr, lb, ld := len(red), len(black), len(discard)
    fmt.Println("After dealing the cards the state of the stacks is:")
    fmt.Printf("  Red    : %2d cards -> %c\n", lr, red)
    fmt.Printf("  Black  : %2d cards -> %c\n", lb, black)
    fmt.Printf("  Discard: %2d cards -> %c\n", ld, discard)

    
    min := lr
    if lb < min {
        min = lb
    }
    n := 1 + rand.Intn(min)
    rp := rand.Perm(lr)[:n]
    bp := rand.Perm(lb)[:n]
    fmt.Printf("\n%d card(s) are to be swapped.\n\n", n)
    fmt.Println("The respective zero-based indices of the cards(s) to be swapped are:")
    fmt.Printf("  Red    : %2d\n", rp)
    fmt.Printf("  Black  : %2d\n", bp)
    for i := 0; i < n; i++ {
        red[rp[i]], black[bp[i]] = black[bp[i]], red[rp[i]]
    }
    fmt.Println("\nAfter swapping, the state of the red and black stacks is:")
    fmt.Printf("  Red    : %c\n", red)
    fmt.Printf("  Black  : %c\n", black)

    
    
    rcount, bcount := 0, 0
    for _, c := range red {
        if c == 'R' {
            rcount++
        }
    }
    for _, c := range black {
        if c == 'B' {
            bcount++
        }
    }

    fmt.Println("\nThe number of red cards in the red stack     =", rcount)
    fmt.Println("The number of black cards in the black stack =", bcount)
    if rcount == bcount {
        fmt.Println("So the asssertion is correct!")
    } else {
        fmt.Println("So the asssertion is incorrect!")
    }
}