HN user

joshcorbin

56 karma
Posts2
Comments24
View on HN
Human Bottlenecks 2 months ago

Could you imagine if you found everything interesting? You’d spend years living in a basement curating a wiki of late Soviet military hardware or something.

Yes... imagine...

Tell me you've got little empathy for the autist mind without telling me...

Just wait until someone finally gets why CSI ( aka the “other escape” from the 8-bit ansi realm, which is now eternalized in unicode C1 block ) is written ESC [ in 7-bit systems, such as the equally now eternal utf-8 encoding

It's not the most obvious UX but hit "/" to open the rules dialog, this rule set is "ant(2L 64F 2S)". Click through to the project page and check out the README for more info on the key binds: https://github.com/jcorbin/hexant.

The coloring trick is a recent addition I call "redraw tracing"; essentially there are two color palettes: one for "cold cells" and "hot cells" (ones that haven't/have been visited "recently").

What makes it "redraw" tracing is that "recent" is simply defined as "since last full redraw". Full redraws are triggered when the ant hits an edge of the screen.

I plan to expand the tracing to support "last-N" tracing where "recent" would mean something more comprehensible like "in the last 1024 iterations" f.e.

Further showing the advantage of the pythonic way, is that the above construction remains about as clear when you refactor it for better pruning:

    (
        (to_number(s, e, n, d),
         to_number(m, o, r, e),
         to_number(m, o, n, e, y))

        for d, digits in choose1(digits)
        for e, digits in choose1(digits)
        for y, digits in choose1(digits)
        if (d + e) % 10 == y

        for n, digits in choose1(digits)
        for r, digits in choose1(digits)
        if (n + r + (d + e) // 10) % 10 == e

        for o, digits in choose1(digits)
        if (e + o + (n + r + (d + e) // 10) // 10) % 10 == n

        for s, digits in choose1(digits, 0)
        for m, digits in choose1(digits, 0)
        if (s + m + (e + o + (n + r + (d + e) // 10) // 10) // 10) % 10 == o
        if (s + m + (e + o + (n + r + (d + e) // 10) // 10) // 10) // 10 == m)
Ends up being several order of magnitudes faster since it partially sums each place and prunes aggressively. You can eliminate the sub-expressions, but it has noise impact on the run time (likely due to trading off temporary tuples for cheap arithmetic):
    (
        (to_number(s, e, n, d),
         to_number(m, o, r, e),
         to_number(m, o, n, e, y))

        for d, digits in choose1(digits)
        for e, digits in choose1(digits)
        for y, digits in choose1(digits)
        if (d + e) % 10 == y

        for n, digits in choose1(digits)
        for r, digits in choose1(digits)
        if (n + r + (d + e) // 10) % 10 == e

        for o, digits in choose1(digits)
        if (e + o + (n + r + (d + e) // 10) // 10) % 10 == n

        for s, digits in choose1(digits, 0)
        for m, digits in choose1(digits, 0)
        if (s + m + (e + o + (n + r + (d + e) // 10) // 10) // 10) % 10 == o
        if (s + m + (e + o + (n + r + (d + e) // 10) // 10) // 10) // 10 == m)

An alternative using Python's builtin monadic machinery (comprehensions) with a utility function to aid with threading around the remaining alphabet:

    def to_number(*digits):
        return sum(d * 10 ** n
                   for n, d in enumerate(reversed(digits)))


    def choose1(digits, *exclude):
        for digit in digits.difference(exclude):
            yield digit, digits - {digit}

    all_digits = set(range(10))

    print [
        (send, more, money)
        for s, e, n, d, send, digits in (
            (s, e, n, d, to_number(s, e, n, d), digits)
            for s, digits in choose1(all_digits, 0)
            for e, digits in choose1(digits)
            for n, digits in choose1(digits)
            for d, digits in choose1(digits))
        for m, o, r, more, digits in (
            (m, o, r, to_number(m, o, r, e), digits)
            for m, digits in choose1(digits, 0)
            for o, digits in choose1(digits)
            for r, digits in choose1(digits))
        for y, money, digits in (
            (y, to_number(m, o, n, e, y), digits)
            for y, digits in choose1(digits))
        if send + more == money]
I could've actually had the base alphabet called `digits`, but found calling it `all_digits` perhaps less confusing so then `digits` is the one that's only internally visible in the comprehension. This solution is lazy internally, then eagerly pumped to full exhaustion; usually changing the outer `[...]` to `next(...)` is more useful.

I find it very useful to remember that comprehensions deeply connected to monads: https://en.wikipedia.org/wiki/Monad_(functional_programming)...

I'm really still trying to come to terms with the opener: "It’s not like I deserve any credit for being smart. I didn’t do anything to make that happen. I’m also tall, but nobody compliments me on that. (Good job being tall!) Intelligence is an immutable characteristic that I have at times capitalized on and at other times let go to waste."

To my layman understanding of psychology, and especially what intelligence research has been uncovering over the last few decades, the exact opposite is the case: - intelligence is far from an immutable trait - we do a lot to influence our own intelligence (perhaps far more than we realize, since much of what we do is due to implicit socialization/upbringing)

If you're going to use an analogy to a physical characteristic, than I'd suggest using weight not height: yes there are relevant genetic traits, but they're only a fraction of the story.

Even more interesting to me:

In [3]: ar = [1, 2, 3, 2, 4, 6, 3, 5 ,7, 3, 5, 8]

In [4]: %timeit zip([iter(ar)]3) 100000 loops, best of 3: 2.02 us per loop

In [5]: %timeit zip(ar[0::3], ar[1::3], ar[2::3]) 1000000 loops, best of 3: 1.37 us per loop

In [6]: %timeit zip((iter(ar),)3) 1000000 loops, best of 3: 1.34 us per loop

From which I conclude: - zipping slices is even more efficient, and arguably easier to grok - but you get about the same runtime by multiplying a singleton tuple rather than a list

However if you want to generalize the chunk size, multiplication seems to win out over slicing (with tuples still being more efficient than lists):

In [7]: chunk1 = lambda n, it: zip([iter(it)]n)

In [8]: chunk2 = lambda n, it: zip((iter(it),)n)

In [9]: chunk3 = lambda n, seq: zip(*(seq[i::n] for i in xrange(n)))

In [10]: %timeit chunk1(3, ar) 100000 loops, best of 3: 2.32 us per loop

In [11]: %timeit chunk2(3, ar) 1000000 loops, best of 3: 1.83 us per loop

In [12]: %timeit chunk3(3, ar) 100000 loops, best of 3: 3.55 us per loop

Except that if you do: whatever | tee filea | tee fileb | tee filec | tee filed >/dev/null, you'll get parallelism. This works since tee will write first to stdout, and then to the file you pass it. This may not be "all available" parallelism, but I suspect that it's a decent approximation of "good enough".

That's actually what I'm speaking to.

The Mahayana tradition (in particular Zen) is the one that focuses more on not doing; where-as Theravada very much puts forth the practice as an act of doing. The usual language is to "turn towards" what is happening, not to simply "be one" with it.

As I understand Theravada, it's about observing what is happening rather than stopping or nullifying; so thought -> observe -> repeat is quite appropriate for it.

I use gkrellm in the top right corner, and a small vertical panel in the lower right corner that has a clock and notification, nothing else.

I find that tucking the clock away in this place where my eyes scan to last causes me to look at it very little except when I want to.

Sick Linux Commands 16 years ago

Wide lines like from syslog, frequently you want one event per line and not to have wrapping occur. The -S switch to less is a boon here.

If you were to eliminate one form of differentiation (parties), another would evolve to fill the void. In fact, as soon as you start trying to abolish parties, you will implicitly create at least two parties: those for, and those against.

The Internet does not solve this; to the contrary, it only help to amplify the effect of what Freud called the "Narcissm of small differences" ( http://en.wikipedia.org/wiki/Narcissism_of_small_differences ).

We see this fact recapitulated in every domain of technology such as: - Linux v Windows v Apple - Fedora v Redhat v Debian v Ubuntu v Arch v Gentoo v ... - $OUR_EDITOR v $THEIR_EDITOR - Slashdot v Hacker News

The difference is that the political landscape isn't nearly as diverse. However this is changing already due to the Internet. Agree with their views or not, the Tea Party is sign of this.

The way forward is to partition more, not less. Trying to pretend like we can do away with partitions is flawed at inception.