|
1778 | 1778 | "source": [ |
1779 | 1779 | "#### Part 1: Determine which pairs of packets are already in the right order. What is the sum of the indices of those pairs?\n", |
1780 | 1780 | "\n", |
1781 | | - "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:" |
| 1781 | + "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", |
| 1782 | + "\n", |
| 1783 | + "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:" |
1782 | 1784 | ] |
1783 | 1785 | }, |
1784 | 1786 | { |
|
1791 | 1793 | " \"\"\"Are the two packets in the right order? \n", |
1792 | 1794 | " Negative number for right order; 0 for equal; positive for wrong order.\"\"\"\n", |
1793 | 1795 | " types = (type(left), type(right))\n", |
1794 | | - " if types == (int, int): return left - right\n", |
1795 | | - " elif types == (int, list): return compare([left], right)\n", |
1796 | | - " elif types == (list, int): return compare(left, [right])\n", |
1797 | | - " elif types == (list, list): return first_true(map(compare, left, right), \n", |
1798 | | - " default=len(left) - len(right))" |
| 1796 | + " if types == (int, int): return left - right\n", |
| 1797 | + " elif types == (int, list): return compare([left], right)\n", |
| 1798 | + " elif types == (list, int): return compare(left, [right])\n", |
| 1799 | + " elif types == (list, list): return first_true(map(compare, left, right), \n", |
| 1800 | + " default=len(left) - len(right))" |
1799 | 1801 | ] |
1800 | 1802 | }, |
1801 | 1803 | { |
1802 | 1804 | "cell_type": "markdown", |
1803 | 1805 | "metadata": {}, |
1804 | 1806 | "source": [ |
1805 | | - "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", |
| 1807 | + "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", |
1806 | 1808 | "\n", |
1807 | 1809 | "I threw in some test cases to gain some confidence that I got it right: " |
1808 | 1810 | ] |
|
1850 | 1852 | "source": [ |
1851 | 1853 | "#### Part 2: Organize all of the packets into the correct order. What is the decoder key for the distress signal?\n", |
1852 | 1854 | "\n", |
1853 | | - "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", |
| 1855 | + "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", |
1854 | 1856 | "\n", |
1855 | | - "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." |
| 1857 | + "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. " |
1856 | 1858 | ] |
1857 | 1859 | }, |
1858 | 1860 | { |
|
0 commit comments