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\$ Commented 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\$ Commented Jul 28, 2020 at 13:09
  • \$\begingroup\$ @Noodle9 Haha, exactly!! \$\endgroup\$ Commented Jul 28, 2020 at 16:44
  • \$\begingroup\$ Closely related \$\endgroup\$ Commented 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
  • \$\begingroup\$ A few more 7 byters \$\endgroup\$ Commented May 4, 2021 at 0:11
  • \$\begingroup\$ @cairdcoinheringaahing Nice, here's another along the same track. \$\endgroup\$ Commented May 4, 2021 at 0:29
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
  • 1
    \$\begingroup\$ 10 bytes. \$\endgroup\$ Commented Jul 27, 2020 at 2:18
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\$ Commented 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\$ Commented 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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.