A perfect shuffle (or faro/weave shuffle) means splitting a deck of cards into equal halves, and perfectly interleaving them - so that you end up with the first card from the left half, followed by the first card from the right half, and so on:



 7♠ 8♠ 9♠ J♠ Q♠ K♠→7♠  8♠  9♠
  J♠  Q♠  K♠→7♠ J♠ 8♠ Q♠ 9♠ K♠


When you repeatedly perform perfect shuffles on an even-sized deck of unique cards, it will at some point arrive back at its original order. How many shuffles this takes, depends solely on the number of cards in the deck - for example for a deck of eight cards it takes three shuffles:





 original: 

1
2
3
4
5
6
7
8



 after 1st shuffle: 

1
5
2
6
3
7
4
8



 after 2nd shuffle: 

1
3
5
7
2
4
6
8



 after 3rd shuffle: 

1
2
3
4
5
6
7
8




The Task
 Write a function that can perform a perfect shuffle on an even-sized list of values.
 Call this function repeatedly to count how many shuffles are needed to get a deck back to its original order, for each of the deck sizes listed under "Test Cases" below.
 You can use a list of numbers (or anything else that's convenient) to represent a deck; just make sure that all "cards" are unique within each deck.
 Print out the resulting shuffle counts, to demonstrate that your program passes the test-cases.
Test Cases


 input (deck size) 
 output (number of shuffles required)


 8 
 3


 24 
 11


 52 
 8


 100 
 30


 1020 
 1018


 1024 
 10


 10000 
 300



 
program Perfect_shuffle;
 
{$APPTYPE CONSOLE}
 
uses
  System.SysUtils;
 
type
  TDeck = record
    Cards: TArray<Integer>;
    Len: Integer;
    constructor Create(deckSize: Integer); overload;
    constructor Create(deck: TDeck); overload;
    procedure shuffleDeck();
    class operator Equal(a, b: TDeck): boolean;
    function ShufflesRequired: Integer;
    procedure Assign(a: TDeck);
  end;
 
{ TDeck }
 
procedure TDeck.Assign(a: TDeck);
begin
  Len := a.Len;
  Cards := copy(a.Cards, 0, len);
end;
 
constructor TDeck.Create(deckSize: Integer);
begin
  if deckSize < 1 then
    raise Exception.Create('Error: Deck size must have above zero');
 
  if Odd(deckSize) then
    raise Exception.Create('Error: Deck size must be even');
 
  SetLength(Cards, deckSize);
  Len := deckSize;
 
  for var i := 0 to High(Cards) do
    Cards[i] := i;
end;
 
constructor TDeck.Create(deck: TDeck);
begin
  Assign(deck);
end;
 
class operator TDeck.Equal(a, b: TDeck): boolean;
begin
  if a.len <> b.len then
    raise Exception.Create('Error: Decks aren''t equally sized');
 
  if a.Len = 0 then
    exit(True);
 
  for var i := 0 to a.Len - 1 do
    if a.Cards[i] <> b.Cards[i] then
      exit(False);
 
  Result := True;
end;
 
procedure TDeck.shuffleDeck;
var
  tmp: TArray<Integer>;
begin
  SetLength(tmp, len);
  for var i := 0 to len div 2 - 1 do
  begin
    tmp[i * 2] := Cards[i];
    tmp[i * 2 + 1] := Cards[len div 2 + i];
  end;
  Cards := copy(tmp, 0, len);
end;
 
function TDeck.ShufflesRequired: Integer;
var
  ref: TDeck;
begin
  Result := 1;
  ref := TDeck.Create(self);
  shuffleDeck;
  while not (self = ref) do
  begin
    shuffleDeck;
    inc(Result);
  end;
end;
 
const
  cases: TArray<Integer> = [8, 24, 52, 100, 1020, 1024, 10000];
 
begin
  for var size in cases do
  begin
    var deck := TDeck.Create(size);
    writeln(format('Cards count: %d, shuffles required: %d', [size, deck.ShufflesRequired]));
  end;
  readln;
end.