g | x | w | all
Bytes Lang Time Link
060250215T111908ZJoao-3
023Uiua250212T135153ZVen
007Vyxal 3240226T195114Zpacman25
068Perl 5 pa190311T220021ZXcali
070MATLAB210304T174420Zrobbie c
079Lua LuaJIT210117T184631ZLuaNoob
011Husk210117T090548ZRazetime
014Stax210117T090529ZRazetime
010Japt190311T113917ZShaggy
026J190311T202425ZGalen Iv
022APL Dyalog Unicode190311T125346ZVen
066PowerShell190318T050926Zmazzy
078PowerShell190317T210634ZAndrei O
018Pyth190311T152753ZVen
032Perl 6190311T135648Znwellnho
085R190313T104504ZVolare
044JavaScript ES6190311T113242ZArnauld
063C GCC190311T194447Zrtpax
045R190312T111909ZKirill L
072R190311T222829ZNick Ken
042Ruby190312T070645ZG B
039Python 2190311T113606ZErik the
032Perl 6190311T102952ZJo King
078Red190311T145900ZGalen Iv
008Jelly190311T104016ZJonathan
040Python 3190311T192243ZAlex
098APLNARS190311T160332Zuser5898
062Wolfram Language Mathematica190311T155342ZRainer G
059Java JDK190311T124040ZOlivier
00905AB1E legacy190311T102448ZEmigna

, 22 19 chars (67 60 bytes)

screenshot (sorry, my font is f***ed up in the screenshots, I'm a Windows user or something LOL)

🃌○←󷺹↨󰒼󷺹₀%2ᐸᴍ󷸺ᐸ⍟󷺹≡⟞󰒼

Run the tests here.

explanation The code runs a function to undo a riffle-shuffle, and does that until the array is sorted. Then, it gets the amount of iterations that whole process took. Due to the fact that it only cares about indices in the grouping, you can feed it both 0-indexed decks and 1-indexed decks.

Thanks to Ganer (the creator of the language) for -1 char (before I posted this).

Uiua, 23 bytes

F←|1 ⨬(+1F⊏⍏◿2°⊏|0◌)≍⊸⍆.

Explained:

F←|1 ⨬(+1F⊏⍏◿2°⊏|0◌)≍⊸⍆. # F is a |1.1 function (1 in, 1 out)
     ⨬(          |  )≍⊸⍆  # if the array is sorted
                  0◌     . # return 0 (and discard copied input)
               °⊏          # otherwise, generate 0..n
       +1F⊏⍏◿2             # mod 2
           ⍏               # grade (returns sorted indices)
          ⊏             .  # index into our original input, that's as shufflin'
       +1F                 # recurse and add 1 to the recursion count

Vyxal 3, 7 bytes

ϩUJiᶤᵞS

Try it Online!

ϩUJiᶤᵞS­⁡​‎‎⁡⁠⁡‏⁠⁠⁠‎⁡⁠⁤‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢‏⁠‎⁡⁠⁣‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏⁠‎⁡⁠⁢⁣‏‏​⁡⁠⁡‌­
ϩ  i     # ‎⁡Apply and collect until value is no longer unique, including initial value
 UJ      # ‎⁢Uninterleave and append
    ᶤᵞS  # ‎⁣first index where the list is sorted (invariant after sort)
💎

Created with the help of Luminespire.

Perl 5 -pa, 77 68 bytes

map{push@{$_%2},$_}0..$#F;++$\,@F=@F[@0,@1]while"@F"ne"@{[1..@F]}"}{

Try it online!

MATLAB, 70 bytes

function s(l),x=max(l);find(find(l==2)==1+mod(2.^(1:x),x-1))*(l(2)~=2)

explanation:

every nth shuffle, 2 will be pushed n^2 indices down from its previous position, wrapping around when it reaches the last position. That means that the function for index(n) is

1+mod(2^n,list-size-1)

for a list-size of 10, then, the indices are:

etc.

Using this, I find the index where 2 is, and find which power of 2 that is along the array. That power corresponds the the number of shuffles. To account for 0 shuffles, the whole thing is multiplied by the boolean value of l(2)~=2 to make sure that it returns 0 when 2 is in the right place, which only happens for an unshuffled array.

Lua (LuaJIT), 119 96 79 bytes

n=t;while 2~=n[2]do n={}for a=1,#t*2,2 do x=a-#t n[#n+1]=t[a]or t[x+x%2]end;t=n

Try it online!

Husk, 11 bytes

L↑S≠ŀ¡ȯΣTC2

Try it online!

Stax, 14 bytes

ü≈:☻‼Xí┌ùß♦▲▬á

Run and debug it

Japt, 13 11 10 bytes

Taking my shiny, new, very-work-in-progress interpreter for a test drive.

ÅÎÍ©ÒßUñÏu

Try it or run all test cases

ÅÎÍ©ÒßUñÏu     :Implicit input of integer array U
Å              :Slice the first element off U
 Î             :Get the first element
  Í            :Subtract from 2
   ©           :Logical AND with
    Ò          :  Negation of bitwise NOT of
     ß         :  A recursive call to the programme with input
      Uñ       :    U sorted
        Ï      :    By 0-based indices
         u     :    Modulo 2

J, 28 26 bytes

-2 bytes thanks to Jonah!

 1#@}.(\:2|#\)^:(2<1{])^:a:

Try it online!

Inspired be Ven's APL solution.

Explanation:

               ^:       ^:a:   while 
                 (2<1{])       the 1-st (zero-indexed) element is greater than 2   
     (        )                do the following and keep the intermediate results
          i.@#                 make a list form 0 to len-1
        2|                     find modulo 2 of each element
      /:                       sort the argument according the list of 0's and 1's
1  }.                          drop the first row of the result
 #@                            and take the length (how many rows -> steps)     

K (ngn/k), 25 bytes

Thanks to ngn for the advice and for his K interpreter!

{#1_{~2=x@1}{x@<2!!#x}\x}

Try it online!

APL (Dyalog Unicode), 35 26 23 22 bytesSBCS

{⍵≡⍳≢⍵:0⋄1+∇⍵[⍒2|⍳⍴⍵]}

Try it online!

Thanks to Adám for the help, Erik the Outgolfer for -3 and ngn for -1.

The TIO link contains two test cases.

Explanation:

{⍵≡⍳≢⍵:0⋄1+∇⍵[⍒2|⍳⍴⍵]}
{⍵≡⍳≢⍵:0⋄1+∇⍵[⍒2|⍳⍴⍵]} ⍝ function takes one argument: ⍵, the array
 ⍵≡⍳≢⍵                 ⍝ if the array is sorted:
 ⍵≡⍳≢⍵                 ⍝ array = 1..length(array)
      :0               ⍝ then return 0
        ⋄              ⍝ otherwise
         1+            ⍝ increment
           ∇           ⍝ the value of the recursive call with this argument:
            ⍵[      ]  ⍝ index into the argument with these indexes:
                 ⍳⍴⍵   ⍝ - generate a range from 1 up to the size of ⍵
               2|      ⍝ - %2: generate a binary mask like [1 0 1 0 1 0]
              ⍒        ⍝ - grade (sorts but returns indexes instead of values), so we have the indexes of all the 1s first, then the 0s.

¹

PowerShell, 62 71 70 66 bytes

+9 bytes when Test cases with an even number of elements added.

-1 byte with splatting.

-4 bytes: wrap the expression with $i,$j to a new scope.

for($a=$args;$a[1]-2;$a=&{($a|?{++$j%2})+($a|?{$i++%2})}){$n++}+$n

Try it online!

PowerShell, 116 114 108 84 78 bytes

-24 bytes thanks to Erik the Outgolfer's solution.

-6 bytes thanks to mazzy.

param($a)for(;$a[1]-2){$n++;$t=@{};$a|%{$t[$j++%2]+=,$_};$a=$t.0+$t.1;$j=0}+$n

Try it online!

Pyth, 18 bytes

L?SIb0hys%L2>Bb1
y

Try it online!

-2 thanks to @Erik the Outgolfer.

The script has two line: the first one defines a function y, the second line calls y with the implicit Q (evaluated stdin) argument.

L?SIb0hys%L2>Bb1
L                function y(b)
 ?               if...
  SIb            the Invariant b == sort(b) holds
     0           return 0
      h          otherwise increment...
       y         ...the return of a recursive call with:
             B   the current argument "bifurcated", an array of:
              b   - the original argument
            >  1  - same with the head popped off
          L      map...
         % 2     ...take only every 2nd value in each array
        s         and concat them back together

¹

Perl 6, 34 32 bytes

-2 bytes thanks to Jo King

{(.[(2 X**^$_)X%$_-1+|1]...2)-1}

Try it online!

Similar to Arnauld's approach. The index of the second card after n shuffles is 2**n % k with k defined as in Arnauld's answer.

R, 85 bytes

s=scan();u=sort(s);k=0;while(any(u[seq(s)]!=s)){k=k+1;u=as.vector(t(matrix(u,,2)))};k

Try it online.

Explanation

Stupid (brute force) method, much less elegant than following the card #2.

Instead of unshuffling the input s we start with a sorted vector u that we progressively shuffle until it is identical with s. This gives warnings (but shuffle counts are still correct) for odd lengths of input due to folding an odd-length vector into a 2-column matrix; in that case, in R, missing data point is filled by recycling of the first element of input.

The loop will never terminate if we provide a vector that cannot be unshuffled.

Addendum: you save one byte if unshuffling instead. Unlike the answer above, there is no need to transpose with t(), however, ordering is byrow=TRUE which is why T appears in matrix().

R, 84 bytes

s=scan();u=sort(s);k=0;while(any(s[seq(u)]!=u)){k=k+1;s=as.vector(matrix(s,,2,T))};k

Try it online!

JavaScript (ES6), 44 bytes

Shorter version suggested by @nwellnhof

Expects a deck with 1-indexed cards as input.

f=(a,x=1)=>a[x]-2&&1+f(a,x*2%(a.length-1|1))

Try it online!

Given a deck \$[c_0,\ldots,c_{L-1}]\$ of length \$L\$, we define:

$$x_n=\begin{cases} 2^n\bmod L&\text{if }L\text{ is odd}\\ 2^n\bmod (L-1)&\text{if }L\text{ is even}\\ \end{cases}$$

And we look for \$n\$ such that \$c_{x_n}=2\$.


JavaScript (ES6),  57 52  50 bytes

Expects a deck with 0-indexed cards as input.

f=(a,x=1,k=a.length-1|1)=>a[1]-x%k&&1+f(a,x*-~k/2)

Try it online!

How?

Since JS is lacking native support for extracting array slices with a custom stepping, simulating the entire riffle-shuffle would probably be rather costly (but to be honest, I didn't even try). However, the solution can also be found by just looking at the 2nd card and the total number of cards in the deck.

Given a deck of length \$L\$, this code looks for \$n\$ such that:

$$c_2\equiv\left(\frac{k+1}{2}\right)^n\pmod k$$

where \$c_2\$ is the second card and \$k\$ is defined as:

$$k=\begin{cases} L&\text{if }L\text{ is odd}\\ L-1&\text{if }L\text{ is even}\\ \end{cases}$$

C (GCC) 64 63 bytes

-1 byte from nwellnhof

i,r;f(c,v)int*v;{for(i=r=1;v[i]>2;++r)i=i*2%(c-1|1);return~-r;}

This is a drastically shorter answer based on Arnauld's and Olivier Grégoire's answers. I'll leave my old solution below since it solves the slightly more general problem of decks with cards that are not contiguous.

Try it online


C (GCC) 162 bytes

a[999],b[999],i,r,o;f(c,v)int*v;{for(r=0;o=1;++r){for(i=c;i--;(i&1?b:a)[i/2]=v[i])o=(v[i]>v[i-1]|!i)&o;if(o)return r;for(i+=o=c+1;i--;)v[i]=i<o/2?a[i]:b[i-o/2];}}

Try it online

a[999],b[999],i,r,o; //pre-declare variables
f(c,v)int*v;{ //argument list
    for(r=0;o=1;++r){ //major loop, reset o (ordered) to true at beginning, increment number of shuffles at end
        for(i=c;i--;(i&1?b:a)[i/2]=v[i]) //loop through v, split into halves a/b as we go
            o=(v[i]>v[i-1]|!i)&o; //if out of order set o (ordered) to false
        if(o) //if ordered
            return r; //return number of shuffles
        //note that i==-1 at this point
        for(i+=o=c+1;i--;)//set i=c and o=c+1, loop through v
            v[i]=i<o/2?a[i]:b[i-o/2];//set first half of v to a, second half to b
    }
}

R, 58 55 45 bytes

a=scan();while(a[2]>2)a=matrix(a,,2,F<-F+1);F

Try it online!

Simulates the sorting process. Input is 1-indexed, returns FALSE for 0.

R, 70 72 bytes

x=scan();i=0;while(any(x>sort(x))){x=c(x[y<-seq(x)%%2>0],x[!y]);i=i+1};i

Try it online!

Now handles the zero shuffle case.

Ruby, 42 bytes

f=->d,r=1{d[r]<3?0:1+f[d,r*2%(1|~-d.max)]}

Try it online!

How:

Search for number 2 inside the array: if it's in second position, the deck hasn't been shuffled, otherwise check the positions where successive shuffles would put it.

Python 2, 39 bytes

f=lambda x:x[1]-2and-~f(x[::2]+x[1::2])

Try it online!

-4 thanks to Jonathan Allan.

Perl 6, 36 34 32 bytes

-2 bytes thanks to nwellnhof

$!={.[1]-2&&$!(.sort:{$++%2})+1}

Try it online!

Reverse riffle shuffles by sorting by the index modulo 2 until the list is sorted, then returns the length of the sequence.

It's funny, I don't usually try the recursive approach for Perl 6, but this time it ended up shorter than the original.

Explanation:

$!={.[1]-2&&$!(.sort:{$++%2})+1}
$!={                           }   # Assign the anonymous code block to $!
    .[1]-2&&                       # While the list is not sorted
            $!(             )      # Recursively call the function on
               .sort:{$++%2}       # It sorted by the parity of each index
                             +1    # And return the number of shuffles

Red, 87 79 78 bytes

func[b][c: 0 while[b/2 > 2][c: c + 1 b: append extract b 2 extract next b 2]c]

Try it online!

Jelly, 8 bytes

ŒœẎ$ƬiṢ’

Try it online!

How?

ŒœẎ$ƬiṢ’ - Link: list of integers A
    Ƭ    - collect up until results are no longer unique...
   $     -   last two links as a monad:
Œœ       -     odds & evens i.e. [a,b,c,d,...] -> [[a,c,...],[b,d,...]]
  Ẏ      -     tighten                         -> [a,c,...,b,d,...]
     Ṣ   - sort A
    i    - first (1-indexed) index of sorted A in collected shuffles
      ’  - decrement

Python 3, 40 bytes

f=lambda x:x[1]-2and 1+f(x[::2]+x[1::2])  # 1-based
f=lambda x:x[1]-1and 1+f(x[::2]+x[1::2])  # 0-based

Try it online!

I need to refresh the page more frequently: missed Erik the Outgolfer's edit doing a similar trick =)

APL(NARS), chars 49, bytes 98

{0{∧/¯1↓⍵≤1⌽⍵:⍺⋄(⍺+1)∇⍵[d],⍵[i∼d←↑¨i⊂⍨2∣i←⍳≢⍵]}⍵}

why use in the deepest loop, one algo that should be nlog(n), when we can use one linear n? just for few bytes more? [⍵≡⍵[⍋⍵] O(nlog n) and the confront each element for see are in order using ∧/¯1↓⍵≤1⌽⍵ O(n)]test:

  f←{0{∧/¯1↓⍵≤1⌽⍵:⍺⋄(⍺+1)∇⍵[d],⍵[i∼d←↑¨i⊂⍨2∣i←⍳≢⍵]}⍵}
  f ,1
0
  f 1 2 3
0
  f 1,9,8,7,6,5,4,3,2,10
3
  f 1,3,5,7,9,11,13,15,17,19,2,4,6,8,10,12,14,16,18,20
17

Wolfram Language (Mathematica), 62 bytes

c=0;While[Sort[a]!=a,a=a[[1;;-1;;2]]~Join~a[[2;;-1;;2]];c++];c

Try it online!

Explanation

The input list is a . It is unriffled and compared with the sorted list until they match.

Java (JDK), 59 bytes

a->{int c=0;for(;a[(1<<c)%(a.length-1|1)]>2;)c++;return c;}

Try it online!

Works reliably only for arrays with a size less than 31 or solutions with less than 31 iterations. For a more general solution, see the following solution with 63 bytes:

a->{int i=1,c=0;for(;a[i]>2;c++)i=i*2%(a.length-1|1);return c;}

Try it online!

Explanation

In a riffle, the next position is the previous one times two modulo either length if it's odd or length - 1 if it's even.

So I'm iterating over all indices using this formula until I find the value 2 in the array.

Credits

05AB1E (legacy), 9 bytes

[DāQ#ι˜]N

Try it online!

Explanation

[   #  ]     # loop until
  ā          # the 1-indexed enumeration of the current list
 D Q         # equals a copy of the current list
     ι˜      # while false, uninterleave the current list and flatten
        N    # push the iteration index N as output