Task: Card shuffles




Go: package main

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

func reverse(s []int) {
    for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
        s[i], s[j] = s[j], s[i]
    }
}

func riffle(deck []int, iterations int) []int {
    le := len(deck)
    pile := make([]int, le)
    copy(pile, deck)
    for i := 0; i < iterations; i++ {
        mid := le / 2
        tenpc := mid / 10
        
        cut := mid - tenpc + rand.Intn(2*tenpc+1)
        
        deck1 := make([]int, cut)
        deck2 := make([]int, le-cut)
        copy(deck1, pile[:cut])
        copy(deck2, pile[cut:])
        pile = pile[:0]
        fromTop := rand.Intn(2) 
        for len(deck1) > 0 && len(deck2) > 0 {
            if fromTop == 1 {
                el1 := deck1[0]
                deck1 = deck1[1:]
                el2 := deck2[0]
                deck2 = deck2[1:]
                pile = append(pile, el1, el2)
            } else {
                el1 := deck1[len(deck1)-1]
                deck1 = deck1[:len(deck1)-1]
                el2 := deck2[len(deck2)-1]
                deck2 = deck2[:len(deck2)-1]
                pile = append(pile, el1, el2)
            }
        }
        
        if len(deck1) > 0 {
            pile = append(pile, deck1...)
        } else if len(deck2) > 0 {
            pile = append(pile, deck2...)
        }
        reverse(pile) 
    }
    return pile
}

func overhand(deck []int, iterations int) []int {
    le := len(deck)
    pile := make([]int, le)
    copy(pile, deck)
    pile2 := make([]int, 0)
    twentypc := le / 5
    for i := 0; i < iterations; i++ {
        for len(pile) > 0 {
            cards := 1 + rand.Intn(twentypc)
            if cards > len(pile) {
                cards = len(pile)
            }
            temp := make([]int, cards)
            copy(temp, pile[:cards])
            pile2 = append(temp, pile2...)
            pile = pile[cards:]
        }
        pile = append(pile, pile2...)
        pile2 = pile2[:0]
    }
    return pile
}

func main() {
    rand.Seed(time.Now().UnixNano())
    fmt.Println("Starting deck:")
    deck := make([]int, 20)
    for i := 0; i < 20; i++ {
        deck[i] = i + 1
    }
    fmt.Println(deck)
    const iterations = 10
    fmt.Println("\nRiffle shuffle with", iterations, "iterations:")
    fmt.Println(riffle(deck, iterations))
    fmt.Println("\nOverhand shuffle with", iterations, "iterations:")
    fmt.Println(overhand(deck, iterations))
    fmt.Println("\nStandard library shuffle with 1 iteration:")
    rand.Shuffle(len(deck), func(i, j int) {
        deck[i], deck[j] = deck[j], deck[i] 
    })
    fmt.Println(deck)
}


Java: import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

public class CardShuffles{

	private static final Random rand = new Random();

	public static <T> LinkedList<T> riffleShuffle(List<T> list, int flips){
		LinkedList<T> newList = new LinkedList<T>();

		newList.addAll(list);

		for(int n = 0; n < flips; n++){
			
			int cutPoint = newList.size() / 2 
				+ (rand.nextBoolean() ? -1 : 1 ) * rand.nextInt((int)(newList.size() * 0.1));

			
			List<T> left = new LinkedList<T>();
			left.addAll(newList.subList(0, cutPoint));
			List<T> right = new LinkedList<T>();
			right.addAll(newList.subList(cutPoint, newList.size()));

			newList.clear();

			while(left.size() > 0 && right.size() > 0){
				
				
				
				if(rand.nextDouble() >= ((double)left.size() / right.size()) / 2){
					newList.add(right.remove(0));
				}else{
					newList.add(left.remove(0));
				}
			}

			
			if(left.size() > 0) newList.addAll(left);
			if(right.size() > 0) newList.addAll(right);
		}
		return newList;
	}

	public static <T> LinkedList<T> overhandShuffle(List<T> list, int passes){
		LinkedList<T> mainHand = new LinkedList<T>();

		mainHand.addAll(list);
		for(int n = 0; n < passes; n++){
			LinkedList<T> otherHand = new LinkedList<T>();

			while(mainHand.size() > 0){
				
				int cutSize = rand.nextInt((int)(list.size() * 0.2)) + 1;

				LinkedList<T> temp = new LinkedList<T>();

				
				for(int i = 0; i < cutSize && mainHand.size() > 0; i++){
					temp.add(mainHand.remove());
				}

				
				if(rand.nextDouble()  >= 0.1){
					
					otherHand.addAll(0, temp);
				}else{
					
					otherHand.addAll(temp);
				}
			}

			
			mainHand = otherHand;
		}		
		return mainHand;
	}

	public static void main(String[] args){
		List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
		System.out.println(list);
		list = riffleShuffle(list, 10);
		System.out.println(list + "\n");

                list = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
		System.out.println(list);
		list = riffleShuffle(list, 1);
		System.out.println(list + "\n");

		list = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
		System.out.println(list);
		list = overhandShuffle(list, 10);
		System.out.println(list + "\n");

                list = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
		System.out.println(list);
		list = overhandShuffle(list, 1);
		System.out.println(list + "\n");

		list = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
		System.out.println(list);
		Collections.shuffle(list);
		System.out.println(list + "\n");
	}
}