Print a shuffled deck of cards

23

2

Input

None

Output

52 cards. No duplicates. Cards are represented as their unicode characters, e.g. .

The Unicode codepoints follow the following format:

  • The first three digits are 1F0.
  • The next digit is A, B, C, or D for spades, hearts, diamonds, and clubs respectively.
  • The next digit is 1 through C and E for the various numbers/face cards. 1 is ace, 2-A are the number cards, and B, D, and E are the jack, queen, and king respectively. (C is the knight, which isn't in most decks.)

Example output:

Rules:

  • This is . Shortest answer wins.
  • Forbidden loopholes are forbidden.
  • Your deck must be actually randomized. If run 20 times, 20 random (and most likely unique) outputs must be generated.

Note

If you only see boxes, install the DejaVu fonts.

dkudriavtsev

Posted 2017-06-04T21:23:22.267

Reputation: 5 781

Let us continue this discussion in chat.

– NoOneIsHere – 2017-06-04T21:36:24.930

2Can there be spaces between each character? – totallyhuman – 2017-06-04T22:14:57.573

3I think you mean it should be random and that all permutations should have a none zero probability of occurrence. – Notts90 supports Monica – 2017-06-04T22:39:49.330

4Who else is seeing a bunch of boxes? – SuperJedi224 – 2017-06-05T01:00:09.260

@SuperJedi224 Read the bottom section – dkudriavtsev – 2017-06-05T01:01:05.103

1@Mendeleev you should also post a warning that that download is almost a gigabyte! – Noodle9 – 2017-06-05T03:52:08.010

1@Noodle9 That's only if you download the CJK fonts. All the other ones should be less than 50M total, and you should only need Sans, Serif, and Mono anyway. – dkudriavtsev – 2017-06-05T04:30:31.243

The example output is showing as just 52 boxes for me. – Magic Octopus Urn – 2017-06-05T17:40:13.017

@carusocomputing Please read the bottom section of the challenge – dkudriavtsev – 2017-06-05T18:16:29.783

2If you only see boxes, install Google's Noto fonts. Yeah, I can't do that on my phone... – Dennis – 2017-06-06T13:37:49.010

From which of the linked fonts are these cards? I've installed all of them (except for NotoColorEmoji.ttf, which gives an error), but I still see boxes.. – Kevin Cruijssen – 2017-06-07T08:55:12.107

Noto Emoji contains one playing card (U+1F0CF PLAYING CARD BLACK JOKER), and it doesn't even appear in your challenge! – Dennis – 2017-06-08T16:28:42.120

Ooooops... I linked the wrong fonts! – dkudriavtsev – 2017-06-08T16:45:19.997

@Dennis Should be fixed now – dkudriavtsev – 2017-06-08T16:45:38.680

1@KevinCruijssen Should be fixed now – dkudriavtsev – 2017-06-08T16:45:50.683

@SuperJedi224 Try installing the newly linked fonts – dkudriavtsev – 2017-06-08T16:46:59.227

Can confirm, DejaVu Sans is what my desktop computer uses by default and indeed has the playing cards. – Dennis – 2017-06-08T16:49:23.720

@carusocomputing I've updated the font section, try again – dkudriavtsev – 2017-06-09T00:09:12.520

Is the Knight used in any set of cards? Google searches seem to suggest tarot cards? – mbomb007 – 2018-01-16T15:38:56.113

Answers

9

Jelly,  25 23  21 bytes

62R%⁴g180<11T+“¢¬⁷’ẊỌ

A niladic link returning a list of characters, or a full program that prints the shuffled deck.

Try it online!

How?

62R%⁴g180<11T+“¢¬⁷’ẊỌ - Main link: no arguments
62                    - literal 62
  R                   - range(62) -> [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62]
    ⁴                 - literal 16
   %                  - modulo    -> [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14]
      180             - literal 180
     g                - G.C.D.    -> [1,2,3,4,5,6,1,4,9,10, 1,12, 1, 2,15,180, 1, 2, 3, 4, 5, 6, 1, 4, 9,10, 1,12, 1, 2,15,180, 1, 2, 3, 4, 5, 6, 1, 4, 9,10, 1,12, 1, 2,15,180, 1, 2, 3, 4, 5, 6, 1, 4, 9,10, 1,12, 1, 2]
          11          - literal 11
         <            - less than?-> [1,1,1,1,1,1,1,1,1, 1, 1, 0, 1, 1, 0,  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0,  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0,  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]
            T         - truthy    -> [1,2,3,4,5,6,7,8,9,10,11,   13,14,       17,18,19,20,21,22,23,24,25,26,27,   29,30,       33,34,35,36,37,38,39,40,41,42,43,   45,46,       49,50,51,52,53,54,55,56,57,58,59,   61,62]
              “¢¬⁷’   - base 250 number 127136
             +        - addition (vectorises) -> card character ordinals
                   Ẋ  - shuffle the list
                    Ọ - convert to characters
                      - full program has an implicit print

Jonathan Allan

Posted 2017-06-04T21:23:22.267

Reputation: 67 804

4Why is it always Jelly that does this magic? – Gryphon – 2017-06-05T00:55:41.407

8

JavaScript (ES6), 107 106 108 bytes

a=[]
for(S of'ABCD')for(N of'123456789ABDE')a.splice(Math.random()*-~a.length,0,eval(`'\\u\{1F0${S+N}}'`))
a

a=[]
for(S of'ABCD')for(N of'123456789ABDE')a.splice(Math.random()*-~a.length,0,eval(`'\\u\{1F0${S+N}}'`))
a

o.innerHTML = a.join``
<div id=o style="font-size:80px"></div>

-1 byte thanks to @nderscore


JavaScript (ES6), 120 119 121 bytes

Previous version.

a=[],[...'ABCD'].map(S=>[...'123456789ABCE'].map(N=>a.splice(Math.random()*-~a.length|0,0,eval("'\\u\{1F0"+S+N+"}'")))),a

darrylyeo

Posted 2017-06-04T21:23:22.267

Reputation: 6 214

Whoa, never seen [...'ABCD'] before. That's cool :) – Steve Bennett – 2017-06-05T01:02:05.563

@SteveBennett Indeed! It's nice that strings are iterable by char like that. :) – darrylyeo – 2017-06-05T01:07:11.167

But you still can't do things like "ABCD".map(...). I'm sure there are sensible reasons why that's the case. – Steve Bennett – 2017-06-05T01:27:50.160

@SteveBennett Yeah, I'd guess it's because it's ambiguous whether such a method would return a string or an array. – darrylyeo – 2017-06-05T01:35:07.533

The map method is only part of the Array prototype, not the String prototype. – kamoroso94 – 2017-06-05T03:44:06.307

1Very nice one. I took the liberty of modifying the snippet for a more graphical output, but feel free to rollback. – Arnauld – 2017-06-05T10:16:53.853

-1 byte with eval(\'\u{1F0${S+N}}'`)` – nderscore – 2017-06-05T12:40:17.453

@Arnauld Awesome, thanks! Nice to hear from a well seasoned JS golfer. :) – darrylyeo – 2017-06-05T15:46:33.533

@nderscore Done. – darrylyeo – 2017-06-05T15:50:16.667

123456789ABCE includes the cavaliers in the output instead of the queens; it should be 123456789ABDE. – Shaggy – 2017-06-06T10:34:51.540

Also, this always places the ace of spades last. – Shaggy – 2017-06-06T11:27:28.393

@Shaggy Fixed the queens. Including the ace of spades in the shuffle cost me two bytes. – darrylyeo – 2017-06-06T15:47:38.323

7

Python 3,  106  94 bytes

-5 bytes thanks to musicman523 (1. use sample(...,52) as an inline equivalent to shuffle [thanks to totallyhuman]; 2. use ~v&2 instead of v%4<2; plus a further 1 byte as a consequence as a space may be removed)

from random import*
print(*sample([chr(v+127137)for v in range(63)if~v&2or~v%16>4],52),sep='')

Try it online!

Jonathan Allan

Posted 2017-06-04T21:23:22.267

Reputation: 67 804

2

Well I wasn't able to get my own Python solution any better, but I got yours down to 97 using totallyhuman's switch to sample. Try it online!

– musicman523 – 2017-06-05T03:09:17.857

1Additionally, you can change v%4<2 to ~v&2 to save one more byte. – musicman523 – 2017-06-05T03:19:44.893

Nicely done! I had thought maybe another random function could help there. Another byte on top as or ~... can be or~.... – Jonathan Allan – 2017-06-05T03:26:33.843

6

Bash + coreutils, 56 bytes

printf %b\\n \\U1F0{A..D}{{1..9},A,B,D,E}|shuf|tr -d \\n

We use printf to write each card on its own line, shuffle the lines, then concatenate all the lines by removing the newline characters.

Note that although the coreutils printf command requires exactly 8 hexadecimal digits after \U, the Bash built-in printf lets us omit leading zeros.

Toby Speight

Posted 2017-06-04T21:23:22.267

Reputation: 5 058

I got as far as echo 16iF09F8{2A,2B,38,39}{{1..9},A,B,D,E}0AP|dc|shuf|tr -d \\n, but yours is better. I didn't know about %b. – Digital Trauma – 2017-06-05T16:45:33.720

1@Digital - neither did I, until writing this answer! – Toby Speight – 2017-06-05T16:46:51.113

6

05AB1E, 22 21 bytes

Saved 1 byte thanks to carusocomputing.

…1F0A4£14L13KhJâ«Hç.r

Try it online!

Explanation

…1F0                    # push the string "1F0"
    A4£                 # push the string "abcd"
       14L              # push range [1 ... 14]
          13K           # remove 13
             h          # convert to hexadecimal
              J         # join to string "123456789ABCE"
               â        # cartesian product
                «       # prepend the string to each char in the list
                 H      # convert to decimal
                  ç     # get the chars with those code points
                   .r   # randomize

Emigna

Posted 2017-06-04T21:23:22.267

Reputation: 50 798

1…1F0A4£14L13KhJâ«Hç.r for 21 bytes (edited because I forgot to remove knights). Does help you tie jelly though. – Magic Octopus Urn – 2017-06-05T17:52:19.250

@carusocomputing: Good idea to do the cartesian before the concatenation, so we can skip the split. Thanks! – Emigna – 2017-06-05T18:00:30.310

3

Python 3, 107 bytes

Saved 6 bytes thanks to @totallyhuman and 3 thanks to @CCB60!

from random import*
print(*sample([chr(int('1F0'+a+b,16))for a in'ABCD'for b in'123456789ABDE'],52),sep='')

Try it online!

musicman523

Posted 2017-06-04T21:23:22.267

Reputation: 4 472

Golfed it a little. This is only valid if spaces are allowed as separators though. – totallyhuman – 2017-06-04T22:20:29.597

@totallyhuman adding ,sep='' fixes the spaces, of course – but makes it 112 bytes – vroomfondel – 2017-06-04T22:50:07.883

I forgot about random.sample! I'll let the OP decide about spaces. I can add ,sep='' to get rid of them, and still save 6 bytes. – musicman523 – 2017-06-04T22:50:17.493

chr(int(f'0x1F0{a}{b}',16)) can be shortened by 3 bytes to chr(int('0x1F0'+a+b,16)) – CCB60 – 2017-06-05T00:17:38.180

@CCB60 I'm a fool. Good catch – musicman523 – 2017-06-05T02:36:58.787

@musicman523 You mean you're a – mbomb007 – 2018-01-16T15:18:55.577

3

Python 3, 112 bytes

from random import*
*a,=map(chr,range(127136,127200))
del a[::16],a[::-15],a[11::14]
shuffle(a)
print(*a,sep='')

Try it online!

Anders Kaseorg

Posted 2017-06-04T21:23:22.267

Reputation: 29 242

Can you explain the magic going on in the del statement? I've been trying to figure it out by breaking it down into three sequential statements, but I end up deleting the wrong items in the list. For example, a[::16] gives me one card and three uninterpreted unicodes. – CCB60 – 2017-06-05T00:41:58.033

The del statement does break down sequentially from left to right. The first element of of a[::16] is U+1F0A0 PLAYING CARD BACK, which should be deleted. We also need to delete the Knight and Joker cards that are stuck in between the normal 52. See https://en.wikipedia.org/wiki/Playing_cards_in_Unicode#Playing_cards_deck.

– Anders Kaseorg – 2017-06-05T01:31:17.000

3

Charcoal, 50 bytes

A¹²⁷¹³⁶χA⪫E…χ⁺⁶⁴χ℅ιωσWσ«A‽σχA⪫⪪σχωσ¿﹪﹪﹪℅χ¹⁶¦¹⁵¦¹³χ

Try it online! Link is to verbose version of code. Creates the string of all the 64 characters in the block but filters invalid cards out as they are randomly selected. (Speaking of which, random selection without replacement from a string is only 11 bytes, compared to 17 for an array.)

Edit: Subtraction from an array and other Charcoal improvements have cut down the size to 41 bytes: Try it online!

Neil

Posted 2017-06-04T21:23:22.267

Reputation: 95 035

3

PHP>=7, 102 bytes

for(;$i++<64;)in_array(($c=127136+$i)%16,[0,12,15])?:$q[]=IntlChar::chr($c);shuffle($q);echo join($q);

No Online Interpreter available for the IntlChar::chr method

PHP, 112 bytes

for(;$n++<4;shuffle($r))for($i=0;$i++<14;)$i==12?:$r[]=pack("c*",240,159,131-($n>2),$n*16+112+$i);echo join($r);

Try it online!

PHP, 116 bytes

for(;$c=ab89[$n++];shuffle($r))for($i=0;$i++<14;)$i==12?:$r[]=hex2bin(f09f8.(2+($n>2)).$c.dechex($i));echo join($r);

Try it online!

PHP, 121 Bytes

for(;$c=ABCD[$n++];shuffle($r))for($i=0;$i++<14;)$i==12?:$r[]=json_decode('"\ud83c\udc'.$c.dechex($i).'"');echo join($r);

Try it online!

Jörg Hülsermann

Posted 2017-06-04T21:23:22.267

Reputation: 13 026

3

APL (Dyalog), 40 38 bytes

Jonathan Allan's method

⎕UCS((11>180∨16|⍳62)/127136+⍳62)[?⍨52]

() on the following array

⍳62 the first 62 integers

127136+ add 127136 to that

()/ filter that with the Boolean

  ⍳62 first 62 integers

  16| modulus 16

  180∨ GCD of 180 and that

  11> whether 11 is greater than those

[] select the following elements

?⍨52 shuffle the first 52 integers (pick 52 random integers out of a bag of the first 52 integers)

⎕UCS convert to corresponding symbols in the Unicode Character Set


Version 16.0 (currently in beta) solution (33 characters)

⎕UCS(127136+⍸11>180∨16|⍳62)[?⍨52]

() on the following array

⍳62 first 62 integers

16| modulus 16

180∨ GCD of 180 and that

11> whether 11 is greater than those

 indices where True

127136+ add 127136 to that

[] select the following elements

?⍨52 shuffle the first 52 integers (pick 52 random integers out of a bag of the first 52 integers)

⎕UCS convert to corresponding symbols in the Unicode Character Set


Old solution

⎕UCS(126976+16⊥¨,(9+⍳4)∘.,12~⍨⍳14)[?⍨52]

() on the following array

⍳14 the first 14 integers

12~⍨ except 12

()∘., Cartesianly concatenated to

  ⍳4 the first 4 integers

  9+ added to 9

, ravel (flatten) that

16⊥¨ evaluate each in base 16

126976+ add 126976 to that

[] select the following elements

?⍨52 shuffle the first 52 integers (pick 52 random integers out of a bag of the first 52 integers)

⎕UCS convert to corresponding symbols in the Unicode Character Set

Adám

Posted 2017-06-04T21:23:22.267

Reputation: 37 779

2

Alice, 34 bytes

'?rwd.n$@U,!6?44*%a7+-F$K?'+OK

Try it online!

Explanation

'?r                               push numbers 0-63 onto stack
   w                              store return address (start main loop)
    d                             get stack depth
     .n$@                         if zero, terminate
         U                        random number in [0, depth)
          ,                       move corresponding stack element to top
           !                      store on tape
             ?                    copy back from tape
              44*%                mod 16
                  a7+-            subtract 17
            6         F           does the result divide 6?
                       $K         if so, return to start of main loop
                         ?        copy card number from tape again
                          '+     add 0x1F0A1
                             O    output
                              K   return to start of main loop

Nitrodon

Posted 2017-06-04T21:23:22.267

Reputation: 9 181

2

><>, 49 50 49 bytes

""v
=?v>:1+}:88+%:c-:3-**?!~{l4d*
{>x
o^>l?!;

Try it online!

(+1 byte to make the randomness better)

I'm interpreting "random" to mean "every possible outcome has a non-zero probability". This isn't a uniform distribution.

There are two stages to this code. First, the fish puts all the cards on the stack, using the first two lines. Starting with the ace of spades, the fish duplicates and increments it, then checks if the previous card's hex code ends in 0, C or F by multiplying together x (x-12) (x-15), where x is the charcode mod 16, and checking if that's zero. If it is, it deletes the offending card from the stack. It repeats until the stack has 52 cards, then swims into stage 2:

  v
{>x
o^>l?!;

This bit of code shuffles and prints the stack. The x sets the fish's direction randomly:

  • If the fish swims up, it hits the v and goes back to the x without doing anything. The left direction is similar.
  • If the fish swims right, it wraps and hits the {, rotating the entire stack to the left, then returns to the x.
  • If the fish swims down, it prints the card at the front of the stack then returns to the x.

It's clear that every possible order of the cards can be produced: at any point in stage 2, every card that hasn't been printed yet can be printed next if the fish swims rightwards enough times. This shuffling technique usually doesn't move cards very far apart if they were already near each other, but then again, neither does shuffling by hand.

Not a tree

Posted 2017-06-04T21:23:22.267

Reputation: 3 106

2

R, 61 bytes

cat(intToUtf8(sample(c(127137:127198)[-c(12,28,44,47,60)])))

Randomly sample the vector of integer representations of the cards unicode values (which can be obtained from utf8ToInt() fucntion) and remove the unwanted knight/joker cards.

Andrew Haynes

Posted 2017-06-04T21:23:22.267

Reputation: 311

57 bytes – Giuseppe – 2018-01-16T16:02:15.770

1

C# (146 141 bytes)

using System.Linq;()=>Enumerable.Range(0,52).OrderBy(i=>System.Guid.NewGuid()).Aggregate("",(s,i)=>s+"\uD83C"+(char)(56481+i+i/13*3+i%13/12))

Online demo

This uses extremely bad style in shuffling with Guid.NewGuid(), but it's code-golf. It then builds the surrogate pairs manually.

Peter Taylor

Posted 2017-06-04T21:23:22.267

Reputation: 41 901

Does this actually work? Whenever I tried casting the dynamic int to a char, it threw an exception? – TheLethalCoder – 2017-06-06T11:04:18.667

@TheLethalCoder, I don't have any dynamic values. But as proof that it works, I've attached an Ideone link. – Peter Taylor – 2017-06-06T11:06:42.697

I meant the int created for the second part of the surrogate pair. – TheLethalCoder – 2017-06-06T11:07:32.867

You can save a byte by not including the trailing semicolon – TheLethalCoder – 2017-06-06T11:08:47.643

Says 147 bytes, reads as 146 – Neil A. – 2017-06-07T06:38:38.923

0

Perl 5, 75 bytes

@c=map{7946+$_%4+$_/64}4..51,56..59;print chr(16*splice@c,@c*rand,1)while@c

Note that this uses the code points for queens as given in the question (i.e. last digit C). For the actual code points (last digit D), replace 51,56 with 47,52.

faubi

Posted 2017-06-04T21:23:22.267

Reputation: 2 599

0

Java 8, 216 bytes

import java.util.*;()->{List<Long>l=new ArrayList();for(long i=52;i-->0;l.add(i));Collections.shuffle(l);for(Long x:l)System.out.print((char)(x.parseLong("1F0"+(char)(65+x/12)+((x%=4)>9?(char)(x>2?69:65+x):x),16)));}

Explanation:

Try it here.

NOTE: Untested because even though I've installed the linked font, I still see boxes. Probably have to restart my PC or something..

import java.util.*;               // Required import for List, ArrayList and Collections
()->{                             // Method without parameter nor return-type
  List<Long>l=new ArrayList();    //  List
  for(long i=52;i-->0;l.add(i));  //  Fill the list with 1 through 52
  Collections.shuffle(l);         //  Randomly shuffle the list
  for(Long x:l)                   //  Loop over the shuffled list
    System.out.print(             //   Print the following character:
      (char)(x.parseLong(         //    Convert the following String to a character:
        "1F0"+                    //     The literal String "1F0" +
         (char)(65+x/12)+         //     either A, B, C or D by using x/12, adding 65,
                                  //      and casting it to a char +
         ((x%=4)>9?               //     If the current item mod-4 is 10 or higher:
            (char)(x>2?69:65+x)   //      Convert it to A, B, C or E
           :                      //     Else (1 through 9):
            x)                    //      Simply add this digit
      ,16))
    );
}                                 // End of method

Kevin Cruijssen

Posted 2017-06-04T21:23:22.267

Reputation: 67 575

0

Japt, 51 41 39 22 bytes

With some inspiration from Jonathan's Jelly solution.

#?ö¬k@B§XuG y#´Ãmd##

Try it (or view output with increased font-size)


Explanation

#?                         :63
  ö¬                       :Random permutation of range [0,63)
    k                      :Remove elements that return true
     @                     :When passed through this function
      B                    :  11
       §                   :  Less than or equal to
        X                  :  Current element
         u                 :  Modulo
          G                :  16
            y              :  GCD
             #´            :  180
               Ã           :End function
                m          :Map
                  ##       :  Add 127136
                 d         :  Get character at that codepoint

Shaggy

Posted 2017-06-04T21:23:22.267

Reputation: 24 623

0

Dyalog APL, 35 bytes

⎕ucs(∊127150+(16×⍳4)-⊂2~⍨⍳14)[?⍨52]

based on Adám's answer

uses ⎕io←0

ngn

Posted 2017-06-04T21:23:22.267

Reputation: 11 449