This commit is contained in:
Peter Norvig 2022-12-14 01:00:38 -08:00 committed by GitHub
parent 778f22dbde
commit 798045e624
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1778,7 +1778,9 @@
"source": [
"#### Part 1: Determine which pairs of packets are already in the right order. What is the sum of the indices of those pairs?\n",
"\n",
"The notion of \"right order\" is almost the same as \"less than\", except that an integer is equal to a singleton list. Also, I was confused for a bit because the rules don't say whether two identical lists are in the right order or not; the rules just say you should \"continue checking\" in that case. I decided that I should not define a Boolean truth predicate; rather it should be a *ternary* comparison function. By convention, a Python comparison function, `compare(left, right)`, returns a negative number if `left < right`, zero if they are equal, and a positive number if `left > right`. I'll implement that:"
"The notion of \"right order\" is almost the same as \"less than\", except that an integer can match against a singleton list. Also, I was confused for a bit because the rules don't say whether two identical lists are in the right order or not; the rules just say you should \"continue checking\" in that case. I decided that I should not define a Boolean truth predicate; rather it should be a *ternary* comparison function. \n",
"\n",
"By convention, a Python comparison function, `compare(left, right)`, returns a negative number if `left < right`, zero if they are equal, and a positive number if `left > right`. I'll implement that:"
]
},
{
@ -1791,18 +1793,18 @@
" \"\"\"Are the two packets in the right order? \n",
" Negative number for right order; 0 for equal; positive for wrong order.\"\"\"\n",
" types = (type(left), type(right))\n",
" if types == (int, int): return left - right\n",
" elif types == (int, list): return compare([left], right)\n",
" elif types == (list, int): return compare(left, [right])\n",
" elif types == (list, list): return first_true(map(compare, left, right), \n",
" default=len(left) - len(right))"
" if types == (int, int): return left - right\n",
" elif types == (int, list): return compare([left], right)\n",
" elif types == (list, int): return compare(left, [right])\n",
" elif types == (list, list): return first_true(map(compare, left, right), \n",
" default=len(left) - len(right))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The call to `first_true` (from my [AdventUtils](AdventUtils.ipynb) or from [itertools recipes](https://docs.python.org/3/library/itertools.html#itertools-recipes)) says to `compare` respective successive elements of the two lists one by one, and to return the first true (i.e. non-zero) comparison, or if one of the two lists is exhausted first, return the comparison of the list lengths. \n",
"The call to `first_true` (from my [AdventUtils](AdventUtils.ipynb)) says to `compare` respective successive elements of the two lists one by one, and to return the first truthy (i.e. non-zero) comparison, or if one of the two lists is exhausted first, return the comparison of the list lengths. \n",
"\n",
"I threw in some test cases to gain some confidence that I got it right: "
]
@ -1850,9 +1852,9 @@
"source": [
"#### Part 2: Organize all of the packets into the correct order. What is the decoder key for the distress signal?\n",
"\n",
"This should be easy; all I have to do is sort using `right_order`, then look up the resulting indices of the two divider packets (taking care to use 1-based rather than 0-based indexing). I tried to sort using `key=right_order` and got an error message reminding me how foolish I am: `right_order` is not a key function (of one argument), it is a comparison function (of two arguments).\n",
"This should be easy; all I have to do is sort using `compare`, then look up the resulting indices of the two divider packets (taking care to use 1-based rather than 0-based indexing). I tried to sort using `key=compare` and got an error message reminding me how foolish I am: `compare` is not a key function (of one argument), it is a comparison function (of two arguments).\n",
"\n",
"In Python 2, the `sorted` function did accept a two-argument `cmp` function, but in Python 3 that functionality is gone. I had to look it up to find that the `functools.cmp_to_key` function converts a comparison function to a key function, and that a `cmp_to_key` comparison function returns -1/0/+1, not True/None/False like my `right_order` does. Once I correct for that, it works fine."
"In Python 2, the `sorted` function accepted a two-argument `cmp` function, but in Python 3 that functionality is gone. I had to look it up to find that the `functools.cmp_to_key` function converts a comparison function to a key function. "
]
},
{