## Bridge Hands

### August 11, 2015

```# bridge - generate random bridge hands

BEGIN { split(permute(52,52), deck)           # generate a random deck
sort(1,13); sort(14,26); sort(27,39); sort(40,52) # sort hands
prhands()                    # format and print the four hands
}

function permute(k, n,    i, p, r) {   # generate a random permutation
srand(); p = " "                   # of k integers between 1 and n
for (i = n-k+1; i <= n; i++)
if (p ~ " " (r = int(i*rand())+1) " " )
sub(" " r " ", " " r " " i " ", p)    # put i after r in p
else p = " " r p                     # put r at beginning of p
return p
}

function sort(left,right,    i,j,t) { # sort hand in deck[left..right]
for (i = left+1; i <= right; i++)
for (j = i; j > left && deck[j-1] < deck[j]; j--) {
t = deck[j-1]; deck[j-1] = deck[j]; deck[j] = t
}
}

function prhands() {                            # print the four hands
b = sprintf("%20s", " "); b40 = sprintf("%40s", " ")
card = 1                                  # global index into deck
suits(13); print b "   NORTH"
print b spds; print b hrts; print b dnds; print b clbs
suits(26)  # create the west hand from deck[14..26]
ws = spds substr(b40, 1, 40 - length(spds))
wh = hrts substr(b40, 1, 40 - length(hrts))
wd = dnds substr(b40, 1, 40 - length(dnds))
wc = clbs substr(b40, 1, 40 - length(clbs))
suits(39); print "   WEST" sprintf("%36s", " ") "EAST"
print ws spds; print wh hrts; print wd dnds; print wc clbs
suits(52); print b "   SOUTH"
print b spds; print b hrts; print b dnds; print b clbs
}

function suits(j) {           # collect suits of hand in deck[j-12..j]
for (spds = "S:"; deck[card] > 39 && card <= j; card++)
spds = spds " " fvcard(deck[card])
for (hrts = "H:"; deck[card] > 26 && card <= j; card++)
hrts = hrts " " fvcard(deck[card])
for (dnds = "D:"; deck[card] > 13 && card <= j; card++)
dnds = dnds " " fvcard(deck[card])
for (clbs = "C:"; card <= j; card++)
clbs = clbs " " fvcard(deck[card])
}

function fvcard(i) {                    # compute face value of card i
if (i % 13 == 0) return "A"
else if (i % 13 == 12) return "K"
else if (i % 13 == 11) return "Q"
else if (i % 13 == 10) return "J"
else return (i % 13) + 1
}
```

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[8] = "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[0]):
print ' '*20 + north
print '{:<40}{:}'.format('WEST', 'EAST')
for west, east in zip(hand_to_string(four_hands[1]), hand_to_string(four_hands[2])):
print '{:<40}{:}'.format(west, east)
for south in hand_to_string(four_hands[3]):
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 […]