## Bridge Hands

### August 11, 2015

[ Thanks to all who wrote with good wishes after my post last Friday. I am fully recovered and back at work. ]

Newspapers and textbooks often print bridge hands in the format shown below, then discuss the proper playing of the hand:

```                    NORTH
S: A Q J 10 8
H: 5 4 2
D: 9
C: 10 7 6 2
WEST                                    EAST
S: 7                                    S: 6
H: Q J 7 6 3                            H: K 10 8
D: J 10 6 4 3                           D: A K Q 5
C: A 8                                  C: K 9 5 4 3
SOUTH
S: K 9 5 4 3 2
H: A 9
D: 8 7 2
C: Q J```

Your task is to write a program to generate random bridge hands and print them in the format shown above. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2 3

### 10 Responses to “Bridge Hands”

1. Paul said

In Python.

```import random
from itertools import groupby
from operator import itemgetter

VALUES = list("23456789TJQKA")
VALUES = "10"

def random_hand():
cards = list(range(52))
random.shuffle(cards)
return [sorted(cards[i*13:i*13+13], reverse=True) for i in range(4)]

def nr_to_card(n):
suit, value = divmod(n, 13)
return "CDHS"[suit], VALUES[value]

def hand(side):
cards = [nr_to_card(c) for c in side]
cc = groupby(cards, key=itemgetter(0))
D = {k:"{:s}: {:s}".format(k, " ".join(v for s, v in g)) for k, g in cc}
return [D[k] if k in D else k + ":" for k in "SHDC"]

def print_bridge(hands):
output = [[" "] * 80 for _ in  range(15)]
pos = [(0, 20), (5, 0), (5, 40), (10, 20)]
seats = ["NORTH", "WEST", "EAST", "SOUTH"]
for (row, col), seat, hand_ in zip(pos, seats, hands):
output[row][col:col+len(seat)] = seat
for i, hi in enumerate(hand(hand_)):
output[row+i+1][col:col+len(hi)] = hi
for o in output:
print ("".join(o))

print_bridge(random_hand())
```
2. Rutger said

Good to see you recovered!
Hereby my Python solution..

```import random

suits = ["S", "H", "D", "C"]
values = ["2","3","4","5","6","7","8","9","10","J","Q","K","A"]

# returns tuples of (suit, value)
def deck(shuffle=True):
def card_number_to_card_tuple(n):
suit, value = divmod(n, 13)
return suits[suit], values[value]

all_cards = range(52)
if shuffle:
random.shuffle(all_cards)
return map(card_number_to_card_tuple, all_cards)

# returns list of 4 hands, with each hand as a dict with k=suit , v=list of values for suit k
def four_hands(deck):
hands = []
for hand in [deck[i*13:i*13+13] for i in range(4)]:
d = dict(zip(suits, [[],[],[],[]]))
for suit, value in hand:
d.setdefault(suit, []).append(value)
hands.append(d)
return hands

# prints output. Spent most time in that python format mini language..
def print_formatted(four_hands):
def hand_to_string(hand):
return [suit + ': ' + " ".join(hand[suit]) for suit in suits]

print ' '*20 + 'NORTH'
for north in hand_to_string(four_hands):
print ' '*20 + north
print '{:<40}{:}'.format('WEST', 'EAST')
for west, east in zip(hand_to_string(four_hands), hand_to_string(four_hands)):
print '{:<40}{:}'.format(west, east)
for south in hand_to_string(four_hands):
print ' '*20 + south

print_formatted(four_hands(deck()))
```
3. Andras said

