| Bytes | Lang | Time | Link |
|---|---|---|---|
| 081 | JavaScript SpiderMonkey | 250124T182706Z | Arnauld |
| 119 | Desmos | 250204T041738Z | DesmosEn |
| 013 | J | 250126T060056Z | Jonah |
| 009 | Uiua 0.15.0dev.1 | 250124T171426Z | Tbw |
| 042 | APL+WIN | 250124T173139Z | Graham |
| 008 | 05AB1E | 250127T082701Z | Kevin Cr |
| 078 | Maple | 250125T211203Z | dharr |
| 010 | Japt | 250124T205238Z | Shaggy |
| 028 | Haskell + hgl | 250124T171047Z | Wheat Wi |
| 027 | Charcoal | 250125T003302Z | Neil |
| 080 | Perl 5 nl | 250124T223656Z | Xcali |
| 052 | Python 3 | 250124T182049Z | Jonathan |
| 006 | Jelly | 250124T165855Z | Jonathan |
JavaScript (SpiderMonkey), 81 bytes
Expects (piles)(cards) and prints the cards one by one, 0-indexed.
p=>n=>{for(k=p-1&~1;~k<p;k-=2)for(j=i=k<0?~k:k;j<n-n%p+p*(i<n%p)+i;j+=p)print(j)}
JavaScript (ES7), 65 bytes
A port of Jonathan Allan's Python answer.
Expects (piles)(cards) and returns an array of 0-indexed cards.
p=>n=>[...Array(n).keys(g=v=>v%p%2-1^v%p)].sort((a,b)=>g(a)-g(b))
Desmos, 119 bytes
d(n)=n+[0...\floor((c-n)/p)]p
R(n,a,r)=\{n>p:a,r=1:R(n+1,\join(a,d(n)),-1),R(n+1,\join(d(n),a),1)\}
f(p,c)=R(2,d(1),1)
This solution works by having a function d(n) find the contents of deck n, then calls a recursive function R(n,a,r) to append d(n) to and accumulator array. I used recursion since it isn't possible to push all d(n) for n=[1...p] into the array at once.
To use it, just call f(Numpiles, Numcards).
J, 23 15 13 bytes
(]/:_2-@^|)i.
-2 thanks to Tbw, in a snake eating its tail chain of improvements
This approach avoids having to group and instead uses a single sort on a flat array. The logic only has to worry about finding the right sorting vector.
Consider 7 f 14 -- 14 cards, 7 piles.
First we create our "cards":
0 1 2 3 4 5 6 7 8 9 10 11 12 13Then mod each by 7 to create our pile ids:
0 1 2 3 4 5 6 0 1 2 3 4 5 6Now we raise -2 to each of those and reverse the signs, so that odd (1-indexed) decreasing negative numbers, and evens are increasing positive numbers:
_1 2 _4 8 _16 32 _64 _1 2 _4 8 _16 32 _64But now the problem is solved, because if we sort our cards ascending according to that vector, then "all of the odd-numbered piles come first in descending order, and the even-numbered piles come second in ascending order," as desired.
Uiua 0.15.0-dev.1, 30, 21, 16, 11 9 bytes SBCS
⍏¯ⁿ⊙¯2◿⊙⇡
-5 bytes thanks to @noodle person's port of @Jonah's answer.
Takes number of piles and deck size and returns a 0-indexed array.
Explanation
⍏¯ⁿ⊙¯2◿⊙⇡
◿⊙⇡ # range(deck) mod piles
¯ⁿ⊙¯2 # map x -> -(-2)^x
⍏ # indices to sort array
Since the other solutions had significantly different strategies, I include them here as well.
Old solutions
⍏×ⁿ+₁⤙¯1◿⊙⇡ (thanks @noodle person and @Jonah)
⍏↯¤:⍏⊂⇌∩▽¬,,◿2.⇡
≡⊡1⊚⊞=⊂⇌∩▽¬,,◿2.⇡:◿,⇡
⊡◴⊚.⬚0⊏♭⍜⊢⇌⍉⬚∞↯∞_2⇡:⍉⬚0↯⊂∞,+1⇡
APL+WIN, 58 42 bytes
Prompts for number of piles followed by number of cards.
(v≤c)/v←∊(⊂¨⍋(i⍴¯1 1)×⍳i)+⊂0,i×⍳⌈(c←⎕)÷i←⎕
05AB1E, 8 bytes
LIιιćRì˜
Inputs in the order \$cards,piles\$.
Try it online or verify all test cases.
Explanation:
L # Push a list in the range [1, (implicit) first input]
Iι # Uninterleave it into the second input amount of parts
ι # Uninterleave that into two parts
ć # Extract the first part
R # Reverse this first list of lists
ì # Prepend it back to the second part
˜ # Flatten the list of lists
# (after which the result is output implicitly)
Maple, 78 bytes
(p,n)->op~(sort([ListTools:-Deal([$n],p)],(a,b)->`if`(b[1]::odd,false,true)));
Ungolfed:
proc(p,n)
[ListTools:-Deal([$n],p)]; # deal out [1..n] into p piles (sublists)
op~(sort(%,(a,b)->`if`(b[1]::odd,false,true))); # if first in the pile is odd,
# bring the pile to the beginning
# op~ flattens to a single list
end:
This relies on Maple's sort only changing the order if the comparison function returns false; then the second argument moves earlier. So setting false if the second argument is odd means that [1,2,3,4,5,6,7] is sorted to [7,5,3,2,1,2,4,6], precisely the order we want for the piles. So this sort order is applied to the list of piles based on the first element in each pile.
Japt, 10 bytes
õ óV ó vÔc
õ óV ó vÔc :Implicit input of integers U=cards & V=piles
õ :Range [1,U]
óV :Partitions of every Vth element
ó :Uninterleave
v :Modify first element/sub-array
Ô : Reverse
c :Flatten
Haskell + hgl, 28 bytes
(cx<(mp<rv)<%uak<tx)<<fxS<e1
Takes input in reverse order from the test cases.
Explanation
e1enumerate from 1 to the inputfxSsplit into chunks of the input sizetxtransposeuaksplit into elements of odd and even indicesrvreverse the odd indicesmpcombine the odds and evenscxconcat the piles
Reflection
uakis a sort of strange function that keeps being useful in unexpected ways. I could extend its behavior to take a function to combine the two parts. Sof :: (List a -> List a -> c) -> List a -> cwhereuak = f (,).- I will probably add
on mp fo(take two lists of monoid elements and concat them). It would save bytes here, and I can see it being a useful albeit niche operation.
Charcoal, 27 bytes
NθNηIΣE⁺⮌Φθ¬﹪ι²Φθ﹪ι²✂…⁰ηιηθ
Attempt This Online! Link is to verbose version of code. 0-indexed. Explanation:
Nθ Input number of piles
Nη Input number of cards
θ Number of piles
Φ Filter on implicit range
ι Current value
﹪ Modulo
² Literal integer `2`
¬ Is zero
⮌ Reversed
⁺ Concatenated with
θ Number of piles
Φ Filter on implicit range
ι Current value
﹪ Modulo
² Literal integer `2`
E Map over values
… Range from
⁰ Literal integer `0` to
η Number of cards
✂ Sliced from
ι Current value to
η Number of cards
θ In steps of number of piles
Σ Concatenate the lists
I Cast to string
Implicitly print
Perl 5 -nl, 80 bytes
for$b(sort{$a%2-$b%2||($a%2?$a-$b:$b-$a)}0..($u=<>)-1){map$_%$u-$b||say,0..$_-1}
Python 3, 57 56 52 bytes
-4 from me & xnor (although it looks like he pipped me to the post by about six minutes).
lambda p,d:sorted(range(d),key=lambda v:v%p%2-1^v%p)
An unnamed function that accepts the pile count, p, and the deck size, d, and returns a list of the shuffled, 0-indexed cards.
Try it online! (Increments all cards to align with the examples given in the question.)
How?
Sorts the indexes of the original deck (range(d) being the range \$[0,d-1]\$) by whether firstly the 0-indexed pile index, v, is even and secondly by the pile index. The pile index is v%p so we get -1-(v%p) when v%p%2 is zero (even pile index) or v%p when v%p%2 is one (odd pile index). We could use just -(v%p) but shifting down one to -1-(v%p) is golfier using an XOR (^) with v%p%2-1^v%p - that is, with parentheses to clarify precedence (((v%p)%2)-1)^(v%p).
47 bytes if we may accept a list of the card indexes (i.e. the integers \$[0,d-1]\$) in an undetermined order (i.e. shuffled), by rearranging them to the (one and only) desired order.
lambda p,d:d.sort(key=lambda v:(v%p%2-1^v%p,v))
43 bytes if we can take the same input, but ordered. (Seems cheaty to me.)
lambda p,d:d.sort(key=lambda v:v%p%2-1^v%p)
Jelly, 7 6 bytes
-1 by Unrelated String (use a grade-up of the card's pile indexes.)
NḂ¡€ṁỤ
A dyadic Link that accepts the number of piles on the left and the deck size on the right and yields the shuffled deck.
How?
NḂ¡€ṁỤ - Link: integer, PileCount, integer, DeckSize
€ - for each {PileIndex in [1..PileCount]}:
¡ - repeat...
Ḃ - ...times: PileIndex mod 2 -> One if odd else Zero
N - ...action: negate
ṁ - mould like {[1..DeckSize]}
Ụ - grade {that} up (the indices of {that} sorted by their respective values)