| Bytes | Lang | Time | Link |
|---|---|---|---|
| nan | Scala 3 | 240916T135728Z | 138 Aspe |
| 337 | Go | 240916T164134Z | bigyihsu |
| 047 | Uiua | 240916T132533Z | nyxbird |
| 135 | Python 2 | 180226T155121Z | TFeld |
| 171 | R | 180220T223120Z | Giuseppe |
| 026 | Jelly | 180221T001036Z | Jonathan |
| 045 | Pyth | 180221T163413Z | user4854 |
| 193 | ><> | 180221T053245Z | Jo King |
| 259 | Java 8 | 180221T103723Z | Kevin Cr |
| 059 | Retina | 180221T100358Z | Neil |
| 175 | PowerShell v2 or later | 180221T101639Z | user3141 |
| 029 | 05AB1E | 180221T091841Z | Emigna |
| 175 | Python 2 | 180220T221824Z | ovs |
| nan | Ruby | 180220T235227Z | Level Ri |
Scala 3, 382 339 bytes
Saved 43 bytes thanks to @ceilingcat
def main(g:Array[String])={val S="SHCD"
val V="23456789TJQKA"
val z=scala.util.Random
var d:List[(Char,Char)]=List()
if(d.nonEmpty)println(d.collect{case(v,s)if S.contains(s)=>s"$s$v"})
val f:String=>String=x=>z.shuffle(x.toList).take(1).mkString
println(z.shuffle((for{v<-V
s<-S}yield if(f(V)+f(S)!=s"$v$s")s"$v$s"else s"$s$v").toList))}
Ungoled version. Attempt This Online!
import scala.util.Random
object Main {
def main(args: Array[String]): Unit = {
// Suits and card values
val suits = "SHCD" // S = Spade, H = Heart, C = Club, D = Diamond
val values = "23456789TJQKA"
// Empty list for card pairs
var deck: List[(Char, Char)] = List()
// If the deck is not empty, print the reversed card pairs (not applicable as the deck is empty here)
if (deck.nonEmpty) {
println(deck.collect { case (value, suit) if suits.contains(suit) => s"$suit$value" })
}
// Sample one card value and one suit
val selectedCard = Random.shuffle(values.toList).take(1).mkString // Randomly pick one card value
val selectedSuit = Random.shuffle(suits.toList).take(1).mkString // Randomly pick one suit
val r = selectedCard + selectedSuit // Combine to form a card (e.g., "2S")
// Generate all combinations of card values and suits, and compare each to the selected card
val cardsCombined = for {
value <- values
suit <- suits
} yield if (r != s"$value$suit") s"$value$suit" else s"$suit$value"
// Shuffle and print the deck of 52 cards
println(Random.shuffle(cardsCombined.toList))
}
}
Go, 337 bytes
import(."math/rand";."strings")
func f(d*[]string)(o[]string){D,S,V:=[]string{},"SHCD","23456789TJQKA"
for i:=range V{for j:=range S{D=append(D,V[i:i+1]+S[j:j+1])}}
n:=Intn(52)
if d==nil{D[n]=D[n][1:2]+D[n][0:1]
for _,i:=range Perm(52){o=append(o,D[i])}}else{for _,c:=range*d{if ContainsAny(c[0:1],S){o=append(o,c[1:2]+c[0:1])}}}
return}
This solution uses SHCD for suits, and 23456789TJQKA for values. An "empty" input here is when the function is passed nil.
Go, 344 bytes
import(."math/rand";."strings")
func f(d...[]string)(o[]string){D,S,V:=[]string{},"SHCD","23456789TJQKA"
for i:=range V{for j:=range S{D=append(D,V[i:i+1]+S[j:j+1])}}
n:=Intn(52)
if len(d)<1{D[n]=D[n][1:2]+D[n][0:1]
for _,i:=range Perm(52){o=append(o,D[i])}}else{for _,c:=range d[0]{if ContainsAny(c[0:1],S){o=append(o,c[1:2]+c[0:1])}}}
return}
This solution uses a variadic argument to allow for a truly empty input.
Uiua, 47 bytes
⨬(°⍆⍜⊢⇌°⍆☇1⊞⊂⊂+@2⇡8"TJQKA"|⇌⊢▽⊢⍉⊸∈)±⧻,"SDCH"
Experimental because of °⍆
⨬(°⍆⍜⊢⇌°⍆☇1⊞⊂⊂+@2⇡8"TJQKA"|⇌⊢▽⊢⍉⊸∈)±⧻,"SDCH"
⨬( )±⧻, # switch on the sign of the length of the input
(°⍆⍜⊢⇌°⍆☇1⊞⊂⊂+@2⇡8"TJQKA"| # 0:
☇1⊞⊂⊂+@2⇡8"TJQKA" "SDCH" # cartesian product of ranks and suits
°⍆ # shuffle
⍜⊢⇌ # reverse the first
°⍆ # shuffle again
|⇌⊢▽⊢⍉⊸∈) # 1:
⊢▽ # get the element for which
⊢⍉⊸∈ "SDCH" # the first character is a member of "SDCH"
⇌ # and reverse it
Funnily enough, if we could use ♣♦♥♠ instead of letters, we could save a byte with Suits
Python 2, 135 bytes
from random import*
s=shuffle
d=zip('A23456789TJQK'*4,'SCDH'*13)
s(d)
D=input()
if D:d=list(set(D)-set(d))
d[0]=d[0][::-1]
s(d)
print d
Cards are tuples of (value,suit)
Empty input is []
R, 177 171 bytes
function(l=1,F="(.)(.)",R="\\2\\1",S=sample)if(l>1)sub(F,R,grep("^[SDHC]",l,v=T))else{m=S(outer(c(2:9,"T","J","Q","K"),c("S","D","H","C"),paste0))
m[1]=sub(F,R,m[1])
S(m)}
Given empty input, (call f with no input), we default to l=1 and thus create a random permutation m of the deck. Assuming sample is truly random, there is an equal probability of any card being the first in this list. So we modify the first one, and then shuffle again, returning the list.
Reversing it, we look for a card starting with one of SDHC and reverse it.
Jelly, 26 bytes
9ḊṾ€;“AJKQT”p“CDHS”ḟ⁸ẊU-¦Ẋ
A monadic link accepting a list of lists of characters (a stub of 0 cards or a full-deck of 52 cards with one card reversed) and returning a list of lists of characters (a stub of the 1 reversed card but forward or a full-deck with one random card reversed).
Try it online! (footer to make input and output representations match - as a full program Jelly code Python-evals the argument and smashes the characters together for the output)
How?
9ḊṾ€;“AJKQT”p“CDHS”ḟ⁸ẊU-¦Ẋ - Link: list of lists of characters, Z
9Ḋ - nine dequeued = [2,3,4,5,6,7,8,9]
Ṿ€ - unevaluate €ach = ['2','3','4','5','6','7','8','9']
“AJKQT” - literal list of characters = ['A','J','K','Q','T']
; - concatenate = ['2','3','4','5','6','7','8','9','A','J','K','Q','T']
“CDHS” - literal list of characters = ['C','D','H','S']
p - Cartesian product = [['2','C'],['2','D'],...,['T','S']]
- a full deck of forward cards
⁸ - chain's left argument, Z
ḟ - filter discard
- leaving either that deck or the 1 reversed card in the input
Ẋ - shuffle
¦ - sparse application...
- - ...to index: -1 (which doesn't exist when the length is only 1)
U - ...do: upend (reverses the penultimate card of the deck)
Ẋ - shuffle
Pyth, 45 bytes
J"CDHS"KO52=NsM.S*+c"AKQJT"1S9J|f}hTJQXNK_@NK
Takes the empty list for empty input.
Try it online
Explanation
J"CDHS"KO52=NsM.S*+c"AKQJT"1S9J|f}hTJQXNK_@NK
J"CDHS" Save the suits as J.
KO52 Save a random index as K.
=NsM.S*+c"AKQJT"1S9J Save a shuffled deck as N.
f}hTJQ Find all cards with suit first.
| XNK_@NK If there aren't any, flip a card.
><>, 215 193 bytes
i:0)?\~"CHSD":"2"$:"3"$:"4"$:"5"$:"6"$:"7"$:"8"$:"9"$:"T"$:"J"$:"Q"$:"K"$:"A"$&105&"S"=?.~~~{c0.
=+i$?\i$:::"B")$"I"(*$"S"
_oo$~/;
x0
x0
x0
x0
x0
x0
x0
x0
x0
x0
\l&>?!<
>&"3"%:?\~$>o<
\ }}&-1/
Takes input as not separated cards, and output as the same (e.g. KCAC5C6S...)
To make it easier to test, here's a version that takes input as comma separated and outputs as newline separated.
All the x0s are just an attempt to make a semi-uniform random number generator. More of them increases the range of possible values, and the opposite for less. 10 of them is where I judged it to be random enough.
Note that it follows the rules in that:
- All cards have an equal chance of being selected to be reversed.
- All cards have an equal chance of appearing anywhere in the shuffled deck.
But not all shuffled combinations are possible outputs (and in fact, the vast majority aren't).
Java 8, 275 274 259 bytes
import java.util.*;s->{if(s==null){List l=new Stack();char i=52,r=i,x,y;for(r*=Math.random();i-->0;y="23456789TJQKA".charAt(i%13),l.add(i==r?x+""+y:y+""+x))x="HSDC".charAt(i&3);Collections.shuffle(l);return l;}return s.replaceAll(".*,(.)([^HSDC]).*","$2$1");}
Input is a String, output is either a String or a java.util.List depending on the input.
Explanation:
import java.util.*; // Required import for List, Stack and Collections
s->{ // Method with String parameter and Object return-type
if(s==null){ // If the input is `null`:
char i=52, // Index-integer
r=i, // Random-integer
x,y; // Temp characters
List l=new Stack(); // Create a List
for(r*=Math.random(); // Determine the random integer in the range (0;52]
i-->0 // Loop `i` 52 times:
; // After every iteration:
y="23456789TJQKA".charAt(i%13)
// Set `y` to one of 23456789TJQKA based on `i` modulo-13
,l.add(i==r? // If the random integer equals the current `i`
x+""+y // Add the current card reversed
: // Else:
y+""+x)) // Add the current card as is
x="HSDC".charAt(i&3); // Set `x` to one of HSDC based on `i` bitwise-AND 3
Collections.shuffle(l); // Shuffle the generated Deck
return l;} // And return this Deck as result
// If the input was a Deck instead:
return s.replaceAll(".*,(.)([^HSDC]).*",
// Get the reversed card from the Deck,
"$2$1");} // and output it non-reversed
Retina, 61 60 59 bytes
G`[HCDS].
^$
23456789TJQK
/^2/&L$`.
$&H¶$&D¶$&C¶$&S
@V`
O?`
Try it online! Edit: Saved 1 2 bytes thanks to @MartinEnder. Explanation:
G`[HCDS].
Delete all unreversed cards. This should leave one reversed card or no cards.
^$
23456789TJQK
/^2/&L$`.
$&H¶$&D¶$&C¶$&S
If the input is (now) empty, create a pack of cards.
@V`
Randomly select one card and reverse it (unreverses the single reversed card).
O?`
Shuffle the card(s).
PowerShell v2 or later, 175 bytes
%{$s=[char[]]'SDHC';if($_){$_|?{$s-contains$_[0]}|%{$_[1]+$_[0]}}else{$d=$s|%{$e=$_;[char[]]'23456789TJQKA'|%{$_+$e}}|random -c 52;$r=random 52;$d[$r]=$d[$r][1]+$d[$r][0];$d}}
Long version:
ForEach-Object {
$s = [char[]]'SDHC' # Create a character array with the suits
if ($_) { # If there's pipeline input ...
$_ | # ... write it to the output pipeline ...
Where-Object {$s -contains $_[0]} | # ... but let only those input elements pass where the first letter appears in the suits ...
ForEach-Object {$_[1] + $_[0]} # ... and swap the two elements
} else {
$d = $s | ForEach-Object { # Assign $d to the output of the suits, processing each element first.
$e = $_ # Store the current suit element for use in the inner loop
[char[]]'23456789TJQKA' | ForEach-Object {$_ + $e} # Process each of the numbers, joining it with the current suit, ...
} | Get-Random -Count 52 # ... and the resulting 2-char-strings goes back into the output to be shuffled
$r = Get-Random -Maximum 52
$d[$r] = $d[$r][1] + $d[$r][0] # Swap the two chars of a random array element in $d
$d # Write $d to the output pipeline
}
}
Usage:
Create a shuffled deck and store it in a variable:
$Deck = %{$s=[char[]]'SDHC';if($_){$_|?{$s-contains$_[0]}|%{$_[1]+$_[0]}}else{$d=$s|%{$e=$_;[char[]]'23456789TJQKA'|%{$_+$e}}|random -c 52;$r=random 52;$d[$r]=$d[$r][1]+$d[$r][0];$d}}
Inspect the variable at will, for example
$Deck -join ','
Pipe the deck back into the script:
$Deck | %{$s=[char[]]'SDHC';if($_){$_|?{$s-contains$_[0]}|%{$_[1]+$_[0]}}else{$d=$s|%{$e=$_;[char[]]'23456789TJQKA'|%{$_+$e}}|random -c 52;$r=random 52;$d[$r]=$d[$r][1]+$d[$r][0];$d}}
Python 2, 175 bytes
from random import*
s='SHCD';c='23456789TJQKA'
d=input()
if d:print[b+a for a,b in d if a in s];q
k=sample
r=k(c,1)+k(s,1)
print k([(a+b,b+a)[r==a+b]for a in c for b in s],52)
Try it online! empty input is denoted as []
Ruby, 95 (or 100) bytes
->n{s=(0..51).map{|i|"A23456789TJQK"[i/4]+"HCDS"[i%4]}
n[0]?s-n:s[rand 52].reverse!&&s.shuffle}
Given an empty array as input, returns the deck as an array of strings. Given a nonempty array as input, returns the flipped card as an array containing a single string. If the flipped card is required as a string rather than a single-element array containing a string, the following adds 5 bytes: change s-n to (s-n)[0]
The first line generates a standard deck. The second line breaks down as follows
n[0]? #If the input array is not empty (contains a truthy first element)
s-n: #Find the contents of s with the contents of n removed. The only card remaining from the standard deck corresponds to the flipped card in the input.
#ELSE
s[rand 52].reverse!&& #Flip one card in place in the array s. As the result is truthy, whatever is next will be returned.
s.shuffle #shuffle the deck and return the shuffled deck with one element flipped
}