Combinatorics#
Programming Environment#
Show code cell source
import numpy as np
from collections import Counter
import itertools
from itertools import (chain,
combinations,
combinations_with_replacement,
permutations,
product)
#dir(itertools)
import math
import string
def powerset (iterable):
"""powerset([1,2,3]) ---> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"""
s=list(iterable)
return chain.from_iterable(combinations(s,r) for r in range(len(s)+1))
Counting#
In discrete mathematics, the goal is to count the number of elements in (or the cardinality of) a finite set given a description of the set.
Determining a set’s cardinality often requires exploiting some mathematical structure of the set.
A pizzeria sells 6 different varieties of pizza \(\{0,1,2,3,4,5\}\).
How many ways are there to fill an order of 24 slices from the 6 varieties?
The order in which the slices are selected is unimportant; all that matters is the number of each variety in the order after they are chosen.
118755
p=set(range(6))
p
{0, 1, 2, 3, 4, 5}
Definition: Product Rule#
A={0,1}
B={2,3}
C={4,5,6}
list(product(A,B,C))
[(0, 2, 4),
(0, 2, 5),
(0, 2, 6),
(0, 3, 4),
(0, 3, 5),
(0, 3, 6),
(1, 2, 4),
(1, 2, 5),
(1, 2, 6),
(1, 3, 4),
(1, 3, 5),
(1, 3, 6)]
If \(\Sigma\) is a set of characters, called an alphabet, then \(\Sigma^n\) is the set of all strings of length \(n\) whose characters come from the set \(\Sigma\).
If \(\Sigma=\{0,1\}\), then \(\Sigma^6\) is the set of all binary strings with \(6\) bits.
The string \(011101\) is an example of an element in \(\Sigma^6\).
The strings \(xxyzx\) and \(zyyzy\) are examples of strings in the set \(\{x,y,z\}^5\).
The product rule is used to determine the number of strings of a given length over a finite alphabet:
\( \begin{aligned} |\Sigma^n| = | \underbrace{\Sigma \times \Sigma \times \dotsb \times \Sigma}_{n\,\text{times}} | = \underbrace{|\Sigma| \times |\Sigma| \times \dotsb \times |\Sigma|}_{n\,\text{times}} = |\Sigma|^n \end{aligned} \)
The number of binary strings of length \(n\) is \(2^n\) since the size of the alphabet is \(2=|\{0,1\}|\).
list(product({0},{0,1},{0,1},{0,1},{0}))
[(0, 0, 0, 0, 0),
(0, 0, 0, 1, 0),
(0, 0, 1, 0, 0),
(0, 0, 1, 1, 0),
(0, 1, 0, 0, 0),
(0, 1, 0, 1, 0),
(0, 1, 1, 0, 0),
(0, 1, 1, 1, 0)]
len(list(product({0,1},repeat=6)))
64
len(list(product({0},{1},{0,1},{0,1},{0,1},{0,1})))
16
len(list(product({'a','b','c'},repeat=4)))
81
len(list(product({'a','b','c'},
{'a','b','c'},
{'a','b','c'},
{'c'})))
27
Definition: Sum Rule#
L=set(string.ascii_lowercase)
D=set(string.digits)
C=D.union(L)
print(sorted(L))
print(sorted(D))
print(sorted(C))
print(f"{36**6+36**7+36**8:,}")
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
2,901,650,853,888
S={'14 in','15 in','16 in'}
P={'2.0 GHz','2.7 GHz'}
h={'128 G hdd','256 G hdd','512 G hdd'}
s={'256 G ssd','512 G ssd'}
len(list(product(S,P,h.union(s))))
30
A=set(product({1},{0,1},{0,1},{0,1},{0,1},{1}))
B=set(product({0},{0},{0,1},{0,1},{0,1},{0,1}))
C=len(A)+len(B)
C
32
b5=set(product({1},{0,1},{0,1},{0,1},{0,1}))
b6=set(product({1},{0,1},{0,1},{0,1},{0,1},{0,1}))
len(b5)+len(b6)
48
D=set(string.digits)
L=set(string.ascii_lowercase)
C=D.union(L)
for n in [9,10,12,15,17,20]:
print(f"{'Passwords':<20}{len(C)}^{n:<5}= {len(C)**n:,}")
Passwords 36^9 = 101,559,956,668,416
Passwords 36^10 = 3,656,158,440,062,976
Passwords 36^12 = 4,738,381,338,321,616,896
Passwords 36^15 = 221,073,919,720,733,357,899,776
Passwords 36^17 = 286,511,799,958,070,431,838,109,696
Passwords 36^20 = 13,367,494,538,843,734,067,838,845,976,576
D=set(string.digits)
L=set(string.ascii_lowercase)
S={'*','&','$','#'}
C=D.union(L).union(S)
for n in [6,7,8,9]:
print(f"{'Passwords':<20}{len(C)}^{n:<5}= {len(C)**n:,}")
Passwords 40^6 = 4,096,000,000
Passwords 40^7 = 163,840,000,000
Passwords 40^8 = 6,553,600,000,000
Passwords 40^9 = 262,144,000,000,000
Definition: Bijection Rule#
Claim: the number of subsets of an \(n\)-element set is equal to the number of length-\(n\) bit strings#
X='abc'
P=list(powerset(X))
P
[(),
('a',),
('b',),
('c',),
('a', 'b'),
('a', 'c'),
('b', 'c'),
('a', 'b', 'c')]
for p in P:
z=np.array(['0']*len(X))
z[[X.index(i) for i in p]]=1
print(''.join(z))
000
100
010
001
110
101
011
111
Definition: \(k\)-to-\(1\) Correspondence#
Definition: \(k\)-to-\(1\) Rule#
for x in range(1,31):
print(f"{'x = '}{x:<5}{'y = '}{int(np.ceil(x/3))}")
x = 1 y = 1
x = 2 y = 1
x = 3 y = 1
x = 4 y = 2
x = 5 y = 2
x = 6 y = 2
x = 7 y = 3
x = 8 y = 3
x = 9 y = 3
x = 10 y = 4
x = 11 y = 4
x = 12 y = 4
x = 13 y = 5
x = 14 y = 5
x = 15 y = 5
x = 16 y = 6
x = 17 y = 6
x = 18 y = 6
x = 19 y = 7
x = 20 y = 7
x = 21 y = 7
x = 22 y = 8
x = 23 y = 8
x = 24 y = 8
x = 25 y = 9
x = 26 y = 9
x = 27 y = 9
x = 28 y = 10
x = 29 y = 10
x = 30 y = 10
B =set('01')
n =3
Bn={''.join(c) for c in set(product(B,repeat=n))}
Pn={b+b[::-1] for b in Bn}
Pn
{'000000',
'001100',
'010010',
'011110',
'100001',
'101101',
'110011',
'111111'}
B =set('01')
n =4
Bn={''.join(c) for c in set(product(B,repeat=n))}
Pn={b+b[2::-1] for b in Bn}
Pn
{'0000000',
'0001000',
'0010100',
'0011100',
'0100010',
'0101010',
'0110110',
'0111110',
'1000001',
'1001001',
'1010101',
'1011101',
'1100011',
'1101011',
'1110111',
'1111111'}
B =set('01')
n =9
Bn={''.join(c) for c in set(product(B,repeat=n))}
Bn_arr=np.array(list(list(codeword) for codeword in sorted(Bn)),dtype=np.int8)
En={''.join(codeword) for codeword in np.concatenate([Bn_arr,(Bn_arr.sum(axis=1)%2).reshape((Bn_arr.shape[0],1))],axis=1).astype(str)}
En
{'0000000000',
'0000000011',
'0000000101',
'0000000110',
'0000001001',
'0000001010',
'0000001100',
'0000001111',
'0000010001',
'0000010010',
'0000010100',
'0000010111',
'0000011000',
'0000011011',
'0000011101',
'0000011110',
'0000100001',
'0000100010',
'0000100100',
'0000100111',
'0000101000',
'0000101011',
'0000101101',
'0000101110',
'0000110000',
'0000110011',
'0000110101',
'0000110110',
'0000111001',
'0000111010',
'0000111100',
'0000111111',
'0001000001',
'0001000010',
'0001000100',
'0001000111',
'0001001000',
'0001001011',
'0001001101',
'0001001110',
'0001010000',
'0001010011',
'0001010101',
'0001010110',
'0001011001',
'0001011010',
'0001011100',
'0001011111',
'0001100000',
'0001100011',
'0001100101',
'0001100110',
'0001101001',
'0001101010',
'0001101100',
'0001101111',
'0001110001',
'0001110010',
'0001110100',
'0001110111',
'0001111000',
'0001111011',
'0001111101',
'0001111110',
'0010000001',
'0010000010',
'0010000100',
'0010000111',
'0010001000',
'0010001011',
'0010001101',
'0010001110',
'0010010000',
'0010010011',
'0010010101',
'0010010110',
'0010011001',
'0010011010',
'0010011100',
'0010011111',
'0010100000',
'0010100011',
'0010100101',
'0010100110',
'0010101001',
'0010101010',
'0010101100',
'0010101111',
'0010110001',
'0010110010',
'0010110100',
'0010110111',
'0010111000',
'0010111011',
'0010111101',
'0010111110',
'0011000000',
'0011000011',
'0011000101',
'0011000110',
'0011001001',
'0011001010',
'0011001100',
'0011001111',
'0011010001',
'0011010010',
'0011010100',
'0011010111',
'0011011000',
'0011011011',
'0011011101',
'0011011110',
'0011100001',
'0011100010',
'0011100100',
'0011100111',
'0011101000',
'0011101011',
'0011101101',
'0011101110',
'0011110000',
'0011110011',
'0011110101',
'0011110110',
'0011111001',
'0011111010',
'0011111100',
'0011111111',
'0100000001',
'0100000010',
'0100000100',
'0100000111',
'0100001000',
'0100001011',
'0100001101',
'0100001110',
'0100010000',
'0100010011',
'0100010101',
'0100010110',
'0100011001',
'0100011010',
'0100011100',
'0100011111',
'0100100000',
'0100100011',
'0100100101',
'0100100110',
'0100101001',
'0100101010',
'0100101100',
'0100101111',
'0100110001',
'0100110010',
'0100110100',
'0100110111',
'0100111000',
'0100111011',
'0100111101',
'0100111110',
'0101000000',
'0101000011',
'0101000101',
'0101000110',
'0101001001',
'0101001010',
'0101001100',
'0101001111',
'0101010001',
'0101010010',
'0101010100',
'0101010111',
'0101011000',
'0101011011',
'0101011101',
'0101011110',
'0101100001',
'0101100010',
'0101100100',
'0101100111',
'0101101000',
'0101101011',
'0101101101',
'0101101110',
'0101110000',
'0101110011',
'0101110101',
'0101110110',
'0101111001',
'0101111010',
'0101111100',
'0101111111',
'0110000000',
'0110000011',
'0110000101',
'0110000110',
'0110001001',
'0110001010',
'0110001100',
'0110001111',
'0110010001',
'0110010010',
'0110010100',
'0110010111',
'0110011000',
'0110011011',
'0110011101',
'0110011110',
'0110100001',
'0110100010',
'0110100100',
'0110100111',
'0110101000',
'0110101011',
'0110101101',
'0110101110',
'0110110000',
'0110110011',
'0110110101',
'0110110110',
'0110111001',
'0110111010',
'0110111100',
'0110111111',
'0111000001',
'0111000010',
'0111000100',
'0111000111',
'0111001000',
'0111001011',
'0111001101',
'0111001110',
'0111010000',
'0111010011',
'0111010101',
'0111010110',
'0111011001',
'0111011010',
'0111011100',
'0111011111',
'0111100000',
'0111100011',
'0111100101',
'0111100110',
'0111101001',
'0111101010',
'0111101100',
'0111101111',
'0111110001',
'0111110010',
'0111110100',
'0111110111',
'0111111000',
'0111111011',
'0111111101',
'0111111110',
'1000000001',
'1000000010',
'1000000100',
'1000000111',
'1000001000',
'1000001011',
'1000001101',
'1000001110',
'1000010000',
'1000010011',
'1000010101',
'1000010110',
'1000011001',
'1000011010',
'1000011100',
'1000011111',
'1000100000',
'1000100011',
'1000100101',
'1000100110',
'1000101001',
'1000101010',
'1000101100',
'1000101111',
'1000110001',
'1000110010',
'1000110100',
'1000110111',
'1000111000',
'1000111011',
'1000111101',
'1000111110',
'1001000000',
'1001000011',
'1001000101',
'1001000110',
'1001001001',
'1001001010',
'1001001100',
'1001001111',
'1001010001',
'1001010010',
'1001010100',
'1001010111',
'1001011000',
'1001011011',
'1001011101',
'1001011110',
'1001100001',
'1001100010',
'1001100100',
'1001100111',
'1001101000',
'1001101011',
'1001101101',
'1001101110',
'1001110000',
'1001110011',
'1001110101',
'1001110110',
'1001111001',
'1001111010',
'1001111100',
'1001111111',
'1010000000',
'1010000011',
'1010000101',
'1010000110',
'1010001001',
'1010001010',
'1010001100',
'1010001111',
'1010010001',
'1010010010',
'1010010100',
'1010010111',
'1010011000',
'1010011011',
'1010011101',
'1010011110',
'1010100001',
'1010100010',
'1010100100',
'1010100111',
'1010101000',
'1010101011',
'1010101101',
'1010101110',
'1010110000',
'1010110011',
'1010110101',
'1010110110',
'1010111001',
'1010111010',
'1010111100',
'1010111111',
'1011000001',
'1011000010',
'1011000100',
'1011000111',
'1011001000',
'1011001011',
'1011001101',
'1011001110',
'1011010000',
'1011010011',
'1011010101',
'1011010110',
'1011011001',
'1011011010',
'1011011100',
'1011011111',
'1011100000',
'1011100011',
'1011100101',
'1011100110',
'1011101001',
'1011101010',
'1011101100',
'1011101111',
'1011110001',
'1011110010',
'1011110100',
'1011110111',
'1011111000',
'1011111011',
'1011111101',
'1011111110',
'1100000000',
'1100000011',
'1100000101',
'1100000110',
'1100001001',
'1100001010',
'1100001100',
'1100001111',
'1100010001',
'1100010010',
'1100010100',
'1100010111',
'1100011000',
'1100011011',
'1100011101',
'1100011110',
'1100100001',
'1100100010',
'1100100100',
'1100100111',
'1100101000',
'1100101011',
'1100101101',
'1100101110',
'1100110000',
'1100110011',
'1100110101',
'1100110110',
'1100111001',
'1100111010',
'1100111100',
'1100111111',
'1101000001',
'1101000010',
'1101000100',
'1101000111',
'1101001000',
'1101001011',
'1101001101',
'1101001110',
'1101010000',
'1101010011',
'1101010101',
'1101010110',
'1101011001',
'1101011010',
'1101011100',
'1101011111',
'1101100000',
'1101100011',
'1101100101',
'1101100110',
'1101101001',
'1101101010',
'1101101100',
'1101101111',
'1101110001',
'1101110010',
'1101110100',
'1101110111',
'1101111000',
'1101111011',
'1101111101',
'1101111110',
'1110000001',
'1110000010',
'1110000100',
'1110000111',
'1110001000',
'1110001011',
'1110001101',
'1110001110',
'1110010000',
'1110010011',
'1110010101',
'1110010110',
'1110011001',
'1110011010',
'1110011100',
'1110011111',
'1110100000',
'1110100011',
'1110100101',
'1110100110',
'1110101001',
'1110101010',
'1110101100',
'1110101111',
'1110110001',
'1110110010',
'1110110100',
'1110110111',
'1110111000',
'1110111011',
'1110111101',
'1110111110',
'1111000000',
'1111000011',
'1111000101',
'1111000110',
'1111001001',
'1111001010',
'1111001100',
'1111001111',
'1111010001',
'1111010010',
'1111010100',
'1111010111',
'1111011000',
'1111011011',
'1111011101',
'1111011110',
'1111100001',
'1111100010',
'1111100100',
'1111100111',
'1111101000',
'1111101011',
'1111101101',
'1111101110',
'1111110000',
'1111110011',
'1111110101',
'1111110110',
'1111111001',
'1111111010',
'1111111100',
'1111111111'}
T =set('012')
n =6
T5 ={''.join(c) for c in set(product(T,repeat=n-1))}
T5_arr=np.array(list(list(codeword) for codeword in sorted(T5)),dtype=np.int8)
T6b={''.join(codeword) for codeword in np.concatenate([T5_arr,((3-T5_arr.sum(axis=1))%3).reshape((T5_arr.shape[0],1))],axis=1).astype(str)}
T6b
{'000000',
'000012',
'000021',
'000102',
'000111',
'000120',
'000201',
'000210',
'000222',
'001002',
'001011',
'001020',
'001101',
'001110',
'001122',
'001200',
'001212',
'001221',
'002001',
'002010',
'002022',
'002100',
'002112',
'002121',
'002202',
'002211',
'002220',
'010002',
'010011',
'010020',
'010101',
'010110',
'010122',
'010200',
'010212',
'010221',
'011001',
'011010',
'011022',
'011100',
'011112',
'011121',
'011202',
'011211',
'011220',
'012000',
'012012',
'012021',
'012102',
'012111',
'012120',
'012201',
'012210',
'012222',
'020001',
'020010',
'020022',
'020100',
'020112',
'020121',
'020202',
'020211',
'020220',
'021000',
'021012',
'021021',
'021102',
'021111',
'021120',
'021201',
'021210',
'021222',
'022002',
'022011',
'022020',
'022101',
'022110',
'022122',
'022200',
'022212',
'022221',
'100002',
'100011',
'100020',
'100101',
'100110',
'100122',
'100200',
'100212',
'100221',
'101001',
'101010',
'101022',
'101100',
'101112',
'101121',
'101202',
'101211',
'101220',
'102000',
'102012',
'102021',
'102102',
'102111',
'102120',
'102201',
'102210',
'102222',
'110001',
'110010',
'110022',
'110100',
'110112',
'110121',
'110202',
'110211',
'110220',
'111000',
'111012',
'111021',
'111102',
'111111',
'111120',
'111201',
'111210',
'111222',
'112002',
'112011',
'112020',
'112101',
'112110',
'112122',
'112200',
'112212',
'112221',
'120000',
'120012',
'120021',
'120102',
'120111',
'120120',
'120201',
'120210',
'120222',
'121002',
'121011',
'121020',
'121101',
'121110',
'121122',
'121200',
'121212',
'121221',
'122001',
'122010',
'122022',
'122100',
'122112',
'122121',
'122202',
'122211',
'122220',
'200001',
'200010',
'200022',
'200100',
'200112',
'200121',
'200202',
'200211',
'200220',
'201000',
'201012',
'201021',
'201102',
'201111',
'201120',
'201201',
'201210',
'201222',
'202002',
'202011',
'202020',
'202101',
'202110',
'202122',
'202200',
'202212',
'202221',
'210000',
'210012',
'210021',
'210102',
'210111',
'210120',
'210201',
'210210',
'210222',
'211002',
'211011',
'211020',
'211101',
'211110',
'211122',
'211200',
'211212',
'211221',
'212001',
'212010',
'212022',
'212100',
'212112',
'212121',
'212202',
'212211',
'212220',
'220002',
'220011',
'220020',
'220101',
'220110',
'220122',
'220200',
'220212',
'220221',
'221001',
'221010',
'221022',
'221100',
'221112',
'221121',
'221202',
'221211',
'221220',
'222000',
'222012',
'222021',
'222102',
'222111',
'222120',
'222201',
'222210',
'222222'}
Definition: Generalized Product Rule#
Definition: r-Permutation#
X={'John','Paul','George','Ringo'}
list(permutations(X,r=3))
[('John', 'Paul', 'Ringo'),
('John', 'Paul', 'George'),
('John', 'Ringo', 'Paul'),
('John', 'Ringo', 'George'),
('John', 'George', 'Paul'),
('John', 'George', 'Ringo'),
('Paul', 'John', 'Ringo'),
('Paul', 'John', 'George'),
('Paul', 'Ringo', 'John'),
('Paul', 'Ringo', 'George'),
('Paul', 'George', 'John'),
('Paul', 'George', 'Ringo'),
('Ringo', 'John', 'Paul'),
('Ringo', 'John', 'George'),
('Ringo', 'Paul', 'John'),
('Ringo', 'Paul', 'George'),
('Ringo', 'George', 'John'),
('Ringo', 'George', 'Paul'),
('George', 'John', 'Paul'),
('George', 'John', 'Ringo'),
('George', 'Paul', 'John'),
('George', 'Paul', 'Ringo'),
('George', 'Ringo', 'John'),
('George', 'Ringo', 'Paul')]
Claim: about the number of \(r\)-permutations from a set with \(n\) elements#
E={'Sue','Dave','Chuck','Rajiv','Candace','Jeremy','Nelson','Maureen'}
len(list(permutations(E,r=5)))
6720
Definition: Permutation#
S=set('abc')
list(permutations(S))
[('c', 'a', 'b'),
('c', 'b', 'a'),
('a', 'c', 'b'),
('a', 'b', 'c'),
('b', 'c', 'a'),
('b', 'a', 'c')]
S=set(range(6))
len(list(permutations(S)))
720
S=set(range(3))
len(list(permutations(S)))*2
12
S=set(range(5))
len(list(permutations(S)))*2
240
len(sorted(product({'8'},{'2'},{'4','5'},set(string.digits),set(string.digits),set(string.digits),set(string.digits))))
20000
2*len(list(permutations(set(string.digits),r=4)))
10080
Definition: \(r\)-Combination#
S=set('abc')
print(list(permutations(S,r=2)))
print(list(combinations(S,r=2)))
[('c', 'a'), ('c', 'b'), ('a', 'c'), ('a', 'b'), ('b', 'c'), ('b', 'a')]
[('c', 'a'), ('c', 'b'), ('a', 'b')]
Definition: General Rule for Counting \(r\)-Permutations#
Figures#
[ w ]
1848-1911
Schubert, Hermann[ w ]
1249-1314
Shijie, Zhu[ w ]
1735-1796
Vandermonde, Alexandre-Théophile[ w ]
1873-1940
Young, Alfred
Terms#
[ w ] Cardinality
[ w ] Combination
[ w ] Combinatorics
[ w ] Countability
[ w ] Counting
[ w ] Double Counting
[ w ] Enumerative Combinatorics
[ w ] Falling Factorial
[ w ] Partition
[ w ] Pascal’s Rule
[ w ] Pascal’s Triangle
[ w ] Permutation
[ w ] Permutation Parity
[ w ] q-Analog
[ w ] q-Vandermonde Identity
[ w ] Schubert Calculus
[ w ] Uncountability
[ w ] Vandermonde’s Identity
[ w ] Young Tableau