Given a cribbage hand (six cards), which two cards should you discard to the crib to maximize your chances of getting the best score?
This repo contains implementations in multiple computer languages:
- C
- C++
- Go (golang)
- Nim (nimlang)
- Python
- Rust
- TypeScript
- Julia
Here's a sample run:
$ ./cribbage-cpp "7C 9H 5H 5C 5D JS"
[ JS 5D 5C 7C 5H 9H ]
JS 5D [12.5 3.6 4..29] [-1.4 3.4 -15..8]
JS 5C [12.5 3.6 4..29] [-1.4 3.4 -15..8]
JS 7C [14.6 3.9 8..33] [7.5 3.9 -5..17]
JS 5H [12.5 3.6 4..29] [-1.4 3.4 -15..8]
JS 9H [16.0 4.7 8..35] [7.6 4.0 -9..17]
5D 5C [13.6 4.1 4..32] [-3.9 3.9 -22..6]
5D 7C [15.0 3.5 8..31] [2.5 3.7 -10..13]
5D 5H [13.6 4.1 4..32] [-3.9 3.9 -22..6]
5D 9H [14.6 3.5 8..29] [3.5 3.1 -10..13]
5C 7C [15.1 3.5 8..31] [2.5 3.7 -10..13]
5C 5H [13.6 4.1 4..32] [-3.9 3.9 -22..6]
5C 9H [14.6 3.5 8..29] [3.5 3.1 -10..13]
7C 5H [15.0 3.5 8..31] [2.5 3.7 -10..13]
7C 9H [20.9 4.5 14..41] [12.4 5.5 -10..27]
5H 9H [14.6 3.6 8..29] [3.5 3.1 -10..13]For example:
7C 9H [20.9 4.5 14..41] [12.4 5.5 -10..27]This line says if you discard the seven of clubs (7C) and the nine of hearts (9H) you will get an average score of 20.9 if the crib is yours, or 12.4 if the crib is not yours.
The numbers in brackets (e.g., [16.0 4.7 8..35]) show the mean, standard deviation, minimum and maximum scores. The first set of numbers is for when the crib is yours; the second set, the crib is your opponent's. (A smaller standard deviation means you're more likely to get the average score.)
| Elapsed (s) | Normalized | Language |
|---|---|---|
| 0.69 | 1.0 | c |
| 1.12 | 1.6 | rust |
| 1.13 | 1.6 | cpp |
| 3.68 | 5.3 | julia |
| 6.62 | 9.6 | typescript |
| 6.82 | 9.9 | go |
| 50.43 | 73.1 | nim |
| 114.03 | 165.3 | python |
$ make TIMING=
./cribbage-c 5H-5C-5S-JD-4C-4D
[ 5H 5C 5S JD 4C 4D ]
5H 5C [15.9 4.4 6..39] [-1.2 4.3 -16..13]
5H 5S [15.9 4.4 6..39] [-1.2 4.3 -16..13]
5H JD [16.1 6.0 6..41] [2.4 6.1 -12..22]
5H 4C [16.3 5.2 8..41] [3.1 3.4 -16..13]
5H 4D [16.3 5.2 8..41] [3.1 3.4 -16..13]
5C 5S [15.9 4.4 6..39] [-1.2 4.3 -16..13]
5C JD [16.1 6.0 6..41] [2.4 6.1 -12..22]
5C 4C [16.3 5.2 8..41] [3.0 3.4 -16..13]
5C 4D [16.3 5.2 8..41] [3.1 3.4 -16..13]
5S JD [16.1 6.0 6..41] [2.4 6.1 -12..22]
5S 4C [16.3 5.2 8..41] [3.1 3.4 -16..13]
5S 4D [16.3 5.2 8..41] [3.1 3.4 -16..13]
JD 4C [16.7 5.4 8..38] [9.1 5.1 -5..23]
JD 4D [16.7 5.4 8..38] [9.1 5.2 -7..23]
4C 4D [22.4 4.5 16..53] [10.9 5.1 -10..27]
cd cribbage-rust && cargo build --release --quiet
cribbage-rust/target/release/cribbage 5H-5C-5S-JD-4C-4D
(same output)
./cribbage-cpp 5H-5C-5S-JD-4C-4D
(same output)
node cribbage.js 5H-5C-5S-JD-4C-4D
(same output)
./cribbage-nim 5H-5C-5S-JD-4C-4D
(same output)
./cribbage.py 5H-5C-5S-JD-4C-4D
(same output)
go build -o cribbage-go cribbage.go
./cribbage-go 5H-5C-5S-JD-4C-4D
(same output)
$cribbage.cob is a companion, not a ninth analyzer implementation: it
scores a single cribbage hand (4 hand cards + cut) — fifteens, pairs,
runs, flush, nobs. Written as a dare, compiled with GnuCOBOL 5, and
tested (the 29-hand scores 29).
$ make cribbage-cob
$ echo "5C 5D 5H JS 5S" | ./cribbage-cob
Hand + cut (e.g. 5C 5D 5H JS 5S):
Fifteens: 016
Pairs: 012
Runs: 000
Flush: 00
Nobs: 1
Total: 029cribbage.f90 is the same kind of companion as the COBOL scorer: it
scores a single cribbage hand (4 hand cards + cut). Written in modern
free-form Fortran (2018) and commented for the FORTRAN 77 veteran --
implicit none, whole-array operations, and real bit intrinsics
(BTEST, POPCNT) where the COBOL version had to fake it with
DIVIDE.
$ make cribbage-fortran
$ echo "5C 5D 5H JS 5S" | ./cribbage-fortran
Hand + cut (e.g. 5C 5D 5H JS 5S):
Fifteens: 16
Pairs: 12
Runs: 0
Flush: 0
Nobs: 1
Total: 29cribbage.pas is the same kind of companion: it scores a single
cribbage hand (4 hand cards + cut), written in Free Pascal and
commented for the non-Pascal speaker -- := vs =, subrange types,
begin/end, real bitwise operators, and Pascal's built-in set
type (used to test run distinctness).
$ make cribbage-pascal
$ echo "5C 5D 5H JS 5S" | ./cribbage-pascal
Hand + cut (e.g. 5C 5D 5H JS 5S):
Fifteens: 16
Pairs: 12
Runs: 0
Flush: 0
Nobs: 1
Total: 29cribbage.hs is the same kind of companion: it scores a single
cribbage hand (4 hand cards + cut), written in Haskell and commented
for the non-Haskeller. The whole subset-enumeration machinery
collapses into Data.List.subsequences -- fifteens is a one-liner,
and pairs is the classic group . sort idiom.
$ make cribbage-haskell
$ echo "5C 5D 5H JS 5S" | ./cribbage-haskell
Hand + cut (e.g. 5C 5D 5H JS 5S):
Fifteens: 16
Pairs: 12
Runs: 0
Flush: 0
Nobs: 1
Total: 29