"Let $S = \\{0,1\\}^*$ be the set of all strings of zero and ones, which includes the empty string $\\epsilon$.\n",
"Let $h : S \\rightarrow \\mathbb{Z}^*$ be the function defined by $h(x)$ equal the number of zeros in $x$ multiplied by the number of ones in $x$\n",
"For example, $h(00100011) = 5 \\times 3 = 15, and h(111) = 0 \\times 3 = 0$\n",
"\n",
"(a) Is $h$ one-to-one? No, because both strings $001$ and $110$ map to the same value, $2$\n",
"$2 \\times 1 = 2$ and $1 \\times 2 = 2$\n",
"\n",
"(b) Is $h$ onto? Yes, because you can find every non-negative integer by multiplying any number of ones by one zero $(1 \\times 1), (1 \\times 2), ...$\n",
"Let the number of zeros be exactly 1, and n be the number of ones, and m be any non-negative integer\n",
"$a + b = 2n$, and $b + c = 2p$, then $b = 2n - a$ and $b = 2p - c$\n",
"$-2n + a = 2p - c$\n",
"$a + c = 2p + 2n$\n",
"Since the sum of a and c is the sum of two even numbers (numbers multiplied by 2 must be even), then the result must be even, so the result is divisible by 2\n",
"There are 7 equivalence classes as the results are grouped by the integer returned by $n_0(x) - n_1(x)$/$n_0(y) - n_1(y)$ for any relation pair, the results are that being set of differences $\\{-3, -2, -1, 0, 1, 2, 3\\}$"
],
"metadata": {
"collapsed": false
},
"id": "fd69c73a15e8e6a0"
},
{
"cell_type": "code",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{-3: [('111', '111')],\n",
" -2: [('11', '11')],\n",
" -1: [('1', '1'),\n",
" ('1', '011'),\n",
" ('1', '101'),\n",
" ('1', '110'),\n",
" ('011', '1'),\n",
" ('011', '011'),\n",
" ('011', '101'),\n",
" ('011', '110'),\n",
" ('101', '1'),\n",
" ('101', '011'),\n",
" ('101', '101'),\n",
" ('101', '110'),\n",
" ('110', '1'),\n",
" ('110', '011'),\n",
" ('110', '101'),\n",
" ('110', '110')],\n",
" 0: [('', ''),\n",
" ('', '01'),\n",
" ('', '10'),\n",
" ('01', ''),\n",
" ('01', '01'),\n",
" ('01', '10'),\n",
" ('10', ''),\n",
" ('10', '01'),\n",
" ('10', '10')],\n",
" 1: [('0', '0'),\n",
" ('0', '001'),\n",
" ('0', '010'),\n",
" ('0', '100'),\n",
" ('001', '0'),\n",
" ('001', '001'),\n",
" ('001', '010'),\n",
" ('001', '100'),\n",
" ('010', '0'),\n",
" ('010', '001'),\n",
" ('010', '010'),\n",
" ('010', '100'),\n",
" ('100', '0'),\n",
" ('100', '001'),\n",
" ('100', '010'),\n",
" ('100', '100')],\n",
" 2: [('00', '00')],\n",
" 3: [('000', '000')]}\n"
]
}
],
"source": [
"# Set of all strings containing 0 and 1 up to length 3\n",
"# The relation is valid if the number of zeros from string x minus the number of ones from string x is equal to the number of zeros from string y minus the number of ones from string y\n",
"def is_valid_relation(_x, _y):\n",
"\t# Count the number of zeros and ones in each string\n",
"\tx_zeros = _x.count('0')\n",
"\tx_ones = _x.count('1')\n",
"\ty_zeros = _y.count('0')\n",
"\ty_ones = _y.count('1')\n",
"\n",
"\t# Return true if the difference between the number of zeros and ones is equal\n",