42
\$\begingroup\$

Background

Milking the deck is the name given to the following card shuffling method:

  1. 'Pinch' the deck to remove the top and bottom cards simultaneously. (With lots of imagination, this action resembles milking a cow.) This pair of cards forms the base of a new pile.
  2. Repeat, adding each pair of cards to the top of the new pile, until the whole deck has been used.

Example

Suppose we start with a deck of six cards, [1, 2, 3, 4, 5, 6] (lower-indexed elements are nearer to the top). Let's milk the deck:

  1. old = [1, 2, 3, 4, 5, 6], new = []
  2. Remove [1, 6]: old = [2, 3, 4, 5], new = [1, 6]
  3. Remove [2, 5]: old = [3, 4], new = [2, 5, 1, 6]
  4. Remove [3, 4]: old = [], new = [3, 4, 2, 5, 1, 6]

After milking, the deck is therefore ordered [3, 4, 2, 5, 1, 6].

Challenge

Your task in this challenge is to implement the milking operation on a given array and output/return the result. The input array will contain only positive integers, not necessarily distinct. If the input array contains an odd number of elements, then the last milking step transfers only one element (the last one remaining) from the input to the output array.

Test cases

Input -> Output

[1, 2, 3, 4, 5, 6] -> [3, 4, 2, 5, 1, 6]
[1, 2, 3, 4, 5, 6, 7] -> [4, 3, 5, 2, 6, 1, 7]
[9, 7, 5, 3, 1, 2, 4, 6, 8, 10] -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 1, 2, 1, 2] -> [2, 1, 1, 1, 2]
[] -> []
\$\endgroup\$
4
  • 7
    \$\begingroup\$ @Third-party'Chef' You're right, it is the inverse of pendulum encoding when length is odd. When length is even, though, it ends up with every pair flipped. Eg. [1,2,3,4,5] → [4,2,1,3,5] → [1,2,3,4,5] but [1,2,3,4,5,6] → [6,4,2,1,3,5] → [2,1,4,3,6,5]. (First I applied the pendulum encoding, then the milk shuffle.) \$\endgroup\$
    – AviFS
    Jul 25, 2020 at 11:54
  • 5
    \$\begingroup\$ @AviFS So the inverse of pendulum encoding is therefore the milk shuffle, then pendulum encoding and then finally the milk shuffle again. \$\endgroup\$
    – Noodle9
    Jul 28, 2020 at 13:09
  • \$\begingroup\$ @Noodle9 Haha, exactly!! \$\endgroup\$
    – AviFS
    Jul 28, 2020 at 16:44
  • \$\begingroup\$ Closely related \$\endgroup\$
    – DLosc
    Jun 22, 2021 at 4:29

39 Answers 39

1
2
3
\$\begingroup\$

Scala 3, 46 45 bytes

It appears @cole already had the same answer in Haskell, so you should upvote that.

| =>(|reverse)zip|flatMap(Seq(_,_))drop|.size

Please forgive the name |. I did it to save a byte.

Try it online

Scala 2, 57 55 54 51 bytes

| =>(|reverse,|).zipped.flatMap(Seq(_,_))drop|.size

Same thing, but needed the parameter to be a single tuple instead of having 2 parameters.

Try it online

Ungolfed:

s => s.reverse.zip(s).flatMap{ case(a,b) => List(a,b) }.drop(s.size)

And a recursive solution, just because (71 bytes):

def*(l:List[Int]):List[Int]=if(l.size<2)l else*(l.init.reverse):+l.last

Try it online

\$\endgroup\$
2
\$\begingroup\$

Jelly, 7 bytes

ṖṚ$ƬZṪ€

A monadic Link accepting a list which yields the shuffled list.

Try it online!

How?

ṖṚ$ƬZṪ€ - Link: list, A
   Ƭ    - apply & collect while different - i.e. [A, f(A), f(f(A)), ..., []]
  $     -   last two links as a dyad:
Ṗ       -     remove the rightmost item
 Ṛ      -     reverse
    Z   - transpose the (ragged) result
     Ṫ€ - last item of each

A couple of alternative approaches which are longer:

  1. sort the indices by their absolute difference from the centre and index back into the list: JạÞL‘HƊị
  2. use the beauty of the factorial number system and its relation to the sort order of permutations: J’:2ṚÆ¡‘œ?
\$\endgroup\$
2
2
\$\begingroup\$

J, 15 bytes

#}.],/@|:@,:~|.

Try it online!

Port of Kevin Cruijssen's 05AB1E answer and streetster's K solution - don't forget to upvote them!

\$\endgroup\$
1
2
\$\begingroup\$

T-SQL, 46 bytes

Input is a table variable

DECLARE @ table(v int,i int identity(1,2))
INSERT @ values(1),(2),(3),(4),(5),(6)

SELECT v
FROM @
ORDER BY abs(sum(1)over()-i),i

Try it online

\$\endgroup\$
2
\$\begingroup\$

Ruby, 38 37 bytes 34 bytes

f=->x{(b=x.pop)?f[x.reverse]<<b:x}

Try it online!

-3 bytes thanks to @Dingus

Uses Dominic van Essen's approach: repeatedly takes the bottom card and recurses on the reverse of the rest of the deck.

\$\endgroup\$
1
  • \$\begingroup\$ reverse is a long word. Is there any golfing alternative? \$\endgroup\$ Jul 28, 2020 at 11:28
2
\$\begingroup\$

Vyxal, 7 bytes

(Ṙḣ)WṘ'

Try it Online!

\$\endgroup\$
1
  • \$\begingroup\$ @Dingus Sorry, got mixed up, fixing \$\endgroup\$
    – emanresu A
    Jun 2, 2021 at 1:30
1
\$\begingroup\$

Red, 60 bytes

func[b][reverse collect[while[[]<> b][keep take reverse b]]]

Try it online!

Inspired by Dominic van Essen's R solution

\$\endgroup\$
1
\$\begingroup\$

Japt -Q -m, 17 16 bytes

[UoUÊ/2 ,U]Õcf w

Try it

[UoUÊ/2            take the last half elements( reversed )
        ,U]        and the remaining 
           Õ       transpose
            cf      flatten after removing null
               w   reverse

Flags used for pretty output

\$\endgroup\$
1
\$\begingroup\$

Thunno 2 t, 5 bytes

r$I2Ẇ

Try it online!

Explanation

r$I2Ẇ  # Implicit input
r      # Reverse the input
 $     # Push the input again
  I    # Interleave them
   2Ẇ  # Split into two
       # Leave only the last part
       # Implicit output
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.