Task: Perfect shuffle




Go: package main

import "fmt"

type Deck struct {
	Cards []int
	length int
}

func NewDeck(deckSize int) (res *Deck){
	if deckSize % 2 != 0{
		panic("Deck size must be even")
	}
	res = new(Deck)
	res.Cards = make([]int, deckSize)
	res.length = deckSize
	for i,_ := range  res.Cards{
		res.Cards[i] = i
	}
	return
}
func (d *Deck)shuffleDeck(){
	tmp := make([]int,d.length)
	for i := 0;i <d.length/2;i++  {
		tmp[i*2] = d.Cards[i]
		tmp[i*2+1] = d.Cards[d.length / 2 + i]
	}
	d.Cards = tmp
}
func (d *Deck) isEqualTo(c Deck) (res bool) {
	if d.length != c.length {
		panic("Decks aren't equally sized")
	}
	res = true
	for i, v := range d.Cards{
		if v != c.Cards[i] {
			res = false
		}
	}
	return
}


func main(){
	for _,v := range []int{8,24,52,100,1020,1024,10000} {
		fmt.Printf("Cards count: %d, shuffles required: %d\n",v,ShufflesRequired(v))
	}
}

func ShufflesRequired(deckSize int)(res int){
	deck := NewDeck(deckSize)
	Ref := *deck
	deck.shuffleDeck()
	res++
	for ;!deck.isEqualTo(Ref);deck.shuffleDeck(){
		res++
	}
	return
}







Fortran: MODULE PERFECT_SHUFFLE
     IMPLICIT NONE

     CONTAINS

     
     FUNCTION SHUFFLE(NUM_ARR)
          INTEGER, DIMENSION(:), INTENT(IN) :: NUM_ARR
          INTEGER, DIMENSION(SIZE(NUM_ARR)) :: SHUFFLE
          INTEGER :: I, IDX

          IF (MOD(SIZE(NUM_ARR), 2) .NE. 0) THEN
              WRITE(*,*) "ERROR: SIZE OF DECK MUST BE EVEN NUMBER"
              CALL EXIT(1)
          END IF

          IDX = 1

          DO I=1, SIZE(NUM_ARR)/2
              SHUFFLE(IDX) = NUM_ARR(I)
              SHUFFLE(IDX+1) = NUM_ARR(SIZE(NUM_ARR)/2+I)
              IDX = IDX + 2
          END DO

    END FUNCTION SHUFFLE

    
    FUNCTION COMPARE_ARRAYS(ARRAY_1, ARRAY_2)
        INTEGER, DIMENSION(:) :: ARRAY_1, ARRAY_2
        LOGICAL :: COMPARE_ARRAYS
        INTEGER :: I

        DO I=1,SIZE(ARRAY_1)
            IF (ARRAY_1(I) .NE. ARRAY_2(I)) THEN
                COMPARE_ARRAYS = .FALSE.
                RETURN
            END IF
        END DO

        COMPARE_ARRAYS = .TRUE.
    END FUNCTION COMPARE_ARRAYS

    
    FUNCTION GEN_DECK(DECK_SIZE)
        INTEGER, INTENT(IN) :: DECK_SIZE
        INTEGER, DIMENSION(DECK_SIZE) :: GEN_DECK
        INTEGER :: I

        GEN_DECK = (/(I, I=1,DECK_SIZE)/)
    END FUNCTION GEN_DECK
END MODULE PERFECT_SHUFFLE



PROGRAM DEMO_PERFECT_SHUFFLE
    USE PERFECT_SHUFFLE
    IMPLICIT NONE

    INTEGER, PARAMETER, DIMENSION(7) :: DECK_SIZES = (/8, 24, 52, 100, 1020, 1024, 10000/)
    INTEGER, DIMENSION(:), ALLOCATABLE :: DECK, SHUFFLED
    INTEGER :: I, COUNTER

    WRITE(*,'(A, A, A)') "input (deck size)", " | ", "output (number of shuffles required)"
    WRITE(*,*) REPEAT("-", 55)

    DO I=1, SIZE(DECK_SIZES)
        IF (I .GT. 1) THEN
            DEALLOCATE(DECK)
            DEALLOCATE(SHUFFLED)
        END IF
        ALLOCATE(DECK(DECK_SIZES(I)))
        ALLOCATE(SHUFFLED(DECK_SIZES(I)))
        DECK = GEN_DECK(DECK_SIZES(I))
        SHUFFLED = SHUFFLE(DECK)
        COUNTER = 1
        DO WHILE (.NOT. COMPARE_ARRAYS(DECK, SHUFFLED))
            SHUFFLED = SHUFFLE(SHUFFLED)
            COUNTER = COUNTER + 1
        END DO

        WRITE(*,'(I17, A, I35)') DECK_SIZES(I), " | ", COUNTER
   END DO
END PROGRAM DEMO_PERFECT_SHUFFLE