Skip to content

Instantly share code, notes, and snippets.

@CrossEye
Created March 7, 2019 04:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CrossEye/f84a3dc25efc742a534ed6ab4a30f137 to your computer and use it in GitHub Desktop.
Save CrossEye/f84a3dc25efc742a534ed6ab4a30f137 to your computer and use it in GitHub Desktop.

As we can see, for any n, the actual output will be [n, n], not [n, -1]

While I have no problem with hand-waving a bit in a mathematical argument for popular consumption, "as we can see" is really begging the question. If we could simply see this, then we would really not need to proof by contradiction at all. I think this should be spelled out.

For example, the cardinality of [0, 1, 2, 3, Infinity] is 4, the same as its length.

Oops. There seems to be a miscount here.

Rationals

Almost as soon as I started reading, well before I got to this section, and probably because I knew you were getting to diagonalization, I thought back to one of my favorite little bits of trivia from an old math course.

There is a wonderful infinite binary tree containing the positive rationals, each appearing only once in reduced form. The root is 1 / 1, and the children of n / d are n / (n + d) and (n + d) / d. It's relatively straightforward to show that everything is in lowest terms, and there's a nice induction on n + d to show that every rational has a home.

So I immediately had to implement this as a generator. Here's my version, using a take from one of your gists:

function * take (numberToTake, iterable) {
  const iterator = iterable[Symbol.iterator]();

  for (let i = 0; i < numberToTake; ++i) {
    const { done, value } = iterator.next();
    if (done) return;
    else yield value;
  }
}

function * rationals () {
  let idx = 0;
  let res = [[1, 1]];
  yield [1, 1];
  while (true) {
    idx += 1;
    const [num, den] = res[Math.floor((idx - 1) / 2)];
    const rational = (idx % 2 == 1) ? [num, num + den] : [num + den, num];
    res.push(rational);
    yield rational;
  }
}

[...take(15, rationals())].map(([num, den]) => `${num}/${den}`) 
//=> ["1/1", "1/2", "2/1", "1/3", "3/1", "2/3", "3/2", "1/4", 
//    "4/1", "3/4", "4/3", "2/5", "5/2", "3/5", "5/3"]

This probably doesn't fit at all with your essay, as there is too much to explain, and its tree structure is different from your grid. But if you have a use for it, please feel free.

By inference, the product of three or more denumerables is also denumerable, because the denumerability of the product operation is transitive.

This feels odd to me. I know what you're trying to say, but "the foo of the x operation is transitive" doesn't work well in my mind.

Combination

The definition of combination includes this line:

          const rest = slice(generator, index + 1);

But I don't think you've defined slice yet. (It's not hard to figure out, but I don't know if you realized that.

Product of Products

I think you need to make a little more clear the relationship between this:

No number appearing within a product is greater than or equal to the ordinal of the product.

and this:

What happens if we substitute the elements of the above output for the numbers… In itself?

Perhaps it's going to be obvious to all readers. But I only caught it because I knew what was coming.

Overall

I really liked this essay. Even though I knew where you were coming from based on earlier essays and our tweets about them, it was still exciting to see the conclusion. And the relationship to all finite trees was new to me. (There are so many paths to the Catalan numbers!)

Damn nice for a rough draft

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment