30
\$\begingroup\$

Introduction

Long ago, when I used to code card games with usual playing cards, I used to specify a number for each card and call a function with some number to get a card. This somewhat inspired me to make this challenge.

So for the people unaware of the playing cards, a deck of cards consist of 52 cards (13 in each of the four suits, i.e, Hearts, Diamonds, Spades, Clubs). In each suit, there are 13 cards - firstly the cards numbered from 2-10, then the Jack(J), Queen(Q), King(K) and the Ace(A). This is the order

Challenge

The challenge is to take an integer between 1-52 as input and display the card at that position. But, your output must be in words. Also, order must be maintained, i.e, first 13 cards will be of Hearts, then Diamonds, then Spades and finally Clubs.

For example, if someone chooses the number 30.The card would then belong to the third suit, i.e, the Spades. Also, it would be the fourth card in the suit, which means the number 5. Hence your output in words must be: five of spades and it should always follow this format, i.e, first the card, followed by an of and the name of the suit at the end, with required spaces in between.

Input And Output

The input will be an integer between 1-52 (both inclusive). Note that here counting starts from 1. You may choose to start from 0. However, you must maintain the order of the cards which is mentioned above. Your output should be the card at that position written in words. You do not need to handle invalid inputs. Also, your output may be in lower-case or in upper-case.

Given below is the list of all the possible inputs and their outputs:

1 -> two of hearts
2 -> three of hearts
3 -> four of hearts
4 -> five of hearts
5 -> six of hearts
6 -> seven of hearts
7 -> eight of hearts
8 -> nine of hearts
9 -> ten of hearts
10 -> jack of hearts
11 -> queen of hearts
12 -> king of hearts
13 -> ace of hearts
14 -> two of diamonds
15 -> three of diamonds
16 -> four of diamonds
17 -> five of diamonds
18 -> six of diamonds
19 -> seven of diamonds
20 -> eight of diamonds
21 -> nine of diamonds
22 -> ten of diamonds
23 -> jack of diamonds
24 -> queen of diamonds
25 -> king of diamonds
26 -> ace of diamonds
27 -> two of spades
28 -> three of spades
29 -> four of spades
30 -> five of spades
31 -> six of spades
32 -> seven of spades
33 -> eight of spades
34 -> nine of spades
35 -> ten of spades
36 -> jack of spades
37 -> queen of spades
38 -> king of spades
39 -> ace of spades
40 -> two of clubs
41 -> three of clubs
42 -> four of clubs
43 -> five of clubs
44 -> six of clubs
45 -> seven of clubs
46 -> eight of clubs
47 -> nine of clubs
48 -> ten of clubs
49 -> jack of clubs
50 -> queen of clubs
51 -> king of clubs
52 -> ace of clubs

Scoring

This is , so the shortest code wins.

\$\endgroup\$
  • 1
    \$\begingroup\$ Isn't the default order of suits usually hearts, spaces, diamonds, clubs (red, black, red, black). Not that it matters for the challenge, was just wondering why it's in this order. \$\endgroup\$ – Kevin Cruijssen Mar 14 '18 at 7:53
  • 3
    \$\begingroup\$ It varies from game to game. Different games follow different orders. Also talking about cards, some games even have ace as the lowest card in the suit. \$\endgroup\$ – Manish Kundu Mar 14 '18 at 7:58
  • \$\begingroup\$ Can I output two\s\s\sof\shearts where \s stands for a space? (Note the two extra space.) \$\endgroup\$ – totallyhuman Mar 14 '18 at 10:03
  • 2
    \$\begingroup\$ @totallyhuman sorry but there must be exactly 1 space in between \$\endgroup\$ – Manish Kundu Mar 14 '18 at 10:19

47 Answers 47

1
\$\begingroup\$

Ruby, 124 bytes

->n{%w{two three four five six seven eight nine ten jack queen king ace}[n%13]+" of #{%w{heart diamond spade club}[n/13]}s"}

Try it online!

Zero indexed. Very straightforward.

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

Kotlin, 138 bytes

"two|three|four|five|six|seven|eight|nine|ten|jack|queen|king|ace".split("|")[i%13]+" of "+"hearts|diamonds|spades|clubs".split("|")[i/13]

Beautified

"two|three|four|five|six|seven|eight|nine|ten|jack|queen|king|ace".split("|")[i%13]+" of "+"hearts|diamonds|spades|clubs".split("|")[i/13]

Test

fun i(i:Int) =
"two|three|four|five|six|seven|eight|nine|ten|jack|queen|king|ace".split("|")[i%13]+" of "+"hearts|diamonds|spades|clubs".split("|")[i/13]
fun main(args: Array<String>) {
    for (i in (1..52)) {
        println(i(i))
    }
}

TIO

TryItOnline

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

QBasic, 190 178 bytes

a$="ace  two  threefour five six  seveneightnine ten  jack queenking
b$="hearts  diamondsspades  clubs
INPUT i
?RTRIM$(MID$(a$,(i MOD 13)*5+1,5))+" of "+MID$(b$,((i-1)\13)*8+1,8)

As usual, @DLosc saved me some bytes. I should listen to my own advice more often.

Encoding all the text is expensive here...

Explanation of previous version, same principles still apply.

                ' String containing 13 card values - each position is 5 chars long
a$="ace  two  threefour five six  seveneightnine ten  jack queenking
b$(1)="hearts   ' Four card suits. Now it might look like these string lits 
b$(2)="diamonds ' are not terminated, but that's because they aren't
b$(3)="spades   ' QBasic 4.5 auto-adds the quotes on a line break 
b$(4)="clubs    ' (kinda like it also auto-expands ? to PRINT)
INPUT i         ' Take the base-1 index, and 
?               ' PRINT
RTRIM$(         ' a string with all the spaces removed from the right end
MID$(a$,        ' of a substring of our card values
(i MOD 13)*5+1  ' starting at pos 0 (for the ace) through 12, * 5 (0, 5, 10 ... 60) 
                ' + 1 (QBasic has 1-based strings)
,5))            ' and running for 5 characters
+" of "+        ' followed by " of " and
b$((i-1)\13+1)  ' the suit, taken from the array after int-divide op i
\$\endgroup\$
  • \$\begingroup\$ @DLosc Thanks, that saved 12 bytes. Solution is 1-based btw. 1 --> two of hearts and 52 --> ace of clubs. \$\endgroup\$ – steenbergh Jun 11 '18 at 17:27
  • \$\begingroup\$ Oh, whoops--I didn't notice that suits were supposed to start at two instead of ace. \$\endgroup\$ – DLosc Jun 11 '18 at 22:06
1
\$\begingroup\$

Excel VBA, 138 bytes

An anonymous function that takes input from [A1] and outputs to STDOUT. 0 indexed.

?Split("Two Three Four Five Six Seven Eight Nine Ten Jack Queen King Ace")([A1]Mod 13)" of "Split("Hearts Diamonds Spades Clubs")([A1/13])
\$\endgroup\$
1
\$\begingroup\$

dc, 161 160 158 142 bytes

[TWO][THREE][FOUR][FIVE][SIX][SEVEN][EIGHT][NINE][TEN][JACK][QUEEN][KING][ACE][HEART][DIAMOND][SPADE][CLUB][z2-:rz1<A]dsAxD~;rP[ OF ]PD+;rP83P

Try it online!

Over a year later, I was looking for something in my old golfs and found 16 bytes of inefficiency in the previous code:

[ACE][KING][QUEEN][JACK][TEN][NINE][EIGHT][SEVEN][SIX][FIVE][FOUR][THREE][TWO]0[d1+si:rlidD>A]dsAxr[CLUB]3:s[SPADE]2:s[DIAMOND]1:s[HEART]0:sD~;rP[ OF ]P;sP83P

Try that chunkier version online!

Top of stack used as input. 0-indexed.

In the old version, the array of ranks (r) was created using an iterator to run through the strings on the stack (0[d1+si:rlidD>A]dsAxr), but with only four items, it's shorter to manually assign the suits (3:s, etc.). The new version simply uses one array for all of it and also doesn't check against a fixed stack size. [z2-:rz1<A]dsAx replaces the above stack-crawler, popping everything into r at the position (stack depth)-2; it stops when there's one value left.