Scala:
import scala.util.Random
type Card = Tuple2[String, String]
val color: Seq[String] = List(“S”, “H”, “D”, “C”)
val numbers: Seq[String] = (2 to 10 map { _.toString }) ++ List(“J”, “Q”, “K”, “A”)
def numberSorter(a: String, b: String): Boolean = numbers.indexOf(a) > numbers.indexOf(b)
val cards: Seq[Card] = Random.shuffle(for (c <- color; n List(filter(x, “S”), filter(x, “H”), filter(x, “D”), filter(x, “C”)))
val blockLines = blocks.map(x => (List(x._1) ++ x._2).map(x => x + ” ” * (20 – x.length())))
val north = for (i <- 0 to 4) yield " " * 20 + blockLines(0)(i) + " " * 20
val west_east = for (i <- 0 to 4) yield blockLines(1)(i) + " " * 20 + blockLines(2)(i)
val south = for (i <- 0 to 4) yield " " * 20 + blockLines(3)(i) + " " * 20
println((north ++ west_east ++ south).mkString("\r\n"))

4. Andras said

@Paul, @Rutger: could you please tell me how do you insert your code in such a beauty way? Which website do you use?

5. Paul said

@Andras.I am using method Third as mentioned in the “Howto: Posting Source Code”. You have to know the mnemonic for Scala (I guess it is scala). Further the tag is usefull if you want to use a link in your post. I hope this helps.

6. Paul said

@Andras, the “a href” tag messed up part of my reply. You only have to google for this tag and see how it is used.

7. Andras said

@Paul Thanks it works fine!

8. Globules said

```import Data.Function (on)
import Data.List (groupBy, intercalate, sortOn)
import Data.List.Split (chunksOf)
import Data.Maybe (fromMaybe)
import Data.Ord (Down(..))
import System.Random
import System.Random.Shuffle (shuffle')

shuffle :: (RandomGen r) => [a] -> r -> [a]
shuffle xs = shuffle' xs (length xs)

-- A standard deck of 52 cards, where each card is a pair consisting of a suit
-- and a rank.
deck :: [(Int, Int)]
deck = [(s, r) | s <- [0..3], r <- [0..12]]

-- Deal hands of 13 cards.  Each hand consists of ordered lists of ranks grouped
-- by suit.
deal :: [(Int, Int)] -> [[(Int, [Int])]]
deal = map (map suitify . groupBy ((==) `on` fst) . sortOn Down) . chunksOf 13

showSuit :: Int -> String
showSuit = (["S", "H", "D", "C"] !!)

showRank :: Int -> String
showRank = (ranks !!)
where ranks = [ "2", "3",  "4", "5", "6", "7",
"8", "9", "10", "J", "Q", "K", "A"]

-- Each element of the result is one suit letter followed by the card ranks.
showHand :: [(Int, [Int])] -> [String]
showHand cs = map (\s -> showSuit s ++ ": " ++ showRanks (ranks s)) [0..3]
where ranks s = fromMaybe [] \$ lookup s cs
showRanks = unwords . map showRank

printHand :: [String] -> IO ()
printHand = putStrLn . intercalate "\n"

-- Pad all the strings to the length of the longest.
padR xs = let maxLen = maximum \$ map length xs
where padTo mx s = s ++ replicate (mx - length s) ' '

-- Prepend all the strings with spaces.
padL :: Int -> [String] -> [String]
padL n = map (replicate n ' ' ++)

-- Append corresponding elements of the lists.
followedBy :: [[a]] -> [[a]] -> [[a]]
followedBy = zipWith (++)

main :: IO ()
main = do
hands <- liftM (map showHand . deal . shuffle deck) getStdGen
let [n, s, e, w] = zipWith (:) ["NORTH", "SOUTH", "EAST", "WEST"] hands
```
```\$ ./bridge
NORTH
S: K Q 9 5
H: Q 10
D: K 9 8 3
C: 6 5 4
WEST                                     EAST
S: A 10 8 7                              S: J 6 3
H: K 8 2                                 H: J 9 7 6 3
D: 6 4                                   D: Q J 7
C: 9 8 3 2                               C: A Q
SOUTH
S: 4 2
H: A 5 4
D: A 10 5 2
C: K J 10 7
```
9. […] Bridge hands problem in C++ […]

10. […] bridge hands problem on programming praxis in Common […]