Task: Card shuffles



C#: using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CardShuffles {
    public static class Helper {
        public static string AsString<T>(this ICollection<T> c) {
            StringBuilder sb = new StringBuilder("[");
            sb.Append(string.Join(", ", c));
            return sb.Append("]").ToString();
        }
    }

    class Program {
        private static Random rand = new Random();

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

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

                
                List<T> left = new List<T>(newList.Take(cutPoint));
                List<T> right = new List<T>(newList.Skip(cutPoint));

                newList.Clear();

                while (left.Count > 0 && right.Count > 0) {
                    
                    
                    
                    if (rand.NextDouble() >= ((double)left.Count / right.Count) / 2) {
                        newList.Add(right.First());
                        right.RemoveAt(0);
                    }
                    else {
                        newList.Add(left.First());
                        left.RemoveAt(0);
                    }
                }

                
                if (left.Count > 0) newList.AddRange(left);
                if (right.Count > 0) newList.AddRange(right);
            }

            return newList;
        }

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

            for (int n = 0; n < passes; n++) {
                List<T> otherHand = new List<T>();

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

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

                    
                    for (int i = 0; i < cutSize && mainHand.Count > 0; i++) {
                        temp.Add(mainHand.First());
                        mainHand.RemoveAt(0);
                    }

                    
                    if (rand.NextDouble()>=0.1) {
                        
                        temp.AddRange(otherHand);
                        otherHand = temp;
                    }
                    else {
                        
                        otherHand.AddRange(temp);
                    }
                }

                
                mainHand = otherHand;
            }

            return mainHand;
        }

        static void Main(string[] args) {
            List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
            Console.WriteLine(list.AsString());
            list = riffleShuffle(list, 10);
            Console.WriteLine(list.AsString());
            Console.WriteLine();

            list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
            Console.WriteLine(list.AsString());
            list = riffleShuffle(list, 1);
            Console.WriteLine(list.AsString());
            Console.WriteLine();

            list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
            Console.WriteLine(list.AsString());
            list = overhandShuffle(list, 10);
            Console.WriteLine(list.AsString());
            Console.WriteLine();

            list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
            Console.WriteLine(list.AsString());
            list = overhandShuffle(list, 1);
            Console.WriteLine(list.AsString());
            Console.WriteLine();
        }
    }
}






VB: Imports System.Runtime.CompilerServices
Imports System.Text

Module Module1

    <Extension()>
    Function AsString(Of T)(c As ICollection(Of T)) As String
        Dim sb = New StringBuilder("[")
        sb.Append(String.Join(", ", c))
        Return sb.Append("]").ToString()
    End Function

    Private rand As New Random()

    Function RiffleShuffle(Of T)(list As ICollection(Of T), flips As Integer) As List(Of T)
        Dim newList As New List(Of T)(list)

        For n = 1 To flips
            
            Dim cutPoint As Integer = newList.Count / 2 + If(rand.Next(0, 2) = 0, -1, 1) * rand.Next(newList.Count * 0.1)

            
            Dim left As New List(Of T)(newList.Take(cutPoint))
            Dim right As New List(Of T)(newList.Skip(cutPoint))

            newList.Clear()

            While left.Count > 0 AndAlso right.Count > 0
                
                
                
                If rand.NextDouble() >= left.Count / right.Count / 2 Then
                    newList.Add(right.First())
                    right.RemoveAt(0)
                Else
                    newList.Add(left.First())
                    left.RemoveAt(0)
                End If
            End While

            
            If left.Count > 0 Then
                newList.AddRange(left)
            End If
            If right.Count > 0 Then
                newList.AddRange(right)
            End If
        Next

        Return newList
    End Function

    Function OverhandShuffle(Of T)(list As ICollection(Of T), passes As Integer) As List(Of T)
        Dim mainHand As New List(Of T)(list)

        For n = 1 To passes
            Dim otherhand = New List(Of T)

            While mainHand.Count > 0
                
                Dim cutSize = rand.Next(list.Count * 0.2) + 1

                Dim temp = New List(Of T)

                
                Dim i = 0
                While i < cutSize AndAlso mainHand.Count > 0
                    temp.Add(mainHand.First())
                    mainHand.RemoveAt(0)
                    i = i + 1
                End While

                
                If rand.NextDouble() >= 0.1 Then
                    
                    temp.AddRange(otherhand)
                    otherhand = temp
                Else
                    
                    otherhand.AddRange(temp)
                End If
            End While

            
            mainHand = otherhand
        Next

        Return mainHand
    End Function

    Sub Main()
        Dim list = New List(Of Integer)(Enumerable.Range(1, 20))
        Console.WriteLine(list.AsString())
        list = RiffleShuffle(list, 10)
        Console.WriteLine(list.AsString())
        Console.WriteLine()

        list = New List(Of Integer)(Enumerable.Range(1, 20))
        Console.WriteLine(list.AsString())
        list = RiffleShuffle(list, 1)
        Console.WriteLine(list.AsString())
        Console.WriteLine()

        list = New List(Of Integer)(Enumerable.Range(1, 20))
        Console.WriteLine(list.AsString())
        list = OverhandShuffle(list, 10)
        Console.WriteLine(list.AsString())
        Console.WriteLine()

        list = New List(Of Integer)(Enumerable.Range(1, 20))
        Console.WriteLine(list.AsString())
        list = OverhandShuffle(list, 1)
        Console.WriteLine(list.AsString())
        Console.WriteLine()
    End Sub

End Module