After all that setup is done, we divide by 13 leaving remainder & quotient on stack (D~). In the old version, we used these values to pick from the two arrays. In the new version, without a separate array of suits, we add 14 (E+) to the suit value, since our suits are after our ranks in array r. Print the strings, and print OF in the middle (;rP[ OF ]PE+;rP).

(First two golfs: -1 byte by outputting uppercase; this allows me to remove the 4 ses from the end of the suits, and instead print it via its ASCII value with the 3-byte 83P at the end. -2 bytes because I repeatedly misread the challenge as requiring 1-indexing. Now 0-indexed.)

\$\endgroup\$
0
\$\begingroup\$

Red, 176 bytes

func[n][i: 0
foreach s["hearts""diamonds""spades""clubs"][foreach c split{two three four five six seven eight nine ten jack queen king ace}" "[if n = i: i + 1[print[c"of"s]]]]]

Try it online!

As always, the facts that the indexing is 1-based in Red and the math expressions are always long because of the obligatory spaces, are the reasons not to use modulo in my solution.

\$\endgroup\$
0
\$\begingroup\$

Python 3, 157 bytes

lambda n:'two,three,four,five,six,seven,eight,nine,ten,jack,queen,king,ace'.split(',')[(n-1)%13]+' of '+['hearts','diamonds','spades','clubs'][int((n-1)/13)]

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Charcoal, 78 bytes

§⪪”↶⌈=≔≡Ss←⊟✂sδ‴/﹪]7v1θ/✂eS'⌊D↔⎚B^#ïG⎚¦J←↥§”¶Iθ of §⪪”↶↧#σïP/M≡#↗÷⌕ρTM”¶÷Iθ¹³s

Try it online! Link is to verbose version of code. 0-indexed. Explanation:

  ”...”         Compressed string "two\nthree...king\ace"
 ⪪     ¶        Split on newlines
§       Iθ      Cyclically index on input cast to integer
                Implicitly print
 of             Literal string " of "
                Implicitly print
  ”...”         Compressed string "heart\ndiamond\nspade\nclub"
 ⪪     ¶        Split on newlines
         Iθ     Cast input to integer
        ÷  ¹³   Integer divide by 13
§               Index into list
                Implicitly print
s               Literal string "s"
                Implicitly print

Note: Without the limitation on suit ordering it can be done in 72 bytes:

F⪪”↶±″ς#₂g⎇¹αF+9r@c?×πλ¿BRu≦Zθx⊗Zj⊗✳R⦄ηs⊖▶fB‽⁺P4!⁶E~p↥Fºχβ|»J↧H¦”¶§⪪ιyIθ

Try it online! Link is to verbose version of code. Explanation:

  ”...”         Compressed string "twoy...yace\n of \nheartsy...yclubs"
 ⪪     ¶        Split on newlines
F               Loop over each element
         ⪪ιy    Split on literal string "y"
        §   Iθ  Cyclically index on input cast to integer
                Implicitly print
\$\endgroup\$
0
\$\begingroup\$

Javascript 137 bytes

i=>"two,three,four,five,six,seven,eight,nine,ten,jack,queen,king,ace".split`,`[i%13]+` of ${["heart","diamond","spade","club"][0|i/13]}s`

f=

i=>"two,three,four,five,six,seven,eight,nine,ten,jack,queen,king,ace".split`,`[i%13]+` of ${["heart","diamond","spade","club"][0|i/13]}s`

console.log(f(38))

\$\endgroup\$
0
\$\begingroup\$

///, 460 bytes

/*/\/\///52/M!*51/L!*50/K!*49/J!*48/I!*47/H!*46/G!*45/F!*44/E!*43/D!*42/C!*41/B!*40/A!*39/M@*38/L@*37/K@*36/J@*35/I@*34/H@*33/G@*32/F@*31/E@*30/D@*29/C@*28/B@*27/A@*26/M#*25/L#*24/K#*23/J#*22/I#*21/H#*20/G#*19/F#*18/E#*17/D#*16/C#*15/B#*14/A#*13/M$*12/L$*11/K$*10/J$*9/I$*8/H$*7/G$*6/F$*5/E$*4/D$*3/C$*2/B$*1/A$*M/ace.*L/king.*K/queen.*J/jack.*I/ten.*H/nine.*G/eight.*F/seven.*E/six.*D/five.*C/four.*B/three.*A/two.*./ of *!/clubs*@/spades*#/diamonds*$/hearts/

Try it online!

The index of the card you want gets placed after the last /. I've left all indices in the TIO-link as a test suite. Also, because I've placed that test-suite in the Footer part of TIO, it adds a linebreak at the top.

\$\endgroup\$
0
\$\begingroup\$

PHP 209 Bytes

No way this is the shortest, just a fun challenge.

<?php
 $a=$_GET['q'];$s=$a<53?'clubs':0;$s=$a<40?'spades':$s;$s=$a<27?'diamonds':$s;$s=$a<14?'hearts':$s;$v=$a%13;$v=$v==1?'ace':$v;$v=$v==11?'jack':$v;$v=$v==12?'queen':$v;$v=$v===0?'king':$v;echo "$v of $s";

Ungolfed

<?php
    $a=$_GET['q'];//input
    $s= $a<53?'clubs':0;//Ordered descending to overwrite extra positives, (prevent two checks per number like
    $s= $a<40?'spades':$s;//                                                                           a>=x>=b
    $s= $a<27?'diamonds':$s;
    $s= $a<14?'hearts':$s;

    $v=$a%13;
    $v = $v==1?'ace': $v;
    $v = $v==11?'jack': $v;
    $v = $v==12?'queen': $v;
    $v = $v===0?'king': $v;

    echo "$v of $s";
\$\endgroup\$
0
\$\begingroup\$

Python 3, 143 bytes

s='hearts diamonds spades clubs two three four five six seven eight nine ten jack queen king ace'.split()
lambda n:f'{s[n%13+4]} of {s[n//13]}'
\$\endgroup\$
0
\$\begingroup\$

Pip -s, 114 bytes

Yay I tied CJam!

[("two three four five six seven eight nine ten jack queen king ace"^sa)"of"("heart diamond spade club"^sa/13).'s]

Uses 0-indexing. Try it online! Or, verify all inputs!

\$\endgroup\$
0
\$\begingroup\$

PHP, 148 137 133 bytes

<?=[two,three,four,five,six,seven,eight,nine,ten,jack,queen,king,ace][($a=$argv[1])%13]." of ".[hearts,diamonds,spades,clubs][$a/13];

Try it online!

Zero based.

\$\endgroup\$
0
\$\begingroup\$

T-SQL, 173 bytes

SELECT TRIM(SUBSTRING('two  threefour five six  seveneightnine ten  jack queenking ace'
 ,i%13*5+1,5))+' of '+TRIM(SUBSTRING('hearts  diamondsspades  clubs',i/13*8+1,8))FROM t

0-based input is taken via pre-existing table t with int field i, per our IO standards.

Saw the trick using string position and TRIM in Chronocidal's Excel answer, I'm using it to "look up" both the card value and the suit.

TRIM() is new to SQL 2017, prior to that add 2 characters for RTRIM() instead.

\$\endgroup\$
0
\$\begingroup\$

Pyth, 104 bytesSBCS

jd[@c." X$¾k¼q}V©>##!Tâò°Ùisö÷¼ÞÊ?.Q \\v,X*nã¬ËÇè"d%Q13"OF"@cr." uô¶)BMÙ¼)|Ó¹MÃ"1d/Q13

Try it online!

NOTE: This code make use of unprintable characters which are not copy/paste-able from this post. The link provided leads to the correct version of the program, which is copy/paste-able.

0-indexed.

Python 3 translation:
Q=eval(input())
print(" ".join(["TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN JACK QUEEN KING ACE".split()[Q%13],"OF","hearts diamonds spades clubs".upper().split()[Q//13]]))

A few oddities here and there due to Pyth's string compression deciding to just not work sometimes, but I managed to work around them.

\$\endgroup\$
0
\$\begingroup\$

Yabasic, 186 bytes

An anonymous function that takes input, n and outputs to STDOUT. 0 indexed.

input""n
dim s$(13),t$(4)
k=Split("Two Three Four Five Six Seven Eight Nine Ten Jack Queen King Ace",s$())
k=Split("Hearts Diamonds Spades Clubs",t$())
?s$(Mod(n,13)+1)+" of "+t$(n/13+1)

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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